[llvm] Don't rely on undefined behavior to store how a `User` object's allocation is laid out (PR #105714)

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 9 14:12:02 PDT 2024


================
@@ -454,6 +453,9 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
     assert(InitVal->getType() == Ty &&
            "Initializer should be the same type as the GlobalVariable!");
     Op<0>() = InitVal;
+  } else {
+    // HACK: This is incorrect, we should have allocated less memory.
----------------
rnk wrote:

I see this corresponds to the GlobalVariable operator delete comments that set it back to 1. Would it make more sense to reset NumUserOperands back to 1 in the destructor, just for symmetry?

This also raises a broader question of whether it is well-defined to read NumOperands in `User::operator delete` after the destructor has run. We still do that, and that would interfere with tools like MSan that poison memory in destructors.

Concretely, please update this comment to explain what's going on here in more detail. It's not incorrect as written. All GlobalVariables allocate one Use, and for variable declarations that lack an initializer, we reduce the operand list size to zero. That has to be undone before deletion, or deallocation will fail.

https://github.com/llvm/llvm-project/pull/105714


More information about the llvm-commits mailing list