Skip to content

[TySan] Don't report globals with external storage. #120565

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 1 commit into from
Dec 19, 2024

Conversation

fhahn
Copy link
Contributor

@fhahn fhahn commented Dec 19, 2024

Globals with external storage should have been initialized where they are defined.

Fixes #120448

@fhahn fhahn requested a review from erichkeane December 19, 2024 12:09
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. labels Dec 19, 2024
@fhahn fhahn requested a review from fmayer December 19, 2024 12:10
@llvmbot
Copy link
Member

llvmbot commented Dec 19, 2024

@llvm/pr-subscribers-clang

Author: Florian Hahn (fhahn)

Changes

Globals with external storage should have been initialized where they are defined.

Fixes #120448


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/SanitizerMetadata.cpp (+5-1)
  • (added) clang/test/CodeGen/sanitize-type-globals.cpp (+58)
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index 405124c8b87170..a2da7ff8ce12c6 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -107,7 +107,8 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
 
   GV->setSanitizerMetadata(Meta);
 
-  if (Ty.isNull() || !CGM.getLangOpts().Sanitize.has(SanitizerKind::Type) ||
+  if (Ty.isNull() ||
+      !CGM.getLangOpts().Sanitize.has(SanitizerKind::Type) ||
       NoSanitizeAttrMask & SanitizerKind::Type)
     return;
 
@@ -145,6 +146,9 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
     for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
       NoSanitizeMask |= Attr->getMask();
 
+    if (D.hasExternalStorage())
+      NoSanitizeMask |= SanitizerKind::Type;
+
     return NoSanitizeMask;
   };
 
diff --git a/clang/test/CodeGen/sanitize-type-globals.cpp b/clang/test/CodeGen/sanitize-type-globals.cpp
new file mode 100644
index 00000000000000..7cb8de8b238cc8
--- /dev/null
+++ b/clang/test/CodeGen/sanitize-type-globals.cpp
@@ -0,0 +1,58 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --filter-out "attributes" --filter-out "attributes #" --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type | FileCheck -check-prefix=CHECK %s
+
+//.
+// CHECK: @x = global %struct.CompleteS zeroinitializer, align 8
+// CHECK: @y = external global %struct.S, align 1
+// CHECK: @__tysan_shadow_memory_address = external global i64
+// CHECK: @__tysan_app_memory_mask = external global i64
+// CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat
+// CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat
+// CHECK: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat
+// CHECK: @__tysan_v1_any_20pointer = linkonce_odr constant { i64, i64, ptr, i64, [12 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [12 x i8] c"any pointer\00" }, comdat
+// CHECK: @__tysan_v1_p1_20int = linkonce_odr constant { i64, i64, ptr, i64, [7 x i8] } { i64 2, i64 1, ptr @__tysan_v1_any_20pointer, i64 0, [7 x i8] c"p1 int\00" }, comdat
+// CHECK: @__tysan_v1___ZTS9CompleteS = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, [15 x i8] } { i64 2, i64 2, ptr @__tysan_v1_int, i64 0, ptr @__tysan_v1_p1_20int, i64 8, [15 x i8] c"_ZTS9CompleteS\00" }, comdat
+// CHECK: @llvm.used = appending global [7 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_p1_20int, ptr @__tysan_v1___ZTS9CompleteS], section "llvm.metadata"
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
+//.
+struct CompleteS {
+  int x;
+  int *ptr;
+};
+
+void f(CompleteS *);
+CompleteS x;
+// CHECK-LABEL: define dso_local void @_Z1gv(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @_Z1fP9CompleteS(ptr noundef @x)
+// CHECK:    ret void
+//
+void g() { f(&x); }
+
+typedef struct S IncompleteS;
+void f(IncompleteS *);
+extern IncompleteS y;
+// CHECK-LABEL: define dso_local void @_Z1hv(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @_Z1fP1S(ptr noundef @y)
+// CHECK:    ret void
+//
+void h() { f(&y); }
+//.
+// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone sanitize_type "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR2:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind }
+//.
+// CHECK: [[META0:![0-9]+]] = !{ptr @x, [[META1:![0-9]+]]}
+// CHECK: [[META1]] = !{!"_ZTS9CompleteS", [[META2:![0-9]+]], i64 0, [[META5:![0-9]+]], i64 8}
+// CHECK: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0}
+// CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
+// CHECK: [[META4]] = !{!"Simple C++ TBAA"}
+// CHECK: [[META5]] = !{!"p1 int", [[META6:![0-9]+]], i64 0}
+// CHECK: [[META6]] = !{!"any pointer", [[META3]], i64 0}
+// CHECK: [[META7:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// CHECK: [[META8:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+//.

@llvmbot
Copy link
Member

llvmbot commented Dec 19, 2024

@llvm/pr-subscribers-clang-codegen

Author: Florian Hahn (fhahn)

Changes

Globals with external storage should have been initialized where they are defined.

Fixes #120448


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/SanitizerMetadata.cpp (+5-1)
  • (added) clang/test/CodeGen/sanitize-type-globals.cpp (+58)
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index 405124c8b87170..a2da7ff8ce12c6 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -107,7 +107,8 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
 
   GV->setSanitizerMetadata(Meta);
 
