[llvm] [IR] Avoid UB in `SymbolTableListTraits` (PR #139096)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sun May 11 00:26:44 PDT 2025
https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/139096
>From 0d79165f0a936bf72c19ccf0872b833ac1c000d9 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Sun, 11 May 2025 15:22:48 +0800
Subject: [PATCH] [IR] Avoid UB in `SymbolTableListTraits`
---
llvm/include/llvm/IR/BasicBlock.h | 4 ++++
llvm/include/llvm/IR/Function.h | 4 ++++
llvm/include/llvm/IR/Module.h | 13 +++++++++++++
llvm/include/llvm/IR/SymbolTableListTraits.h | 6 ++----
4 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/IR/BasicBlock.h b/llvm/include/llvm/IR/BasicBlock.h
index 9ee0bacb5c258..10617db09fde6 100644
--- a/llvm/include/llvm/IR/BasicBlock.h
+++ b/llvm/include/llvm/IR/BasicBlock.h
@@ -546,6 +546,10 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
return &BasicBlock::InstList;
}
+ static size_t getSublistOffset(Instruction *) {
+ return offsetof(BasicBlock, InstList);
+ }
+
/// Dedicated function for splicing debug-info: when we have an empty
/// splice (i.e. zero instructions), the caller may still intend any
/// debug-info in between the two "positions" to be spliced.
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 6d4a53da7ff22..63100568d07e4 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -811,6 +811,10 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
return &Function::BasicBlocks;
}
+ static size_t getSublistOffset(BasicBlock *) {
+ return offsetof(Function, BasicBlocks);
+ }
+
public:
const BasicBlock &getEntryBlock() const { return front(); }
BasicBlock &getEntryBlock() { return front(); }
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 53d1005333ee1..f93186d2ea0fc 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -25,6 +25,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ProfileSummary.h"
@@ -609,6 +610,9 @@ class LLVM_ABI Module {
static GlobalListType Module::*getSublistAccess(GlobalVariable*) {
return &Module::GlobalList;
}
+ static size_t getSublistOffset(GlobalVariable *) {
+ return offsetof(Module, GlobalList);
+ }
friend class llvm::SymbolTableListTraits<llvm::GlobalVariable>;
public:
@@ -619,6 +623,9 @@ class LLVM_ABI Module {
static FunctionListType Module::*getSublistAccess(Function*) {
return &Module::FunctionList;
}
+ static size_t getSublistOffset(Function *) {
+ return offsetof(Module, FunctionList);
+ }
/// Detach \p Alias from the list but don't delete it.
void removeAlias(GlobalAlias *Alias) { AliasList.remove(Alias); }
@@ -658,6 +665,9 @@ class LLVM_ABI Module {
static AliasListType Module::*getSublistAccess(GlobalAlias*) {
return &Module::AliasList;
}
+ static size_t getSublistOffset(GlobalAlias *) {
+ return offsetof(Module, AliasList);
+ }
friend class llvm::SymbolTableListTraits<llvm::GlobalAlias>;
/// Get the Module's list of ifuncs (constant).
@@ -668,6 +678,9 @@ class LLVM_ABI Module {
static IFuncListType Module::*getSublistAccess(GlobalIFunc*) {
return &Module::IFuncList;
}
+ static size_t getSublistOffset(GlobalIFunc *) {
+ return offsetof(Module, IFuncList);
+ }
friend class llvm::SymbolTableListTraits<llvm::GlobalIFunc>;
/// Get the Module's list of named metadata (constant).
diff --git a/llvm/include/llvm/IR/SymbolTableListTraits.h b/llvm/include/llvm/IR/SymbolTableListTraits.h
index fcf6f0fb15280..456833fff62ce 100644
--- a/llvm/include/llvm/IR/SymbolTableListTraits.h
+++ b/llvm/include/llvm/IR/SymbolTableListTraits.h
@@ -77,10 +77,8 @@ class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
/// getListOwner - Return the object that owns this list. If this is a list
/// of instructions, it returns the BasicBlock that owns them.
ItemParentClass *getListOwner() {
- size_t Offset = reinterpret_cast<size_t>(
- &((ItemParentClass *)nullptr->*ItemParentClass::getSublistAccess(
- static_cast<ValueSubClass *>(
- nullptr))));
+ size_t Offset = ItemParentClass::getSublistOffset(
+ static_cast<ValueSubClass *>(nullptr));
ListTy *Anchor = static_cast<ListTy *>(this);
return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
Offset);
More information about the llvm-commits
mailing list