[clang] [Clang] Ensure child classes export inherited constructors from base classes (PR #182706)
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 20 05:11:33 PDT 2026
================
@@ -6604,13 +6617,52 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) {
if (MD->isDeleted())
continue;
+ // Don't export inherited constructors whose parameters prevent ABI-
+ // compatible forwarding. When canEmitDelegateCallArgs (in CodeGen)
+ // returns false, Clang inlines the constructor body instead of
+ // emitting a forwarding thunk, producing code that is not ABI-
+ // compatible with MSVC. Suppress the export and warn so the user
+ // gets a linker error rather than a silent runtime mismatch.
+ if (ClassExported) {
+ if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
+ if (CD->getInheritedConstructor()) {
+ if (CD->isVariadic()) {
+ Diag(CD->getLocation(),
+ diag::warn_dllexport_inherited_ctor_unsupported)
+ << /*variadic=*/0;
+ continue;
+ }
+ if (Context.getTargetInfo()
+ .getCXXABI()
+ .areArgsDestroyedLeftToRightInCallee()) {
+ bool HasCalleeCleanupParam = false;
+ for (const auto *P : CD->parameters())
+ if (P->needsDestruction(Context)) {
+ HasCalleeCleanupParam = true;
+ break;
+ }
+ if (HasCalleeCleanupParam) {
+ Diag(CD->getLocation(),
+ diag::warn_dllexport_inherited_ctor_unsupported)
+ << /*callee-cleanup=*/1;
+ continue;
+ }
+ }
+ }
+ }
+ }
+
if (MD->isInlined()) {
// MinGW does not import or export inline methods. But do it for
- // template instantiations.
+ // template instantiations and inherited constructors (which are
+ // marked inline but must be exported to match MSVC behavior).
----------------
zmodem wrote:
We don't need to match MSVC behavior when targeting MinGW. I think what matters is really what GCC does. @mstorsjo
https://github.com/llvm/llvm-project/pull/182706
More information about the cfe-commits
mailing list