When defining a copy constructor or assignment operator as either explicitly defaulted (= default) or deleted (= delete), it's possible to give it a different parameter list from the normal (const Foo &).
For = default, the only allowed change [1] is to use a non-const reference instead of a const one:
struct X {
X(X &) = default;
};
For = delete, it's also possible to add additional parameters with default values, as well as variadic parameters (...).
(Besides the parameter list, it's also possible to change the exception specification and ref-qualifiers, but those never affected triviality.)
Originally, C++11 (which introduced explicit defaulting) had a rule that any modification of the parameter list would prevent the function from being considered trivial, so e.g. is_trivially_copyable_v<X> would be false. However, Defect Report 2171 [2] (2016) removed that rule entirely. Up until now, that change hasn't been implemented in Clang; this patch implements it.
In addition, Clang currently applies a similar rule to deleted *default* constructors, which AFAICT is not in compliance with any published version of the spec. So this fails when it should pass:
struct X {
X(...) = delete;
};
static_assert(__has_trivial_constructor(X));
This patch also fixes that.
This is an ABI-breaking change, since the existence of trivial constructors affects whether a type is "trivial for the purposes of calls" [3]. I checked other compilers to see whether they implement the DR:
- GCC has never treated such functions as nontrivial, even before the DR. [4]
- MSVC currently doesn't treat them as nontrivial [5]; I haven't checked old versions since they're not on Godbolt.
Thus the change would improve Clang's compatibility with those compilers.
Implementation-wise, this patch is simple enough: it just removes the code in Sema::SpecialMemberIsTrivial that checked the parameter list. In terms of tests, there were already a number of tests verifying the old behavior, so the patch merely updates them for the new behavior.
[1] https://eel.is/c++draft/dcl.fct.def.default#2
[2] http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#2171
[3] https://quuxplusone.github.io/blog/2018/05/02/trivial-abi-101/
[4] https://gcc.godbolt.org/z/GU_wyz (note GCC version)
[5] https://gcc.godbolt.org/z/VYiMn3
There is corresponding code in lib/AST/DeclCXX.cpp that attempts to determine whether special members are trivial "on the fly" (without performing overload resolution etc). Please check whether that needs to be updated too.