[clang] c8df781 - [DebugInfo] Fix bug in constructor homing with classes with trivial

Amy Huang via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 24 14:44:00 PDT 2020


Author: Amy Huang
Date: 2020-09-24T14:43:48-07:00
New Revision: c8df781e54a43593eafd993a5a5cd647866955f8

URL: https://github.com/llvm/llvm-project/commit/c8df781e54a43593eafd993a5a5cd647866955f8
DIFF: https://github.com/llvm/llvm-project/commit/c8df781e54a43593eafd993a5a5cd647866955f8.diff

LOG: [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

Added: 
    

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/test/CodeGenCXX/debug-info-limited-ctor.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 1fdb6814c7bd..27c584ff0795 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -2281,22 +2281,20 @@ static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I,
 }
 
 static bool canUseCtorHoming(const CXXRecordDecl *RD) {
-  // Constructor homing can be used for classes that have at least one
-  // constructor and have no trivial or constexpr constructors.
+  // Constructor homing can be used for classes that cannnot be constructed
+  // without emitting code for one of their constructors. This is classes that
+  // don't have trivial or constexpr constructors, or can be created from
+  // aggregate initialization. Also skip lambda objects because they don't call
+  // constructors.
+
   // Skip this optimization if the class or any of its methods are marked
   // dllimport.
-  if (RD->isLambda() || RD->hasConstexprNonCopyMoveConstructor() ||
-      isClassOrMethodDLLImport(RD))
-    return false;
-
-  if (RD->ctors().empty())
+  if (isClassOrMethodDLLImport(RD))
     return false;
 
-  for (const auto *Ctor : RD->ctors())
-    if (Ctor->isTrivial() && !Ctor->isCopyOrMoveConstructor())
-      return false;
-
-  return true;
+  return !RD->isLambda() && !RD->isAggregate() &&
+         !RD->hasTrivialDefaultConstructor() &&
+         !RD->hasConstexprNonCopyMoveConstructor();
 }
 
 static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,

diff  --git a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
index 89dd2b16b75b..cf2e89e35522 100644
--- a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
+++ b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp
@@ -20,14 +20,56 @@ struct D {
 };
 D::D() {}
 
+// Test for constexpr constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "E"{{.*}}DIFlagTypePassByValue
 struct E {
   constexpr E(){};
 } TestE;
 
+// Test for trivial constructor.
 // CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "F"{{.*}}DIFlagTypePassByValue
 struct F {
   F() = default;
   F(int) {}
   int i;
 } TestF;
+
+// Test for trivial constructor.
+// CHECK-DAG: ![[G:.*]] ={{.*}}!DICompositeType({{.*}}name: "G"{{.*}}DIFlagTypePassByValue
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[G]], {{.*}}DIFlagTypePassByValue
+struct G {
+  G() : g_(0) {}
+  struct {
+    int g_;
+  };
+} TestG;
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "H",{{.*}}DIFlagTypePassByValue
+struct H {
+  B b;
+};
+void f(H h) {}
+
+// Test for an aggregate class with an implicit non-trivial default constructor
+// that is instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "J",{{.*}}DIFlagTypePassByValue
+struct J {
+  B b;
+};
+void f(decltype(J()) j) {}
+
+// Test for a class with trivial default constructor that is not instantiated.
+// CHECK-DAG: !DICompositeType({{.*}}name: "K",{{.*}}DIFlagTypePassByValue
+class K {
+  int i;
+};
+void f(K k) {}
+
+// Test that we don't use constructor homing on lambdas.
+// CHECK-DAG: ![[L:.*]] ={{.*}}!DISubprogram({{.*}}name: "L"
+// CHECK-DAG: !DICompositeType({{.*}}scope: ![[L]], {{.*}}DIFlagTypePassByValue
+void L() {
+  auto func = [&]() {};
+}


        


More information about the cfe-commits mailing list