From 9adeffc9ee780c84a525ce0535a84508105e05ae Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 25 Apr 2024 17:06:40 -0700 Subject: [PATCH 1/2] [clang codegen] Fix MS ABI detection of user-provided constructors. In the context of determining whether a class counts as an "aggregate", a constructor template counts as a user-provided constructor. Fixes #86384 --- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 12 +++++++++--- clang/test/CodeGen/arm64-microsoft-arguments.cpp | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index d38a26940a3cb..d47927745759e 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1131,9 +1131,15 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty, return false; if (RD->hasNonTrivialCopyAssignment()) return false; - for (const CXXConstructorDecl *Ctor : RD->ctors()) - if (Ctor->isUserProvided()) - return false; + for (const Decl *D : RD->decls()) { + if (auto *Ctor = dyn_cast(D)) { + if (Ctor->isUserProvided()) + return false; + } else if (auto *Template = dyn_cast(D)) { + if (isa(Template->getTemplatedDecl())) + return false; + } + } if (RD->hasNonTrivialDestructor()) return false; return true; diff --git a/clang/test/CodeGen/arm64-microsoft-arguments.cpp b/clang/test/CodeGen/arm64-microsoft-arguments.cpp index e8309888dcfe2..89299277422a2 100644 --- a/clang/test/CodeGen/arm64-microsoft-arguments.cpp +++ b/clang/test/CodeGen/arm64-microsoft-arguments.cpp @@ -201,3 +201,17 @@ S11 f11() { S11 x; return func11(x); } + +// Pass and return object with template constructor (pass directly, +// return indirectly). +// CHECK: define dso_local void @"?f12@@YA?AUS12@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.S12) align 4 {{.*}}) +// CHECK: call void @"?func12@@YA?AUS12@@U1@@Z"(ptr dead_on_unwind inreg writable sret(%struct.S12) align 4 {{.*}}, i64 {{.*}}) +struct S12 { + template S12(T*) {} + int x; +}; +S12 func12(S12 x); +S12 f12() { + S12 x((int*)0); + return func12(x); +} From b3b974ec14754cb552b1a650010e57aeb7cab0e9 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 26 Apr 2024 13:20:30 -0700 Subject: [PATCH 2/2] Address review comments. --- clang/docs/ReleaseNotes.rst | 6 ++++++ clang/test/CodeGen/arm64-microsoft-arguments.cpp | 1 + 2 files changed, 7 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b5b351f3d30a7..57883313d9eae 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -63,6 +63,12 @@ ABI Changes in This Version MSVC uses a different mangling for these objects, compatibility is not affected. (#GH85423). +- Fixed Microsoft calling convention for returning certain classes with a + templated constructor. If a class has a templated constructor, it should + be returned indirectly even if it meets all the other requirements for + returning a class in a register. This affects some uses of std::pair. + (#GH86384). + AST Dumping Potentially Breaking Changes ---------------------------------------- diff --git a/clang/test/CodeGen/arm64-microsoft-arguments.cpp b/clang/test/CodeGen/arm64-microsoft-arguments.cpp index 89299277422a2..85472645acb3b 100644 --- a/clang/test/CodeGen/arm64-microsoft-arguments.cpp +++ b/clang/test/CodeGen/arm64-microsoft-arguments.cpp @@ -202,6 +202,7 @@ S11 f11() { return func11(x); } +// GH86384 // Pass and return object with template constructor (pass directly, // return indirectly). // CHECK: define dso_local void @"?f12@@YA?AUS12@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.S12) align 4 {{.*}})