Howdy! The tricky details of copy constructors, part 76. In this approach, I let the const-copy "dominate"; that is, if a const-copy was found, a non-const-copy will not turn off triviality of the copy constructor, and a const-copy will reinstate triviality of the copy constructor even if a non-const copy removed said triviality.
I suppose we could try moving this knowledge from the class level to the level of special member function decl, but I wonder whether we have the bits to do that. This approach seems to solve the problem, certainly. This has been tested manually on Linux-x64, running full suite on Linux-PPC64. Thoughts? OK for trunk if the full suite passes? 2018-09-13 Ville Voutilainen <ville.voutilai...@gmail.com> gcc/cp PR c++/87051 * decl.c (grok_special_member_properties): Don't mark the class as having a non-trivial copy constructor if the copy constructor we're looking at is not a const-copy and a const-copy was already found, reset the copy constructor triviality if we found a trivial const-copy. testsuite/ PR c++/87051 * g++.dg/ext/is_trivially_constructible7.C: New.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 50b60e8..1b09721 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13211,8 +13211,11 @@ grok_special_member_properties (tree decl) are no other parameters or else all other parameters have default arguments. */ TYPE_HAS_COPY_CTOR (class_type) = 1; - if (user_provided_p (decl)) - TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1; + if (user_provided_p (decl) + && (ctor > 1 || !TYPE_HAS_CONST_COPY_CTOR (class_type))) + TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1; + else if (ctor > 1) + TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 0; if (ctor > 1) TYPE_HAS_CONST_COPY_CTOR (class_type) = 1; } diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C new file mode 100644 index 0000000..177eb2e --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible7.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++11 } } + +// PR c++/87051 + +struct M { + M(const M&) = default; + M(M&); +}; + +struct M2 { + M2(M2&); + M2(const M2&) = default; +}; + +static_assert( __is_trivially_constructible(M, M&&), ""); +static_assert( __is_trivially_constructible(M2, M2&&), "");