-  if (Ty.isNull() || !CGM.getLangOpts().Sanitize.has(SanitizerKind::Type) ||
+  if (Ty.isNull() ||
+      !CGM.getLangOpts().Sanitize.has(SanitizerKind::Type) ||
       NoSanitizeAttrMask & SanitizerKind::Type)
     return;
 
@@ -145,6 +146,9 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
     for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
       NoSanitizeMask |= Attr->getMask();
 
+    if (D.hasExternalStorage())
+      NoSanitizeMask |= SanitizerKind::Type;
+
     return NoSanitizeMask;
   };
 
diff --git a/clang/test/CodeGen/sanitize-type-globals.cpp b/clang/test/CodeGen/sanitize-type-globals.cpp
new file mode 100644
index 00000000000000..7cb8de8b238cc8
--- /dev/null
+++ b/clang/test/CodeGen/sanitize-type-globals.cpp
@@ -0,0 +1,58 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --filter-out "attributes" --filter-out "attributes #" --version 5
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=type | FileCheck -check-prefix=CHECK %s
+
+//.
+// CHECK: @x = global %struct.CompleteS zeroinitializer, align 8
+// CHECK: @y = external global %struct.S, align 1
+// CHECK: @__tysan_shadow_memory_address = external global i64
+// CHECK: @__tysan_app_memory_mask = external global i64
+// CHECK: @__tysan_v1_Simple_20C_2b_2b_20TBAA = linkonce_odr constant { i64, i64, [16 x i8] } { i64 2, i64 0, [16 x i8] c"Simple C++ TBAA\00" }, comdat
+// CHECK: @__tysan_v1_omnipotent_20char = linkonce_odr constant { i64, i64, ptr, i64, [16 x i8] } { i64 2, i64 1, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, i64 0, [16 x i8] c"omnipotent char\00" }, comdat
+// CHECK: @__tysan_v1_int = linkonce_odr constant { i64, i64, ptr, i64, [4 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [4 x i8] c"int\00" }, comdat
+// CHECK: @__tysan_v1_any_20pointer = linkonce_odr constant { i64, i64, ptr, i64, [12 x i8] } { i64 2, i64 1, ptr @__tysan_v1_omnipotent_20char, i64 0, [12 x i8] c"any pointer\00" }, comdat
+// CHECK: @__tysan_v1_p1_20int = linkonce_odr constant { i64, i64, ptr, i64, [7 x i8] } { i64 2, i64 1, ptr @__tysan_v1_any_20pointer, i64 0, [7 x i8] c"p1 int\00" }, comdat
+// CHECK: @__tysan_v1___ZTS9CompleteS = linkonce_odr constant { i64, i64, ptr, i64, ptr, i64, [15 x i8] } { i64 2, i64 2, ptr @__tysan_v1_int, i64 0, ptr @__tysan_v1_p1_20int, i64 8, [15 x i8] c"_ZTS9CompleteS\00" }, comdat
+// CHECK: @llvm.used = appending global [7 x ptr] [ptr @tysan.module_ctor, ptr @__tysan_v1_Simple_20C_2b_2b_20TBAA, ptr @__tysan_v1_omnipotent_20char, ptr @__tysan_v1_int, ptr @__tysan_v1_any_20pointer, ptr @__tysan_v1_p1_20int, ptr @__tysan_v1___ZTS9CompleteS], section "llvm.metadata"
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 0, ptr @tysan.module_ctor, ptr null }]
+//.
+struct CompleteS {
+  int x;
+  int *ptr;
+};
+
+void f(CompleteS *);
+CompleteS x;
+// CHECK-LABEL: define dso_local void @_Z1gv(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @_Z1fP9CompleteS(ptr noundef @x)
+// CHECK:    ret void
+//
+void g() { f(&x); }
+
+typedef struct S IncompleteS;
+void f(IncompleteS *);
+extern IncompleteS y;
+// CHECK-LABEL: define dso_local void @_Z1hv(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK:  [[ENTRY:.*:]]
+// CHECK:    call void @_Z1fP1S(ptr noundef @y)
+// CHECK:    ret void
+//
+void h() { f(&y); }
+//.
+// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone sanitize_type "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR1:[0-9]+]] = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR2:[0-9]+]] = { nounwind "target-features"="+cx8,+mmx,+sse,+sse2,+x87" }
+// CHECK: attributes #[[ATTR3:[0-9]+]] = { nounwind }
+//.
+// CHECK: [[META0:![0-9]+]] = !{ptr @x, [[META1:![0-9]+]]}
+// CHECK: [[META1]] = !{!"_ZTS9CompleteS", [[META2:![0-9]+]], i64 0, [[META5:![0-9]+]], i64 8}
+// CHECK: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0}
+// CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
+// CHECK: [[META4]] = !{!"Simple C++ TBAA"}
+// CHECK: [[META5]] = !{!"p1 int", [[META6:![0-9]+]], i64 0}
+// CHECK: [[META6]] = !{!"any pointer", [[META3]], i64 0}
+// CHECK: [[META7:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
+// CHECK: [[META8:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
+//.

Copy link

github-actions bot commented Dec 19, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Globals with external storage should have been initialized where they
are defined.

Fixes llvm#120448
@fhahn fhahn force-pushed the tysan-report-external branch from a12283a to 75b6f89 Compare December 19, 2024 12:24
@fhahn fhahn merged commit 9e322c5 into llvm:main Dec 19, 2024
8 checks passed
@fhahn fhahn deleted the tysan-report-external branch December 19, 2024 21:31
github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Jan 10, 2025
Globals with external storage should have been initialized where they
are defined.

Fixes llvm/llvm-project#120448

PR: llvm/llvm-project#120565
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TySan: Assertion `D && "Cannot get layout of forward declarations!"' failed
3 participants