diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1649,6 +1649,29 @@ } }; + class DeclAsInlineDebugLocation { + CGDebugInfo *DI; + llvm::MDNode *InlinedAt; + llvm::Optional Location; + + public: + DeclAsInlineDebugLocation(CodeGenFunction &CGF, const NamedDecl &Decl) + : DI(CGF.getDebugInfo()) { + if (!DI) + return; + InlinedAt = DI->getInlinedAt(); + DI->setInlinedAt(CGF.Builder.getCurrentDebugLocation()); + Location.emplace(CGF, Decl.getLocation()); + } + + ~DeclAsInlineDebugLocation() { + if (!DI) + return; + Location.reset(); + DI->setInlinedAt(InlinedAt); + } + }; + static void EmitSanitizerDtorCallback( CodeGenFunction &CGF, StringRef Name, llvm::Value *Ptr, llvm::Optional PoisonSize = {}) { @@ -1699,6 +1722,8 @@ if (!BaseSize.isPositive()) return; + // Set the top fields declaration location as inline DebugLocation. + DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass); EmitSanitizerDtorFieldsCallback(CGF, Addr.getPointer(), BaseSize.getQuantity()); @@ -1748,6 +1773,9 @@ if (!PoisonSize.isPositive()) return; + // Set the top fields declaration location as inline DebugLocation. + DeclAsInlineDebugLocation InlineHere( + CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex)); EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.getQuantity()); // Prevent the current stack frame from disappearing from the stack trace. diff --git a/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp b/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-bit-field.cpp @@ -83,7 +83,7 @@ // CHECK-LABEL: !DIFile{{.*}}cpp -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-68]] -// CHECK: ![[DI2]] = {{.*}}line: [[@LINE-53]] -// CHECK: ![[DI3]] = {{.*}}line: [[@LINE-41]] -// CHECK: ![[DI4]] = {{.*}}line: [[@LINE-28]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-78]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-54]] +// CHECK-DAG: ![[DI3]] = {{.*}}line: [[@LINE-46]] +// CHECK-DAG: ![[DI4]] = {{.*}}line: [[@LINE-30]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp b/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-callback.cpp @@ -70,6 +70,6 @@ // CHECK-LABEL: !DIFile{{.*}}cpp -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-64]] -// CHECK: ![[DI2]] = {{.*}}line: [[@LINE-55]] -// CHECK: ![[DI3]] = {{.*}}line: [[@LINE-33]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-65]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-56]] +// CHECK-DAG: ![[DI3]] = {{.*}}line: [[@LINE-34]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp b/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-derived-class.cpp @@ -50,17 +50,19 @@ // Poison members and vtable ptr. // CHECK-LABEL: define {{.*}}BaseD2Ev // CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI1:[0-9]+]] -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI1]] +// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI2:[0-9]+]] // CHECK: ret void // Poison members and destroy non-virtual base. // CHECK-LABEL: define {{.*}}DerivedD2Ev // CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI3:[0-9]+]] // CHECK: call void {{.*}}BaseD2Ev -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI3]] +// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI4:[0-9]+]] // CHECK: ret void // CHECK-LABEL: !DIFile{{.*}}cpp -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-49]] -// CHECK: ![[DI3]] = {{.*}}line: [[@LINE-39]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-55]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-50]] +// CHECK-DAG: ![[DI3]] = {{.*}}line: [[@LINE-46]] +// CHECK-DAG: ![[DI4]] = {{.*}}line: [[@LINE-41]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp b/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-nontrivial-virtual-base.cpp @@ -62,32 +62,34 @@ // poison 2 ints // CHECK-LABEL: define {{.*}}ZN11VirtualBaseD2Ev // CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 8){{.*}}, !dbg ![[DI1:[0-9]+]] -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}, !dbg ![[DI1]] +// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}){{.*}}{{.*}}, !dbg ![[DI2:[0-9]+]] // CHECK: ret void // poison int and double // CHECK-LABEL: define {{.*}}ZN4BaseD2Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16){{.*}}, !dbg ![[DI2:[0-9]+]] -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}{{.*}}, !dbg ![[DI2]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16){{.*}}, !dbg ![[DI3:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}{{.*}}, !dbg ![[DI4:[0-9]+]] // CHECK: ret void // poison int, ignore vector, poison int // CHECK-LABEL: define {{.*}}ZN7DerivedD2Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI3:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI5:[0-9]+]] // CHECK: call void {{.*}}ZN6VectorIiED1Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI3]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI6:[0-9]+]] // CHECK: call void {{.*}}ZN4BaseD2Ev // CHECK: ret void // poison int // CHECK-LABEL: define {{.*}}ZN6VectorIiED2Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI5:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 4){{.*}}, !dbg ![[DI7:[0-9]+]] // CHECK: ret void // CHECK-LABEL: !DIFile{{.*}}.cpp -// CHECK: ![[DI0]] = {{.*}}line: [[@LINE-49]] -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-60]] -// CHECK: ![[DI2]] = {{.*}}line: [[@LINE-71]] -// CHECK: ![[DI3]] = {{.*}}line: [[@LINE-52]] -// CHECK: ![[DI5]] = {{.*}}line: [[@LINE-83]] +// CHECK-DAG: ![[DI0]] = {{.*}}line: [[@LINE-49]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-66]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-61]] +// CHECK-DAG: ![[DI3]] = {{.*}}line: [[@LINE-78]] +// CHECK-DAG: ![[DI5]] = {{.*}}line: [[@LINE-57]] +// CHECK-DAG: ![[DI6]] = {{.*}}line: [[@LINE-60]] +// CHECK-DAG: ![[DI7]] = {{.*}}line: [[@LINE-88]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp b/clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-trivial-base.cpp @@ -20,10 +20,11 @@ // Poison members, then poison the trivial base class. // CHECK-LABEL: define {{.*}}DerivedD2Ev // CHECK: %[[GEP:[0-9a-z]+]] = getelementptr i8, i8* {{.*}}, i64 16 -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}%[[GEP]], i64 4{{.*}}, !dbg ![[DI:[0-9]+]] -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16{{.*}}, !dbg ![[DI]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}%[[GEP]], i64 4{{.*}}, !dbg ![[DI1:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, i64 16{{.*}}, !dbg ![[DI2:[0-9]+]] // CHECK: ret void // CHECK-LABEL: !DIFile{{.*}}cpp -// CHECK: ![[DI]] = {{.*}}line: [[@LINE-14]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-16]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-24]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp b/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-trivial.cpp @@ -16,10 +16,4 @@ // CHECK-LABEL: !DIFile{{.*}}.cpp -// CHECK: ![[DI]] = {{.*}}line: [[@LINE-371]] - -// CHECK-LABEL: !DIFile{{.*}}cpp - -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-28]] -// CHECK: ![[DI2]] = {{.*}}line: [[@LINE-37]] -// CHECK: ![[DI4]] = {{.*}}line: [[@LINE-30]] +// CHECK: ![[DI]] = {{.*}}line: [[@LINE-9]] diff --git a/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp b/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp --- a/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp +++ b/clang/test/CodeGenCXX/sanitize-dtor-vtable.cpp @@ -25,22 +25,23 @@ // CHECK-LABEL: define {{.*}}BD1Ev // CHECK: call void {{.*}}BD2Ev // CHECK: call void {{.*}}AD2Ev -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}, !dbg ![[DI1:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_vptr{{.*}}, !dbg ![[DI1:[0-9]+]] // CHECK: ret void // Since no virtual bases, poison vtable ptr here. // CHECK-LABEL: define {{.*}}AD2Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI2:[0-9]+]] -// CHECK: call void @__sanitizer_dtor_callback_vptr({{.*}}, !dbg ![[DI2]] +// CHECK: call void @__sanitizer_dtor_callback_fields{{.*}}, !dbg ![[DI2:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_vptr{{.*}}, !dbg ![[DI3:[0-9]+]] // CHECK: ret void // Poison members // CHECK-LABEL: define {{.*}}BD2Ev -// CHECK: call void @__sanitizer_dtor_callback_fields({{.*}}, !dbg ![[DI4:[0-9]+]] +// CHECK: call void @__sanitizer_dtor_callback_fields{{.*}}, !dbg ![[DI4:[0-9]+]] // CHECK: ret void -// CHECK-LABEL: !DIFile{{.*}}cpp +// CHECK-LABEL: !DIFile{{.*}}sanitize-dtor-vtable.cpp -// CHECK: ![[DI1]] = {{.*}}line: [[@LINE-28]] -// CHECK: ![[DI2]] = {{.*}}line: [[@LINE-37]] -// CHECK: ![[DI4]] = {{.*}}line: [[@LINE-30]] +// CHECK-DAG: ![[DI1]] = {{.*}}line: [[@LINE-28]] +// CHECK-DAG: ![[DI2]] = {{.*}}line: [[@LINE-39]] +// CHECK-DAG: ![[DI3]] = {{.*}}line: [[@LINE-38]] +// CHECK-DAG: ![[DI4]] = {{.*}}line: [[@LINE-33]] diff --git a/compiler-rt/test/msan/dtor-base-access.cpp b/compiler-rt/test/msan/dtor-base-access.cpp --- a/compiler-rt/test/msan/dtor-base-access.cpp +++ b/compiler-rt/test/msan/dtor-base-access.cpp @@ -68,17 +68,20 @@ __msan_print_shadow(&g->tb0, sizeof(g->tb0)); // CHECK: Member fields were destroyed // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}} - // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-20]]: + // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-56]]: + // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-21]]: __msan_print_shadow(&g->b, sizeof(g->b)); // CHECK: Member fields were destroyed // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}} - // CHECK: {{#1 0x.* in .*~Base.*cpp:}}[[@LINE-33]]: + // CHECK: {{#1 0x.* in .*~Base.*cpp:}}[[@LINE-67]]: + // CHECK: {{#2 0x.* in .*~Base.*cpp:}}[[@LINE-35]]: __msan_print_shadow(&g->tb1, sizeof(g->tb1)); // CHECK: Member fields were destroyed // CHECK: {{#0 0x.* in __sanitizer_dtor_callback}} - // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-30]]: + // CHECK: {{#1 0x.* in .*~Derived.*cpp:}}[[@LINE-62]]: + // CHECK: {{#2 0x.* in .*~Derived.*cpp:}}[[@LINE-33]]: return 0; } diff --git a/compiler-rt/test/msan/use-after-dtor.cpp b/compiler-rt/test/msan/use-after-dtor.cpp --- a/compiler-rt/test/msan/use-after-dtor.cpp +++ b/compiler-rt/test/msan/use-after-dtor.cpp @@ -34,7 +34,8 @@ // CHECK-ORIGINS: Member fields were destroyed // CHECK-ORIGINS: {{#0 0x.* in __sanitizer_dtor_callback}} - // CHECK-ORIGINS: {{#1 0x.* in .*~Simple.*cpp:}}[[@LINE-18]]: + // CHECK-ORIGINS: {{#1 0x.* in .*~Simple.*cpp:}}[[@LINE-24]]: + // CHECK-ORIGINS: {{#2 0x.* in .*~Simple.*cpp:}}[[@LINE-19]]: // CHECK-UAD: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*main}} // CHECK-UAD-OFF-NOT: SUMMARY: MemorySanitizer: use-of-uninitialized-value