[llvm] [IR] Avoid UB in `SymbolTableListTraits` (PR #139096)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 29 04:14:56 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
This patch fixes the "dereferencing null" UB. Unfortunately, C++ doesn't provide an inverse operation for `p->*pmf`.
See also https://github.com/llvm/llvm-project/pull/130952.
---
Full diff: https://github.com/llvm/llvm-project/pull/139096.diff
4 Files Affected:
- (modified) llvm/include/llvm/IR/BasicBlock.h (+4)
- (modified) llvm/include/llvm/IR/Function.h (+4)
- (modified) llvm/include/llvm/IR/Module.h (+12)
- (modified) llvm/include/llvm/IR/SymbolTableListTraits.h (+2-4)
``````````diff
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..298ccab3bfae1 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -609,6 +609,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 +622,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 +664,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 +677,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);
``````````
</details>
https://github.com/llvm/llvm-project/pull/139096
More information about the llvm-commits
mailing list