Skip to content

Commit ffbaa2a

Browse files
efriedma-quicllvmbot
authored andcommitted
[clang codegen] Fix MS ABI detection of user-provided constructors. (llvm#90151)
In the context of determining whether a class counts as an "aggregate", a constructor template counts as a user-provided constructor. Fixes llvm#86384 (cherry picked from commit 3ab4ae9)
1 parent f341c76 commit ffbaa2a

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ ABI Changes in This Version
149149
- Following the SystemV ABI for x86-64, ``__int128`` arguments will no longer
150150
be split between a register and a stack slot.
151151

152+
- Fixed Microsoft calling convention for returning certain classes with a
153+
templated constructor. If a class has a templated constructor, it should
154+
be returned indirectly even if it meets all the other requirements for
155+
returning a class in a register. This affects some uses of std::pair.
156+
(#GH86384).
157+
152158
AST Dumping Potentially Breaking Changes
153159
----------------------------------------
154160
- When dumping a sugared type, Clang will no longer print the desugared type if

clang/lib/CodeGen/MicrosoftCXXABI.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,9 +1135,15 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
11351135
return false;
11361136
if (RD->hasNonTrivialCopyAssignment())
11371137
return false;
1138-
for (const CXXConstructorDecl *Ctor : RD->ctors())
1139-
if (Ctor->isUserProvided())
1140-
return false;
1138+
for (const Decl *D : RD->decls()) {
1139+
if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1140+
if (Ctor->isUserProvided())
1141+
return false;
1142+
} else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
1143+
if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
1144+
return false;
1145+
}
1146+
}
11411147
if (RD->hasNonTrivialDestructor())
11421148
return false;
11431149
return true;

clang/test/CodeGen/arm64-microsoft-arguments.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,18 @@ S11 f11() {
201201
S11 x;
202202
return func11(x);
203203
}
204+
205+
// GH86384
206+
// Pass and return object with template constructor (pass directly,
207+
// return indirectly).
208+
// CHECK: define dso_local void @"?f12@@YA?AUS12@@XZ"(ptr dead_on_unwind inreg noalias writable sret(%struct.S12) align 4 {{.*}})
209+
// CHECK: call void @"?func12@@YA?AUS12@@U1@@Z"(ptr dead_on_unwind inreg writable sret(%struct.S12) align 4 {{.*}}, i64 {{.*}})
210+
struct S12 {
211+
template<typename T> S12(T*) {}
212+
int x;
213+
};
214+
S12 func12(S12 x);
215+
S12 f12() {
216+
S12 x((int*)0);
217+
return func12(x);
218+
}

0 commit comments

Comments
 (0)