Skip to content

[IR] Avoid UB in SymbolTableListTraits #139096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/BasicBlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
Expand Down
12 changes: 12 additions & 0 deletions llvm/include/llvm/IR/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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); }
Expand Down Expand Up @@ -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).
Expand All @@ -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).
Expand Down
6 changes: 2 additions & 4 deletions llvm/include/llvm/IR/SymbolTableListTraits.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)-
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure C++ semantics actually allow this arithmetic, strictly speaking; you might need to go though uintptr_t. But I don't want to try to address that in this patch.

Offset);
Expand Down
Loading