[PATCH] D57626: Disallow trivial_abi on a class if all copy and move constructors are deleted
Akira Hatanaka via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 1 15:10:06 PST 2019
ahatanak created this revision.
ahatanak added reviewers: rsmith, rjmccall, aaron.ballman.
ahatanak added a project: clang.
Herald added subscribers: dexonsmith, jkorous.
Instead of forcing the class to be passed in registers, which was what r350920 did, issue a warning and inform the user that the attribute cannot be used.
For more background, see this discussion: http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20190128/259907.html
This fixes PR39683.
rdar://problem/47308221
Repository:
rC Clang
https://reviews.llvm.org/D57626
Files:
include/clang/Basic/AttrDocs.td
lib/Sema/SemaDeclCXX.cpp
test/SemaObjCXX/attr-trivial-abi.mm
Index: test/SemaObjCXX/attr-trivial-abi.mm
===================================================================
--- test/SemaObjCXX/attr-trivial-abi.mm
+++ test/SemaObjCXX/attr-trivial-abi.mm
@@ -95,3 +95,36 @@
};
S17<int> s17;
+
+namespace deletedCopyMoveConstructor {
+ struct __attribute__((trivial_abi)) CopyMoveDeleted { // expected-warning {{'trivial_abi' cannot be applied to 'CopyMoveDeleted'}}
+ CopyMoveDeleted(const CopyMoveDeleted &) = delete;
+ CopyMoveDeleted(CopyMoveDeleted &&) = delete;
+ };
+
+ struct __attribute__((trivial_abi)) S18 { // expected-warning {{'trivial_abi' cannot be applied to 'S18'}}
+ CopyMoveDeleted a;
+ S18(const S18 &);
+ S18(S18 &&);
+ };
+
+ struct __attribute__((trivial_abi)) CopyDeleted {
+ CopyDeleted(const CopyDeleted &) = delete;
+ CopyDeleted(CopyDeleted &&) = default;
+ };
+
+ struct __attribute__((trivial_abi)) MoveDeleted {
+ MoveDeleted(const MoveDeleted &) = default;
+ MoveDeleted(MoveDeleted &&) = delete;
+ };
+
+ struct __attribute__((trivial_abi)) S19 { // expected-warning {{'trivial_abi' cannot be applied to 'S19'}}
+ CopyDeleted a;
+ MoveDeleted b;
+ };
+
+ // This is fine since the move constructor isn't deleted.
+ struct __attribute__((trivial_abi)) S20 {
+ int &&a; // a member of rvalue reference type deletes the copy constructor.
+ };
+}
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -7868,6 +7868,25 @@
RD.dropAttr<TrivialABIAttr>();
};
+ // Ill-formed if the copy and move constructors are deleted.
+ auto HasNonDeletedCopyOrMoveConstructor = [&]() {
+ if (RD.needsImplicitCopyConstructor() &&
+ !RD.defaultedCopyConstructorIsDeleted())
+ return true;
+ if (RD.needsImplicitMoveConstructor() &&
+ !RD.defaultedMoveConstructorIsDeleted())
+ return true;
+ for (const CXXConstructorDecl *CD : RD.ctors())
+ if (CD->isCopyOrMoveConstructor() && !CD->isDeleted())
+ return true;
+ return false;
+ };
+
+ if (!HasNonDeletedCopyOrMoveConstructor()) {
+ PrintDiagAndRemoveAttr();
+ return;
+ }
+
// Ill-formed if the struct has virtual functions.
if (RD.isPolymorphic()) {
PrintDiagAndRemoveAttr();
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -2566,6 +2566,7 @@
Attribute ``trivial_abi`` has no effect in the following cases:
- The class directly declares a virtual base or virtual methods.
+- The class doesn't have a copy or move constructor that isn't deleted.
- The class has a base class that is non-trivial for the purposes of calls.
- The class has a non-static data member whose type is non-trivial for the purposes of calls, which includes:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D57626.184858.patch
Type: text/x-patch
Size: 2913 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190201/59077ade/attachment.bin>
More information about the cfe-commits
mailing list