llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer

@llvm/pr-subscribers-clang-codegen

Author: Gustas Janušonis (LeGusto)

<details>
<summary>Changes</summary>


A polymorphic class's TBAA type descriptor did not include its vtable pointer 
as a member. TypeSanitizer stamps a global's storage with the class's type 
descriptor at startup, thus when the constructor then stores the vtable pointer 
at offset 0, that store was incorrectly reported as a type-aliasing violation, 
since the pre-stamped descriptor had no member at offset 0.

Fixed by inserting a vtable pointer as a member in the descriptor at offset 0 
for classes that own a vptr.

Fixes #<!-- -->208651

Assisted-by: Claude (Anthropic)

---
Full diff: https://github.com/llvm/llvm-project/pull/209053.diff


5 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+9) 
- (added) clang/test/CodeGen/tbaa-vptr-member.cpp (+18) 
- (modified) clang/test/CodeGenCXX/load-reference-metadata.cpp (+3-2) 
- (modified) clang/unittests/CodeGen/TBAAMetadataTest.cpp (+10-12) 
- (added) compiler-rt/test/tysan/global-vtable-ptr.cpp (+19) 


``````````diff
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp 
b/clang/lib/CodeGen/CodeGenTBAA.cpp
index 1854df7c7c0f1..8bc0c10b27f1d 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -531,6 +531,15 @@ llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const 
Type *Ty) {
       // incomplete view for NewStructPathTBAA.
       if (CodeGenOpts.NewStructPathTBAA && CXXRD->getNumVBases() != 0)
         return nullptr;
+      // A polymorphic class holds a vtable pointer at offset 0 that is not 
part
+      // of the declared field list.
+      if (Layout.hasOwnVFPtr()) {
+        uint64_t PtrSize =
+            Context.getTypeSizeInChars(Context.VoidPtrTy).getQuantity();
+        Fields.push_back(llvm::MDBuilder::TBAAStructField(
+            0, PtrSize,
+            createScalarTypeNode("vtable pointer", getRoot(), PtrSize)));
+      }
       for (const CXXBaseSpecifier &B : CXXRD->bases()) {
         if (B.isVirtual())
           continue;
diff --git a/clang/test/CodeGen/tbaa-vptr-member.cpp 
b/clang/test/CodeGen/tbaa-vptr-member.cpp
new file mode 100644
index 0000000000000..f9ce2f297f978
--- /dev/null
+++ b/clang/test/CodeGen/tbaa-vptr-member.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -O1 -disable-llvm-passes 
-emit-llvm -o - %s | FileCheck %s
+//
+// A polymorphic class stores a vtable pointer at offset 0. Its TBAA type
+// descriptor must model that pointer as a member, so a vtable-pointer store
+// reconciles with the object's own type instead of looking like an aliasing
+// violation.
+
+struct A {
+  virtual ~A();
+  char byte;
+};
+
+// Reading a member forces A's struct-path base-type node to be emitted.
+char getByte(A *a) { return a->byte; }
+
+// A's base-type node lists the vtable pointer at offset 0, then 'byte' at 8:
+// CHECK: = !{!"_ZTS1A", [[VPTR:![0-9]+]], i64 0, {{![0-9]+}}, i64 8}
+// CHECK: [[VPTR]] = !{!"vtable pointer", {{.*}}, i64 0}
diff --git a/clang/test/CodeGenCXX/load-reference-metadata.cpp 
b/clang/test/CodeGenCXX/load-reference-metadata.cpp
index d3e3dc1cbe534..c378efcd983cd 100644
--- a/clang/test/CodeGenCXX/load-reference-metadata.cpp
+++ b/clang/test/CodeGenCXX/load-reference-metadata.cpp
@@ -93,6 +93,7 @@ char* test_deref_only(B &s) {
 // CHECK: [[_ZTS1BPTR_TBAA24]] = !{[[META25:![0-9]+]], [[META25]], i64 0}
 // CHECK: [[META25]] = !{!"p1 _ZTS1B", [[META8]], i64 0}
 // CHECK: [[CHAR_TBAA26]] = !{[[META27:![0-9]+]], [[META4]], i64 16}
-// CHECK: [[META27]] = !{!"_ZTS1B", [[META28:![0-9]+]], i64 8, [[META4]], i64 
16}
-// CHECK: [[META28]] = !{!"long long", [[META4]], i64 0}
+// CHECK: [[META27]] = !{!"_ZTS1B", [[META28:![0-9]+]], i64 0, 
[[META29:![0-9]+]], i64 8, [[META4]], i64 16}
+// CHECK: [[META28]] = !{!"vtable pointer", [[META5]], i64 0}
+// CHECK: [[META29]] = !{!"long long", [[META4]], i64 0}
 //.
diff --git a/clang/unittests/CodeGen/TBAAMetadataTest.cpp 
b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
index f05c9787c63ea..b9295f735a08a 100644
--- a/clang/unittests/CodeGen/TBAAMetadataTest.cpp
+++ b/clang/unittests/CodeGen/TBAAMetadataTest.cpp
@@ -1036,12 +1036,11 @@ TEST(TBAAMetadataTest, PolymorphicClass) {
   const BasicBlock *BB = Compiler.compile();
 
   auto ClassBase = MMTuple(
-    MMString("_ZTS4Base"),
-    MMTuple(
-      MMString("int"),
-      OmnipotentCharCXX,
-      MConstInt(0)),
-    MConstInt(Compiler.PtrSize));
+      MMString("_ZTS4Base"),
+      MMTuple(MMString("vtable pointer"), MMTuple(MMString("Simple C++ TBAA")),
+              MConstInt(0)),
+      MConstInt(0), MMTuple(MMString("int"), OmnipotentCharCXX, MConstInt(0)),
+      MConstInt(Compiler.PtrSize));
 
   auto ClassDerived =
       MMTuple(MMString("_ZTS7Derived"), ClassBase, MConstInt(0),
@@ -1118,12 +1117,11 @@ TEST(TBAAMetadataTest, VirtualBase) {
     MConstInt(0));
 
   auto ClassDerived = MMTuple(
-    MMString("_ZTS7Derived"),
-    MMTuple(
-      MMString("short"),
-      OmnipotentCharCXX,
-      MConstInt(0)),
-    MConstInt(Compiler.PtrSize));
+      MMString("_ZTS7Derived"),
+      MMTuple(MMString("vtable pointer"), MMTuple(MMString("Simple C++ TBAA")),
+              MConstInt(0)),
+      MConstInt(0), MMTuple(MMString("short"), OmnipotentCharCXX, 
MConstInt(0)),
+      MConstInt(Compiler.PtrSize));
 
   const Instruction *I = match(BB,
       MInstruction(Instruction::Store,
diff --git a/compiler-rt/test/tysan/global-vtable-ptr.cpp 
b/compiler-rt/test/tysan/global-vtable-ptr.cpp
new file mode 100644
index 0000000000000..6133cf896e271
--- /dev/null
+++ b/compiler-rt/test/tysan/global-vtable-ptr.cpp
@@ -0,0 +1,19 @@
+// RUN: %clangxx_tysan -O0 %s -o %t && %run %t 2>&1 | FileCheck 
--implicit-check-not ERROR %s
+
+// https://github.com/llvm/llvm-project/issues/208651
+
+#include <stdio.h>
+
+class A {
+public:
+  virtual ~A() = default;
+  char byte;
+};
+
+static A a;
+
+int main() {
+  printf("done\n");
+  // CHECK: done
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/209053
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to