jyu2 created this revision. jyu2 added reviewers: rnk, rsmith, majnemer, cfe-commits. jyu2 added a project: clang. Herald added a project: All. jyu2 requested review of this revision.
Currently, for MS, the linkage for the inheriting constructors is set to internal. However, the comdat attribute is also set like: 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 comdat This could cause linker to fail. The change is to remove comdat attribute for the inheriting constructor to make linker happy. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D158538 Files: clang/lib/AST/ASTContext.cpp clang/test/CodeGenCXX/ms-inheriting-ctor.cpp Index: clang/test/CodeGenCXX/ms-inheriting-ctor.cpp =================================================================== --- /dev/null +++ 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 <typename, typename> struct c : b { + c(const a &p1, const A &d) : b(p1, 0, d) {} +}; +template <typename e> struct B : c<e, b> { + using c<e, b>::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<bool>(&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 Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -11688,6 +11688,14 @@ if (FD->isMSExternInline()) return GVA_StrongODR; + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && + isa<CXXConstructorDecl>(FD) && + cast<CXXConstructorDecl>(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; }
Index: clang/test/CodeGenCXX/ms-inheriting-ctor.cpp =================================================================== --- /dev/null +++ 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 <typename, typename> struct c : b { + c(const a &p1, const A &d) : b(p1, 0, d) {} +}; +template <typename e> struct B : c<e, b> { + using c<e, b>::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<bool>(&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 Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -11688,6 +11688,14 @@ if (FD->isMSExternInline()) return GVA_StrongODR; + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && + isa<CXXConstructorDecl>(FD) && + cast<CXXConstructorDecl>(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; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits