Skip to content

Commit c8df781

Browse files
committed
[DebugInfo] Fix bug in constructor homing with classes with trivial
constructors. This changes the code to avoid using constructor homing for aggregate classes and classes with trivial default constructors, instead of trying to loop through the constructors. Differential Revision: https://reviews.llvm.org/D87808
1 parent e392865 commit c8df781

File tree

2 files changed

+52
-12
lines changed

2 files changed

+52
-12
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2281,22 +2281,20 @@ static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I,
22812281
}
22822282

22832283
static bool canUseCtorHoming(const CXXRecordDecl *RD) {
2284-
// Constructor homing can be used for classes that have at least one
2285-
// constructor and have no trivial or constexpr constructors.
2284+
// Constructor homing can be used for classes that cannnot be constructed
2285+
// without emitting code for one of their constructors. This is classes that
2286+
// don't have trivial or constexpr constructors, or can be created from
2287+
// aggregate initialization. Also skip lambda objects because they don't call
2288+
// constructors.
2289+
22862290
// Skip this optimization if the class or any of its methods are marked
22872291
// dllimport.
2288-
if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
2289-
isClassOrMethodDLLImport(RD))
2290-
return false;
2291-
2292-
if (RD->ctors().empty())
2292+
if (isClassOrMethodDLLImport(RD))
22932293
return false;
22942294

2295-
for (const auto *Ctor : RD->ctors())
2296-
if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
2297-
return false;
2298-
2299-
return true;
2295+
return !RD->isLambda() && !RD->isAggregate() &&
2296+
!RD->hasTrivialDefaultConstructor() &&
2297+
!RD->hasConstexprNonCopyMoveConstructor();
23002298
}
23012299

23022300
static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,

clang/test/CodeGenCXX/debug-info-limited-ctor.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,56 @@ struct D {
2020
};
2121
D::D() {}
2222

23+
// Test for constexpr constructor.
2324
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue
2425
struct E {
2526
constexpr E(){};
2627
} TestE;
2728

29+
// Test for trivial constructor.
2830
// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "F"{{.*}}DIFlagTypePassByValue
2931
struct F {
3032
F() = default;
3133
F(int) {}
3234
int i;
3335
} TestF;
36+
37+
// Test for trivial constructor.
38+
// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: "G"{{.*}}DIFlagTypePassByValue
39+
// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
40+
struct G {
41+
G() : g_(0) {}
42+
struct {
43+
int g_;
44+
};
45+
} TestG;
46+
47+
// Test for an aggregate class with an implicit non-trivial default constructor
48+
// that is not instantiated.
49+
// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
50+
struct H {
51+
B b;
52+
};
53+
void f(H h) {}
54+
55+
// Test for an aggregate class with an implicit non-trivial default constructor
56+
// that is instantiated.
57+
// CHECK-DAG: !DICompositeType({{.*}}name: "J",{{.*}}DIFlagTypePassByValue
58+
struct J {
59+
B b;
60+
};
61+
void f(decltype(J()) j) {}
62+
63+
// Test for a class with trivial default constructor that is not instantiated.
64+
// CHECK-DAG: !DICompositeType({{.*}}name: "K",{{.*}}DIFlagTypePassByValue
65+
class K {
66+
int i;
67+
};
68+
void f(K k) {}
69+
70+
// Test that we don't use constructor homing on lambdas.
71+
// CHECK-DAG: ![[L:.*]] ={{.*}}!DISubprogram({{.*}}name: "L"
72+
// CHECK-DAG: !DICompositeType({{.*}}scope: ![[L]], {{.*}}DIFlagTypePassByValue
73+
void L() {
74+
auto func = [&]() {};
75+
}

0 commit comments

Comments
 (0)