Skip to content

Commit 1e81e80

Browse files
authored
[IR] Avoid UB in SymbolTableListTraits (llvm#139096)
This patch fixes the "dereferencing null" UB. Unfortunately, C++ doesn't provide an inverse operation for `p->*pmf`. See also llvm#130952.
1 parent ccb5571 commit 1e81e80

File tree

4 files changed

+22
-4
lines changed

4 files changed

+22
-4
lines changed

llvm/include/llvm/IR/BasicBlock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,10 @@ class BasicBlock final : public Value, // Basic blocks are data objects also
546546
return &BasicBlock::InstList;
547547
}
548548

549+
static size_t getSublistOffset(Instruction *) {
550+
return offsetof(BasicBlock, InstList);
551+
}
552+
549553
/// Dedicated function for splicing debug-info: when we have an empty
550554
/// splice (i.e. zero instructions), the caller may still intend any
551555
/// debug-info in between the two "positions" to be spliced.

llvm/include/llvm/IR/Function.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,10 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
811811
return &Function::BasicBlocks;
812812
}
813813

814+
static size_t getSublistOffset(BasicBlock *) {
815+
return offsetof(Function, BasicBlocks);
816+
}
817+
814818
public:
815819
const BasicBlock &getEntryBlock() const { return front(); }
816820
BasicBlock &getEntryBlock() { return front(); }

llvm/include/llvm/IR/Module.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,9 @@ class LLVM_ABI Module {
608608
static GlobalListType Module::*getSublistAccess(GlobalVariable*) {
609609
return &Module::GlobalList;
610610
}
611+
static size_t getSublistOffset(GlobalVariable *) {
612+
return offsetof(Module, GlobalList);
613+
}
611614
friend class llvm::SymbolTableListTraits<llvm::GlobalVariable>;
612615

613616
public:
@@ -618,6 +621,9 @@ class LLVM_ABI Module {
618621
static FunctionListType Module::*getSublistAccess(Function*) {
619622
return &Module::FunctionList;
620623
}
624+
static size_t getSublistOffset(Function *) {
625+
return offsetof(Module, FunctionList);
626+
}
621627

622628
/// Detach \p Alias from the list but don't delete it.
623629
void removeAlias(GlobalAlias *Alias) { AliasList.remove(Alias); }
@@ -657,6 +663,9 @@ class LLVM_ABI Module {
657663
static AliasListType Module::*getSublistAccess(GlobalAlias*) {
658664
return &Module::AliasList;
659665
}
666+
static size_t getSublistOffset(GlobalAlias *) {
667+
return offsetof(Module, AliasList);
668+
}
660669
friend class llvm::SymbolTableListTraits<llvm::GlobalAlias>;
661670

662671
/// Get the Module's list of ifuncs (constant).
@@ -667,6 +676,9 @@ class LLVM_ABI Module {
667676
static IFuncListType Module::*getSublistAccess(GlobalIFunc*) {
668677
return &Module::IFuncList;
669678
}
679+
static size_t getSublistOffset(GlobalIFunc *) {
680+
return offsetof(Module, IFuncList);
681+
}
670682
friend class llvm::SymbolTableListTraits<llvm::GlobalIFunc>;
671683

672684
/// Get the Module's list of named metadata (constant).

llvm/include/llvm/IR/SymbolTableListTraits.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,8 @@ class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
7777
/// getListOwner - Return the object that owns this list. If this is a list
7878
/// of instructions, it returns the BasicBlock that owns them.
7979
ItemParentClass *getListOwner() {
80-
size_t Offset = reinterpret_cast<size_t>(
81-
&((ItemParentClass *)nullptr->*ItemParentClass::getSublistAccess(
82-
static_cast<ValueSubClass *>(
83-
nullptr))));
80+
size_t Offset = ItemParentClass::getSublistOffset(
81+
static_cast<ValueSubClass *>(nullptr));
8482
ListTy *Anchor = static_cast<ListTy *>(this);
8583
return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
8684
Offset);

0 commit comments

Comments
 (0)