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/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,42 @@ +// 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, should not with comdat. + +// CHECK-LABEL: define internal noundef ptr @"??0?$B@_N@@QEAA@AEBVF@@AEBUA@@@Z"(ptr noundef nonnull returned align 1 dereferenceable(1) %this, ptr noundef nonnull align 1 dereferenceable(1) %0, ptr noundef nonnull align 1 dereferenceable(1) %1) unnamed_addr #2 align 2 +// CHECK-LABEL: define linkonce_odr dso_local noundef ptr @"??0?$c@_NUb@@@@QEAA@AEBVF@@AEBUA@@@Z"(ptr noundef nonnull returned align 1 dereferenceable(1) %this, ptr noundef nonnull align 1 dereferenceable(1) %p1, ptr noundef nonnull align 1 dereferenceable(1) %d) unnamed_addr #2 comdat align 2