Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -3616,6 +3616,11 @@ if (MD->getParent()->getNumVBases()) return StructorCodegen::Emit; + // Omitting the complete structor can degrade debug quality as the debugger + // cannot locate the complete structor symbol anymore. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return StructorCodegen::Emit; + GlobalDecl AliasDecl; if (const auto *DD = dyn_cast(MD)) { AliasDecl = GlobalDecl(DD, Dtor_Complete); Index: test/CodeGenCXX/constructor-alias.cpp =================================================================== --- test/CodeGenCXX/constructor-alias.cpp +++ test/CodeGenCXX/constructor-alias.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple mipsel--linux-gnu -mconstructor-aliases -O1 -disable-llvm-passes -o - %s | FileCheck %s // The target attribute code used to get confused with aliases. Make sure // we don't crash when an alias is used. Index: test/CodeGenCXX/ctor-dtor-alias.cpp =================================================================== --- test/CodeGenCXX/ctor-dtor-alias.cpp +++ test/CodeGenCXX/ctor-dtor-alias.cpp @@ -77,11 +77,12 @@ // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align - // test that we don't do this optimization at -O0 so that the debugger can - // see both destructors. + // test that we don't do this optimization at -O0 and call the complete + // destructor for B instead. This enables the debugger to see both + // destructors. // NOOPT: define internal void @__cxx_global_var_init.2() - // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev - // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align + // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD1Ev + // NOOPT: define linkonce_odr void @_ZN5test41BD1Ev({{.*}} comdat align struct A { virtual ~A() {} }; Index: test/CodeGenCXX/dllexport-alias.cpp =================================================================== --- test/CodeGenCXX/dllexport-alias.cpp +++ test/CodeGenCXX/dllexport-alias.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -O1 -disable-llvm-passes -o - | FileCheck %s // This test assumes that the C1 constructor will be aliased to the C2 // constructor, and the D1 destructor to the D2. It then checks that the aliases Index: test/CodeGenCXX/virtual-bases.cpp =================================================================== --- test/CodeGenCXX/virtual-bases.cpp +++ test/CodeGenCXX/virtual-bases.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases -O1 -disable-llvm-passes | FileCheck %s struct A { A();