On Wed, Jan 16, 2019 at 1:57 AM Akira Hatanaka <ahatan...@apple.com> wrote: > > Yes, the behavior of the compiler doesn’t match what’s explained in the > documentation anymore. > > Please take a look at the attached patch, which updates the documentation.
Patch mostly LGTM, but I did have one wording suggestion. > diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td > index 5773a92c9c..ca3cfcf9b2 100644 > --- a/include/clang/Basic/AttrDocs.td > +++ b/include/clang/Basic/AttrDocs.td > @@ -2478,15 +2478,20 @@ def TrivialABIDocs : Documentation { > let Category = DocCatVariable; > let Content = [{ > The ``trivial_abi`` attribute can be applied to a C++ class, struct, or > union. > -It instructs the compiler to pass and return the type using the C ABI for the > +``trivial_abi`` has the following effects: > + > +- It instructs the compiler to pass and return the type using the C ABI for > the > underlying type when the type would otherwise be considered non-trivial for > the > purpose of calls. > -A class annotated with `trivial_abi` can have non-trivial destructors or > copy/move constructors without automatically becoming non-trivial for the > purposes of calls. For example: > +- It makes the destructor and copy and move constructors of the class trivial > +that would otherwise be considered non-trivial under the C++ ABI rules. How about: It makes the destructor, copy constructors, and move constructors of the class trivial even if they would otherwise be non-trivial under the C++ ABI rules. ~Aaron > + > +For example: > > .. code-block:: c++ > > - // A is trivial for the purposes of calls because `trivial_abi` makes the > - // user-provided special functions trivial. > + // A is trivial for the purposes of calls despite having a destructor and > + // copy and move constructors that are non-trivial under the C++ ABI > rules. > struct __attribute__((trivial_abi)) A { > ~A(); > A(const A &); > @@ -2495,11 +2500,26 @@ A class annotated with `trivial_abi` can have > non-trivial destructors or copy/mo > }; > > // B's destructor and copy/move constructor are considered trivial for > the > - // purpose of calls because A is trivial. > + // purpose of calls because A's destructor and copy and move constructors > + // are treated as being trivial. > struct B { > A a; > }; > > + // C is trivial for the purposes of calls despite having all of its copy > and > + // move constructors deleted. > + struct __attribute__((trivial_abi)) C { > + C(const C &) = delete; > + C(C &&) = delete; > + int x; > + }; > + > + // D is non-trivial for the purposes of calls since it isn't annotated > with > + // trivial_abi and all of its copy and move constructors are deleted. > + struct D { > + C c; > + }; > + > If a type is trivial for the purposes of calls, has a non-trivial destructor, > and is passed as an argument by value, the convention is that the callee will > destroy the object before returning. > > > > > CC’ing a couple more people who commented on the original patch. > > On Jan 10, 2019, at 11:30 PM, Richard Smith <rich...@metafoo.co.uk> wrote: > > This is an ABI break (theoretically), but due to its nature I'm not too > concerned. > > Please update the documentation for the attribute to describe these new > semantics, though: the documentation currently says that we're just treating > certain special members as if they were trivial when determining whether we > can pass in registers, and that's not true any more, because the ABI says > that classes with only deleted copy and move ctors is never passed in > registers regardless of triviality. > > On Thu, 10 Jan 2019, 23:10 Akira Hatanaka via cfe-commits > <cfe-commits@lists.llvm.org wrote: >> >> Author: ahatanak >> Date: Thu Jan 10 23:06:38 2019 >> New Revision: 350920 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=350920&view=rev >> Log: >> [Sema] Make canPassInRegisters return true if the CXXRecordDecl passed >> to it is a trivial_abi class. >> >> A class that has all of its copy and move constructors deleted can still >> be passed or returned in registers if the class is annotated with >> trivial_abi. >> >> This fixes PR39683. >> >> Modified: >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> cfe/trunk/test/CodeGenCXX/trivial_abi.cpp >> >> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=350920&r1=350919&r2=350920&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jan 10 23:06:38 2019 >> @@ -5886,6 +5886,9 @@ static bool canPassInRegisters(Sema &S, >> if (D->isDependentType() || D->isInvalidDecl()) >> return false; >> >> + if (D->hasAttr<TrivialABIAttr>()) >> + return true; >> + >> // Clang <= 4 used the pre-C++11 rule, which ignores move operations. >> // The PS4 platform ABI follows the behavior of Clang 3.2. >> if (CCK == TargetInfo::CCK_ClangABI4OrPS4) >> >> Modified: cfe/trunk/test/CodeGenCXX/trivial_abi.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/trivial_abi.cpp?rev=350920&r1=350919&r2=350920&view=diff >> ============================================================================== >> --- cfe/trunk/test/CodeGenCXX/trivial_abi.cpp (original) >> +++ cfe/trunk/test/CodeGenCXX/trivial_abi.cpp Thu Jan 10 23:06:38 2019 >> @@ -1,5 +1,5 @@ >> -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions >> -fexceptions -emit-llvm -o - %s | FileCheck %s >> -// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fcxx-exceptions >> -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s >> +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions >> -fexceptions -emit-llvm -o - %s | FileCheck %s >> +// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++17 -fcxx-exceptions >> -fexceptions -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s >> >> // CHECK: %[[STRUCT_SMALL:.*]] = type { i32* } >> // CHECK: %[[STRUCT_LARGE:.*]] = type { i32*, [128 x i32] } >> @@ -43,6 +43,13 @@ struct HasNonTrivial { >> NonTrivial m; >> }; >> >> +struct __attribute__((trivial_abi)) CopyMoveDeleted { >> + CopyMoveDeleted(int); >> + CopyMoveDeleted(const CopyMoveDeleted &) = delete; >> + CopyMoveDeleted(CopyMoveDeleted &&) = delete; >> + int a; >> +}; >> + >> // CHECK: define void @_Z14testParamSmall5Small(i64 %[[A_COERCE:.*]]) >> // CHECK: %[[A:.*]] = alloca %[[STRUCT_SMALL]], align 8 >> // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_SMALL]], >> %[[STRUCT_SMALL]]* %[[A]], i32 0, i32 0 >> @@ -237,3 +244,11 @@ void calleeExceptionLarge(Large, Large); >> void testExceptionLarge() { >> calleeExceptionLarge(Large(), Large()); >> } >> + >> +// A class with deleted copy and move constructors can still be passed or >> +// returned in registers if the class is annotated with trivial_abi. >> + >> +// CHECK: define i64 @_Z19testCopyMoveDeletedi(i32 % >> +CopyMoveDeleted testCopyMoveDeleted(int a) { >> + return a; >> +} >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits