diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -11688,6 +11688,14 @@ if (FD->isMSExternInline()) return GVA_StrongODR; + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && + isa(FD) && + cast(FD)->isInheritingConstructor()) + // Our approach to inheriting constructors is fundamentally different from + // that used by the MS ABI, so keep our inheriting constructor thunks + // internal rather than trying to pick an unambiguous mangling for them. + return GVA_Internal; + return GVA_DiscardableODR; } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1970,15 +1970,6 @@ if (const auto *Dtor = dyn_cast(D)) return getCXXABI().getCXXDestructorLinkage(Linkage, Dtor, GD.getDtorType()); - if (isa(D) && - cast(D)->isInheritingConstructor() && - Context.getTargetInfo().getCXXABI().isMicrosoft()) { - // Our approach to inheriting constructors is fundamentally different from - // that used by the MS ABI, so keep our inheriting constructor thunks - // internal rather than trying to pick an unambiguous mangling for them. - return llvm::GlobalValue::InternalLinkage; - } - return getLLVMLinkageForDeclarator(D, Linkage); } diff --git a/clang/test/CodeGenCXX/ms-inheriting-ctor.cpp b/clang/test/CodeGenCXX/ms-inheriting-ctor.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/ms-inheriting-ctor.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fcxx-exceptions -triple=x86_64-windows-msvc -emit-llvm %s -o - | FileCheck %s + +class F { +public: + F(wchar_t *); +}; +using a = F; +struct A {}; +struct b { + b(a, F, A); +}; +template struct c : b { + c(const a &p1, const A &d) : b(p1, 0, d) {} +}; +template struct B : c { + using c::c; +}; +class f { +public: + f(...); +} + +typedef g; +class C { +public: + C(g, f); +}; +static wchar_t h; +class D { +public: + static C E(); +}; + +C D::E() { + C i(B(&h, {}), f()); + return i; +} + +// Inheriting ctor has internal linkage without comdat. + +// CHECK-LABEL: define internal noundef ptr @"??0?$B@_N@@QEAA@AEBVF@@AEBUA@@@Z" +// CHECK-NOT:comdat +// CHECK-SAME: {{\{$}} + +// non-inheriting ctro should has linkonce_odr with comdat attribute. + +// CHECK-LABEL: define linkonce_odr dso_local noundef ptr @"??0?$c@_NUb@@@@QEAA@AEBVF@@AEBUA@@@Z" +// CHECK:comdat +// CHECK-SAME: {{\{$}}