Re-land [DebugInfo] Add debug location to stubs generated by CGDeclCXX and mark them as artificial

Previously, when clang was compiled with -DLLVM_ENABLE_ASSERTIONS=ON, the added tests were displaying:

inlinable function call in a function with debug info must have a !dbg location
  call void @"??1?$c@UB@@@@QEAA@XZ"(%struct.c* @"?f@?1??d@@YAPEAU?$c@UB@@@@XZ@4U2@A")
fatal error: error in backend: Broken module found, compilation aborted!
Stack dump:
0.      Program arguments: <f:\svn\buildninja\bin\clang -cc1 -emit-llvm debug-info-no-location.cpp> -gcodeview -debug-info-kind=limited
1.      <eof> parser at end of file
2.      Per-function optimization

Fixes PR43012

Differential Revision: https://reviews.llvm.org/D66328
This commit is contained in:
Alexandre Ganea 2020-10-08 20:48:50 -04:00
parent 1c19900f94
commit 66face6aa0
8 changed files with 83 additions and 25 deletions

View File

@ -32,6 +32,7 @@ enum class DynamicInitKind : unsigned {
NoStub = 0,
Initializer,
AtExit,
GlobalArrayDestructor
};
enum class KernelReferenceKind : unsigned {

View File

@ -2041,7 +2041,8 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD,
llvm::Function *InitFn) {
// If we're not emitting codeview, use the mangled name. For Itanium, this is
// arbitrary.
if (!CGM.getCodeGenOpts().EmitCodeView)
if (!CGM.getCodeGenOpts().EmitCodeView ||
StubKind == DynamicInitKind::GlobalArrayDestructor)
return InitFn->getName();
// Print the normal qualified name for the variable, then break off the last
@ -2066,6 +2067,7 @@ StringRef CGDebugInfo::getDynamicInitializerName(const VarDecl *VD,
switch (StubKind) {
case DynamicInitKind::NoStub:
case DynamicInitKind::GlobalArrayDestructor:
llvm_unreachable("not an initializer");
case DynamicInitKind::Initializer:
OS << "`dynamic initializer for '";
@ -3832,7 +3834,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, SourceLocation Loc,
if (Name.startswith("\01"))
Name = Name.substr(1);
if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>()) {
if (!HasDecl || D->isImplicit() || D->hasAttr<ArtificialAttr>() ||
(isa<VarDecl>(D) && GD.getDynamicInitKind() != DynamicInitKind::NoStub)) {
Flags |= llvm::DINode::FlagArtificial;
// Artificial functions should not silently reuse CurLoc.
CurLoc = SourceLocation();

View File

@ -247,6 +247,8 @@ llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD,
CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit),
CGM.getContext().VoidTy, fn, FI, FunctionArgList(),
VD.getLocation(), VD.getInit()->getExprLoc());
// Emit an artificial location for this function.
auto AL = ApplyDebugLocation::CreateArtificial(CGF);
llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
@ -672,8 +674,9 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
StartFunction(GlobalDecl(D, DynamicInitKind::Initializer),
getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(),
FunctionArgList(), D->getLocation(),
D->getInit()->getExprLoc());
FunctionArgList());
// Emit an artificial location for this function.
auto AL = ApplyDebugLocation::CreateArtificial(*this);
// Use guarded initialization if the global variable is weak. This
// occurs for, e.g., instantiated static data members and
@ -807,7 +810,10 @@ llvm::Function *CodeGenFunction::generateDestroyHelper(
CurEHLocation = VD->getBeginLoc();
StartFunction(VD, getContext().VoidTy, fn, FI, args);
StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor),
getContext().VoidTy, fn, FI, args);
// Emit an artificial location for this function.
auto AL = ApplyDebugLocation::CreateArtificial(*this);
emitDestroy(addr, type, destroyer, useEHCleanupForArray);

View File

