Skip to content

Commit

Permalink
[clang codegen] Fix MS ABI detection of user-provided constructors. (l…
Browse files Browse the repository at this point in the history
…lvm#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
  • Loading branch information
efriedma-quic authored Apr 29, 2024
1 parent 7eac39f commit 3ab4ae9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
6 changes: 6 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------------------

Expand Down
12 changes: 9 additions & 3 deletions clang/lib/CodeGen/MicrosoftCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CXXConstructorDecl>(D)) {
if (Ctor->isUserProvided())
return false;
} else if (auto *Template = dyn_cast<FunctionTemplateDecl>(D)) {
if (isa<CXXConstructorDecl>(Template->getTemplatedDecl()))
return false;
}
}
if (RD->hasNonTrivialDestructor())
return false;
return true;
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CodeGen/arm64-microsoft-arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,18 @@ S11 f11() {
S11 x;
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 {{.*}})
// CHECK: call void @"?func12@@YA?AUS12@@U1@@Z"(ptr dead_on_unwind inreg writable sret(%struct.S12) align 4 {{.*}}, i64 {{.*}})
struct S12 {
template<typename T> S12(T*) {}
int x;
};
S12 func12(S12 x);
S12 f12() {
S12 x((int*)0);
return func12(x);
}

0 comments on commit 3ab4ae9

Please sign in to comment.