[PATCH] D74684: [Sema][C++] Adopt DR2171 relaxed triviality requirements

Nicholas Allegra via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 16 00:29:48 PST 2020


comex created this revision.
comex added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D74684

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CXX/class/class.union/p1.cpp
  clang/test/CXX/special/class.copy/p12-0x.cpp
  clang/test/CXX/special/class.copy/p25-0x.cpp
  clang/test/CXX/special/class.ctor/p5-0x.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D74684.244857.patch
Type: text/x-patch
Size: 12295 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200216/e912b261/attachment-0001.bin>


More information about the cfe-commits mailing list