diff --git a/clang/test/CodeGen/asan-globals-alias.cpp b/clang/test/CodeGen/asan-globals-alias.cpp --- a/clang/test/CodeGen/asan-globals-alias.cpp +++ b/clang/test/CodeGen/asan-globals-alias.cpp @@ -36,8 +36,8 @@ // CHECK: @__mod_joydev_ids_device_table ={{.*}} alias // CHECK-LABEL: define internal void @asan.module_ctor -// ASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 4) -// KASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 1) +// ASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 5) +// KASAN: call void @__asan_register_globals({{.*}}, i{{32|64}} 2) // CHECK-NEXT: ret void // CHECK-LABEL: define internal void @asan.module_dtor diff --git a/clang/test/CodeGen/asan-globals-odr.cpp b/clang/test/CodeGen/asan-globals-odr.cpp --- a/clang/test/CodeGen/asan-globals-odr.cpp +++ b/clang/test/CodeGen/asan-globals-odr.cpp @@ -24,7 +24,7 @@ // GLOB_ALIAS_INDICATOR: @0 = internal global {{.*}} @1 to i64), {{.*}}, i64 ptrtoint (i8* [[ODR]] to i64) }] // ALIAS0-NOT: private alias -// ALIAS1: @1 = private alias {{.*}} [[VAR]] +// ALIAS1: @2 = private alias {{.*}} [[VAR]] -// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) -// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) +// CHECK: call void @__asan_register_globals(i64 ptrtoint ([2 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 2) +// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([2 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 2) diff --git a/clang/test/CodeGen/asan-globals.cpp b/clang/test/CodeGen/asan-globals.cpp --- a/clang/test/CodeGen/asan-globals.cpp +++ b/clang/test/CodeGen/asan-globals.cpp @@ -33,8 +33,8 @@ // ASAN-NEXT: call void @__asan_version_mismatch_check // KASAN-NOT: call void @__asan_init // KASAN-NOT: call void @__asan_version_mismatch_check -// ASAN-NEXT: call void @__asan_register_globals({{.*}}, i{{32|64}} 7) -// KASAN-NEXT: call void @__asan_register_globals({{.*}}, i{{32|64}} 5) +// ASAN-NEXT: call void @__asan_register_globals({{.*}}, i{{32|64}} 8) +// KASAN-NEXT: call void @__asan_register_globals({{.*}}, i{{32|64}} 6) // CHECK-NEXT: ret void // CHECK: define internal void @asan.module_dtor() #[[#ATTR]] { diff --git a/clang/test/CodeGen/asan-static-odr.cpp b/clang/test/CodeGen/asan-static-odr.cpp --- a/clang/test/CodeGen/asan-static-odr.cpp +++ b/clang/test/CodeGen/asan-static-odr.cpp @@ -13,5 +13,5 @@ // CHECK-NOT: private alias // CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [60 x i8] } zeroinitializer, align 32 // CHECK: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 -1 }] -// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) -// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) +// CHECK: call void @__asan_register_globals(i64 ptrtoint ([2 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 2) +// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([2 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 2) diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2372,6 +2372,18 @@ return false; } + // Create a global zero-sized array precedence before GlobalsToChange[0] so + // that the underflow of the it could be observable. + ArrayType *ZeroSizedArrayTy = ArrayType::get(IRB.getInt8Ty(), 0); + GlobalVariable *UnderflowObserverGV = new GlobalVariable( + M, ZeroSizedArrayTy, /*isConstant*/ false, GlobalVariable::PrivateLinkage, + ConstantArray::get(ZeroSizedArrayTy, {}), kAsanGenPrefix, + GlobalsToChange[0]); + GlobalsToChange.insert(GlobalsToChange.begin(), UnderflowObserverGV); + + // Update size as we insert a dummy one. + n = GlobalsToChange.size(); + auto &DL = M.getDataLayout(); // A global is described by a structure diff --git a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll --- a/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll @@ -28,8 +28,8 @@ ; CHECK: [[LOCDESCR:@___asan_gen_.[0-9]+]] = private unnamed_addr constant { [22 x i8]*, i32, i32 } { [22 x i8]* [[FILENAME]], i32 5, i32 5 } ; NOALIAS: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [60 x i8] }* @global to i64){{.*}} section "asan_globals"{{.*}}, !associated ; NOALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @{{.str|1}} to i64){{.*}} section "asan_globals"{{.*}}, !associated -; ALIAS: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [60 x i8] }* @0 to i64){{.*}} section "asan_globals"{{.*}}, !associated -; ALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @3 to i64){{.*}} section "asan_globals"{{.*}}, !associated +; ALIAS: @__asan_global_global = {{.*}}i64 ptrtoint ({ i32, [60 x i8] }* @1 to i64){{.*}} section "asan_globals"{{.*}}, !associated +; ALIAS: @__asan_global_.str = {{.*}}i64 ptrtoint ({ [14 x i8], [50 x i8] }* @4 to i64){{.*}} section "asan_globals"{{.*}}, !associated ; The metadata has to be inserted to llvm.compiler.used to avoid being stripped ; during LTO.