-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[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
Conversation
6374456
to
11dfefb
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
11dfefb
to
0d79165
Compare
@llvm/pr-subscribers-llvm-ir Author: Yingwei Zheng (dtcxzyw) ChangesThis patch fixes the "dereferencing null" UB. Unfortunately, C++ doesn't provide an inverse operation for Full diff: https://github.com/llvm/llvm-project/pull/139096.diff 4 Files Affected:
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);
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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)- |
There was a problem hiding this comment.
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.
FYI, getting a bunch of these warnings when building LLVM:
|
Clang builds are heavily warning about this change:
https://en.cppreference.com/w/cpp/types/offsetof.html says
|
I noticed this issue when drafting this patch. But we don't have a better solution :( |
Ok, but spamming compilation warnings for almost every TU isn't a solution either. If it's not easy to fix, I would propose to revert both PRs for the time being. |
Reverts #139096 due to invalid uses of `offsetof` on non-standard-layout types.
@dtcxzyw I am no expert in what you are trying to do here, but I wonder if disabling specific warnings with |
Reverts llvm/llvm-project#139096 due to invalid uses of `offsetof` on non-standard-layout types.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/29466 Here is the relevant piece of the build log for the reference
|
This patch fixes the "dereferencing null" UB. Unfortunately, C++ doesn't provide an inverse operation for `p->*pmf`. See also llvm#130952.
Reverts llvm#139096 due to invalid uses of `offsetof` on non-standard-layout types.
This patch fixes the "dereferencing null" UB. Unfortunately, C++ doesn't provide an inverse operation for
p->*pmf
.See also #130952.