diff options
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 1 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 2 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/ctor-dtor-alias.cpp | 13 |
4 files changed, 20 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8981bfe89cb..7a97aa64ea9 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1953,6 +1953,13 @@ static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl &D) { llvm_unreachable("No such linkage"); } +void CodeGenModule::maybeSetTrivialComdat(const Decl &D, + llvm::GlobalObject &GO) { + if (!shouldBeInCOMDAT(*this, D)) + return; + GO.setComdat(TheModule.getOrInsertComdat(GO.getName())); +} + void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { llvm::Constant *Init = nullptr; QualType ASTTy = D->getType(); @@ -2096,8 +2103,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { setTLSMode(GV, *D); } - if (shouldBeInCOMDAT(*this, *D)) - GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); + maybeSetTrivialComdat(*D, *GV); // Emit the initializer function if necessary. if (NeedsGlobalCtor || NeedsGlobalDtor) @@ -2433,8 +2439,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, MaybeHandleStaticInExternC(D, Fn); - if (shouldBeInCOMDAT(*this, *D)) - Fn->setComdat(TheModule.getOrInsertComdat(Fn->getName())); + maybeSetTrivialComdat(*D, *Fn); CodeGenFunction(*this).GenerateCode(D, Fn, FI); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index ddcb414508a..4559aecff12 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -606,6 +606,7 @@ public: const TargetInfo &getTarget() const { return Target; } const llvm::Triple &getTriple() const; bool supportsCOMDAT() const; + void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO); CGCXXABI &getCXXABI() const { return *ABI; } llvm::LLVMContext &getLLVMContext() { return VMContext; } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index f2ffabcf3e9..7d8ad465bf3 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -3202,5 +3202,7 @@ void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD, getMangleContext().mangleCXXCtorComdat(CD, Out); llvm::Comdat *C = CGM.getModule().getOrInsertComdat(Out.str()); Fn->setComdat(C); + } else { + CGM.maybeSetTrivialComdat(*MD, *Fn); } } diff --git a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp index bd60cb88bb2..6f8aedc0712 100644 --- a/clang/test/CodeGenCXX/ctor-dtor-alias.cpp +++ b/clang/test/CodeGenCXX/ctor-dtor-alias.cpp @@ -22,7 +22,10 @@ namespace test1 { // CHECK1-NOT: comdat // COFF doesn't support comdats with arbitrary names (C5/D5). -// COFF-NOT: comdat +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC2Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC1Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED2Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED0Ev({{.*}} comdat align template <typename T> struct foobar { @@ -39,7 +42,7 @@ namespace test2 { // CHECK1: define internal void @__cxx_global_var_init() // CHECK1: call void @_ZN5test26foobarIvEC2Ev -// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev( +// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev({{.*}} comdat align void g(); template <typename T> struct foobar { foobar() { g(); } @@ -72,13 +75,13 @@ namespace test4 { // CHECK1: define internal void @__cxx_global_var_init2() // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev - // CHECK1: define linkonce_odr void @_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. // NOOPT: define internal void @__cxx_global_var_init2() // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev - // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev + // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align struct A { virtual ~A() {} }; @@ -93,7 +96,7 @@ namespace test5 { // CHECK2: define internal void @__cxx_global_var_init3() // CHECK2: call i32 @__cxa_atexit{{.*}}_ZN5test51AD2Ev - // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev( + // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev({{.*}} comdat align struct A { virtual ~A() {} }; |