@ -16,14 +16,14 @@ X v;
// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR16:[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN1XC1Ev(%struct.X* @v), !dbg ![[DBGVAR19:[0-9]+]]
// CHECK: %0 = call i32 @atexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg ![[DBGVAR19]]
// CHECK: %0 = call i32 @atexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg ![[DBGVAR19b:[0-9]+]]
// CHECK: ret void, !dbg ![[DBGVAR19]]
// CHECK: }
// CHECK: define internal void @__dtor_v() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR20:[0-9]+]] {
// CHECK: entry:
// CHECK: call void @_ZN1XD1Ev(%struct.X* @v), !dbg ![[DBGVAR21:[0-9]+]]
// CHECK: ret void, !dbg ![[DBGVAR21]]
// CHECK: call void @_ZN1XD1Ev(%struct.X* @v), !dbg ![[DBGVAR21b:[0-9]+]]
// CHECK: ret void, !dbg ![[DBGVAR21:[0-9]+]]
// CHECK: }
// CHECK: define internal void @__finalize_v() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR22:[0-9]+]] {
@ -52,9 +52,11 @@ X v;
// CHECK: ret void
// CHECK: }
// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
// CHECK: ![[DBGVAR19]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR16]])
// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
// CHECK: ![[DBGVAR19b]] = !DILocation(line: 0, scope: ![[DBGVAR16]])
// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
// CHECK: ![[DBGVAR21b]] = !DILocation(line: 0, scope: ![[DBGVAR20]])
// CHECK: ![[DBGVAR21]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR20]])
// CHECK: ![[DBGVAR22]] = distinct !DISubprogram(linkageName: "__finalize_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
// CHECK: ![[DBGVAR24]] = !DILocation(line: 14, column: 3, scope: ![[DBGVAR22]])

View File

@ -0,0 +1,22 @@
// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s
struct a {
~a();
};
template <typename b> struct c : a {
c(void (b::*)());
};
struct B {
virtual void e();
};
c<B> *d() {
static c<B> f(&B::e);
return &f;
}
// CHECK: define internal void @"??__Ff@?1??d@@YAPEAU?$c@UB@@@@XZ@YAXXZ"()
// CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] {
// CHECK: call void @"??1?$c@UB@@@@QEAA@XZ"(%struct.c* @"?f@?1??d@@YAPEAU?$c@UB@@@@XZ@4U2@A"), !dbg ![[LOCATION:[0-9]+]]
// CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "`dynamic atexit destructor for 'f'"
// CHECK-SAME: flags: DIFlagArtificial
// CHECK: ![[LOCATION]] = !DILocation(line: 0, scope: ![[SUBPROGRAM]])

View File

@ -0,0 +1,24 @@
// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -o - | FileCheck %s
struct b {
b(char *);
~b();
};
struct a {
~a();
};
struct {
b c;
const a &d;
} e[]{nullptr, {}};
// CHECK: define internal void @__cxx_global_array_dtor(i8* %0)
// CHECK-SAME: !dbg ![[SUBPROGRAM:[0-9]+]] {
// CHECK: arraydestroy.body
// CHECK: %arraydestroy.elementPast =
// CHECK-SAME: !dbg ![[LOCATION:[0-9]+]]
// CHECK: call void @"??1<unnamed-type-e>@@QEAA@XZ"(%struct.anon* %arraydestroy.element)
// CHECK-SAME: !dbg ![[LOCATION]]
// CHECK: ![[SUBPROGRAM]] = distinct !DISubprogram(name: "__cxx_global_array_dtor"
// CHECK-SAME: flags: DIFlagArtificial
// CHECK: ![[LOCATION]] = !DILocation(line: 0,

View File

@ -29,25 +29,25 @@ template <typename U>
A FooTpl<T>::sdm_tpl(sizeof(U) + sizeof(T));
template A FooTpl<int>::sdm_tpl<int>;
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 15,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 16,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 19,{{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-NOKEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-KEXT: !DISubprogram({{.*}} DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'glob'",{{.*}} line: 15,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'array'",{{.*}} line: 16,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'stat'",{{.*}} line: 19,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'glob'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'glob'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic initializer for 'array'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'array'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "`dynamic atexit destructor for 'stat'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// MSVC does weird stuff when templates are involved, so we don't match exactly,
// but these names are reasonable.
// FIXME: These should not be marked DISPFlagLocalToUnit.
// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic initializer for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic atexit destructor for 'sdm_tpl<int>'",{{.*}} line: 29,{{.*}}: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic initializer for 'sdm_tpl<int>'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
// CHECK-MSVC: !DISubprogram(name: "FooTpl<int>::`dynamic atexit destructor for 'sdm_tpl<int>'",{{.*}} flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition

View File

@ -314,7 +314,7 @@ void f25() {
// CHECK: [[DBG_F9]] = !DILocation(line: 1000,
// CHECK: [[DBG_F10_STORE]] = !DILocation(line: 1100,
// CHECK: [[DBG_GLBL_CTOR_B]] = !DILocation(line: 1200,
// CHECK: [[DBG_GLBL_DTOR_B]] = !DILocation(line: 1200,
// CHECK: [[DBG_GLBL_DTOR_B]] = !DILocation(line: 0,
// CHECK: [[DBG_F11]] = !DILocation(line: 1300,
// CHECK: [[DBG_F12]] = !DILocation(line: 1400,
// CHECK: [[DBG_F13]] = !DILocation(line: 1500,