diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2300,7 +2300,16 @@ if (isClassOrMethodDLLImport(RD)) return false; - return !RD->isLambda() && !RD->isAggregate() && + // Attempt to avoid using constructor homing if a class is used but for + // whatever reason is not constructed. Constructors are added to the class + // definition when used, so use the existence of constructors here as a + // heuristic. + bool HasCtor = false; + for (auto *Ctor : RD->ctors()) + if (!Ctor->isCopyOrMoveConstructor() && !Ctor->isDeleted()) + HasCtor = true; + + return HasCtor && !RD->isLambda() && !RD->isAggregate() && !RD->hasTrivialDefaultConstructor() && !RD->hasConstexprNonCopyMoveConstructor(); } diff --git a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp --- a/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp +++ b/clang/test/CodeGenCXX/debug-info-limited-ctor.cpp @@ -74,6 +74,14 @@ auto func = [&]() {}; } +// Test that a class that otherwise should be subject to constructor homing +// is not because its constructor isn't used in this translation unit. +// CHECK-DAG: !DICompositeType({{.*}}name: "M",{{.*}}DIFlagTypePassByValue +class M { + B b; +}; +void f(M m) {} + // Check that types are being added to retained types list. // CHECK-DAG: !DICompileUnit{{.*}}retainedTypes: ![[RETAINED:[0-9]+]] // CHECK-DAG: ![[RETAINED]] = {{.*}}![[C]]