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

Reply via email to