Anonymous unions should be transparent wrt `[[clang::trivial_abi]]`.
commitbddaa35177861545fc329123e55b6a3b34549507
authorDmitri Gribenko <gribozavr@gmail.com>
Mon, 7 Aug 2023 18:13:33 +0000 (7 20:13 +0200)
committerDmitri Gribenko <gribozavr@gmail.com>
Mon, 7 Aug 2023 18:30:48 +0000 (7 20:30 +0200)
treeca3e4fe74033cd2451baf61bd24ef18425856a35
parentb8fef7a6d40105ac9bc3bf67268ff1245c4be5c8
Anonymous unions should be transparent wrt `[[clang::trivial_abi]]`.

Anonymous unions should be transparent wrt `[[clang::trivial_abi]]`.

Consider the test input below:

 ```
 struct [[clang::trivial_abi]] Trivial {
   Trivial() {}
   Trivial(Trivial&& other) {}
   Trivial& operator=(Trivial&& other) { return *this; }
   ~Trivial() {}
 };
 static_assert(__is_trivially_relocatable(Trivial), "");

 struct [[clang::trivial_abi]] S2 {
   S2(S2&& other) {}
   S2& operator=(S2&& other) { return *this; }
   ~S2() {}
   union { Trivial field; };
 };
 static_assert(__is_trivially_relocatable(S2), "");
 ```

Before the fix Clang would warn that 'trivial_abi' is disallowed on 'S2'
because it has a field of a non-trivial class type (the type of the
anonymous union is non-trivial, because it doesn't have the
`[[clang::trivial_abi]]` attribute applied to it).  Consequently, before
the fix the `static_assert` about `__is_trivially_relocatable` would
fail.

Note that `[[clang::trivial_abi]]` cannot be applied to the anonymous
union, because Clang warns that 'trivial_abi' is disallowed on '(unnamed
union at ...)' because its copy constructors and move constructors are
all deleted. Also note that it is impossible to provide copy nor move
constructors for anonymous unions and structs.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D155895
clang/include/clang/Basic/LangOptions.h
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/SemaCXX/attr-trivial-abi.cpp