On Fri, Nov 18, 2022 at 09:26:26PM -0500, Jason Merrill wrote: > On 11/16/22 15:27, Jason Merrill wrote: > > On 11/16/22 11:06, Marek Polacek wrote: > > > On Wed, Nov 16, 2022 at 08:41:53AM -0500, Jason Merrill wrote: > > > > On 11/15/22 19:30, Marek Polacek wrote: > > > > > @@ -996,19 +1040,26 @@ register_constexpr_fundef (const > > > > > constexpr_fundef &value) > > > > > **slot = value; > > > > > } > > > > > -/* FUN is a non-constexpr function called in a context that requires > > > > > a > > > > > - constant expression. If it comes from a constexpr > > > > > template, explain why > > > > > - the instantiation isn't constexpr. */ > > > > > +/* FUN is a non-constexpr (or, with -Wno-invalid-constexpr, > > > > > a constexpr > > > > > + function called in a context that requires a constant expression). > > > > > + If it comes from a constexpr template, explain why the > > > > > instantiation > > > > > + isn't constexpr. */ > > > > > > > > The "if it comes from a constexpr template" wording has needed > > > > an update for > > > > a while now. > > > > > > Probably ever since r178519. I've added "Otherwise, explain why the > > > function > > > cannot be used in a constexpr context." Is that acceptable? > > > > > --- /dev/null > > > > > +++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit15.C > > > > > @@ -0,0 +1,43 @@ > > > > > +// PR c++/106649 > > > > > +// P2448 - Relaxing some constexpr restrictions > > > > > +// { dg-do compile { target c++23 } } > > > > > +// { dg-options "-Winvalid-constexpr" } > > > > > +// A copy/move assignment operator for a class X that is defaulted > > > > > and > > > > > +// not defined as deleted is implicitly defined when it is odr-used, > > > > > +// when it is needed for constant evaluation, or when it is > > > > > explicitly > > > > > +// defaulted after its first declaration. > > > > > +// The implicitly-defined copy/move assignment operator is constexpr. > > > > > + > > > > > +struct S { > > > > > + constexpr S() {} > > > > > + S& operator=(const S&) = default; // #1 > > > > > + S& operator=(S&&) = default; // #2 > > > > > +}; > > > > > + > > > > > +struct U { > > > > > + constexpr U& operator=(const U&) = default; > > > > > + constexpr U& operator=(U&&) = default; > > > > > +}; > > > > > + > > > > > +/* FIXME: If we only declare #1 and #2, and default them here: > > > > > + > > > > > + S& S::operator=(const S&) = default; > > > > > + S& S::operator=(S&&) = default; > > > > > + > > > > > +then they aren't constexpr. This sounds like a bug: > > > > > +<https://gcc.gnu.org/PR107598>. */ > > > > > > > > As I commented on the PR, I don't think this is actually a bug, so let's > > > > omit this FIXME. > > > > > > I'm glad I didn't really attempt to "fix" it (the inform message is > > > flawed > > > and should be improved). Thanks for taking a look. > > > > > > Here's a version with the two comments updated. > > > > > > Ok? > > > > OK. > > Since this patch I'm seeing these failures: > > FAIL: g++.dg/cpp0x/constexpr-ex1.C -std=c++23 -fimplicit-constexpr at line > 91 (test for errors, line 89) > FAIL: g++.dg/cpp23/constexpr-nonlit10.C -std=gnu++23 -fimplicit-constexpr > (test for warnings, line 14) > FAIL: g++.dg/cpp23/constexpr-nonlit10.C -std=gnu++23 -fimplicit-constexpr > (test for warnings, line 20) > FAIL: g++.dg/cpp23/constexpr-nonlit11.C -std=gnu++23 -fimplicit-constexpr > (test for warnings, line 28) > FAIL: g++.dg/cpp23/constexpr-nonlit11.C -std=gnu++23 -fimplicit-constexpr > (test for warnings, line 31) > FAIL: g++.dg/cpp2a/spaceship-eq3.C -std=c++23 -fimplicit-constexpr (test > for excess errors)
Ah, sorry. The following patch fixes those fails. Ok? -- >8 -- Some of the new tests were failing with -fimplicit-constexpr. This patch adjusts the expected diagnostic. Tested with GXX_TESTSUITE_STDS=98,11,14,17,20,23 make check-c++ RUNTESTFLAGS="--target_board=unix\{,-fimplicit-constexpr\} dg.exp=spaceship-eq3.C" gcc/testsuite/ChangeLog: * g++.dg/cpp0x/constexpr-ex1.C: Adjust dg-error. * g++.dg/cpp23/constexpr-nonlit10.C: Adjust dg-warning. * g++.dg/cpp23/constexpr-nonlit11.C: Likewise. * g++.dg/cpp2a/spaceship-eq3.C: Add dg-error. --- gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C | 6 +++--- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C | 4 ++-- gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C | 4 ++-- gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C | 1 + 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C index 48281a47784..383d38a42d4 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ex1.C @@ -87,8 +87,8 @@ struct resource { } }; constexpr resource f(resource d) -{ return d; } // { dg-error "non-.constexpr." "" { target { { ! implicit_constexpr } && c++20_down } } } -// { dg-error "non-.constexpr." "" { target c++23 } .-2 } -constexpr resource d = f(9); // { dg-message ".constexpr." "" { target { ! implicit_constexpr } } } +{ return d; } // { dg-error "non-.constexpr." "" { target { { { ! implicit_constexpr } && c++20_down } || c++11_only } } } +// { dg-error "non-.constexpr." "" { target { c++23 && { ! implicit_constexpr } } } .-2 } +constexpr resource d = f(9); // { dg-message ".constexpr." "" { target { { ! implicit_constexpr } || c++11_only } } } // 4.4 floating-point constant expressions diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C index 48706f7b66e..31d4b873bbf 100644 --- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C +++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit10.C @@ -11,13 +11,13 @@ struct NonLiteral { // C++23: It is possible to write a constexpr function for which no // invocation satisfies the requirements of a core constant expression. constexpr NonLiteral -fn0 (int) // { dg-warning "invalid return type" } +fn0 (int) // { dg-warning "invalid return type" "" { target { ! implicit_constexpr } } } { return NonLiteral{}; } constexpr int -fn1 (NonLiteral) // { dg-warning "invalid type" } +fn1 (NonLiteral) // { dg-warning "invalid type" "" { target { ! implicit_constexpr } } } { return 42; } diff --git a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C index a7114bc66cb..e08809f873c 100644 --- a/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C +++ b/gcc/testsuite/g++.dg/cpp23/constexpr-nonlit11.C @@ -25,10 +25,10 @@ struct X { struct S { X x; // Calls a non-constexpr constructor X::X(int). - constexpr S(int i) : x(i) { } // { dg-warning "call to" } + constexpr S(int i) : x(i) { } // { dg-warning "call to" "" { target { ! implicit_constexpr } } } S(int, int) { } // Target constructor isn't constexpr. - constexpr S() : S(42, 42) { } // { dg-warning "call to" } + constexpr S() : S(42, 42) { } // { dg-warning "call to" "" { target { ! implicit_constexpr } } } }; namespace N1 { diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C index 69eaa7b9b20..246839f1f95 100644 --- a/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-eq3.C @@ -9,6 +9,7 @@ struct D A i; bool operator==(const D& x) const = default; // { dg-error "A::operator==" "" { target c++20_down } } bool operator!=(const D& z) const = default; // { dg-error "D::operator==" "" { target c++20_down } } +// { dg-error "called" "" { target { c++23 && implicit_constexpr } } .-1 } }; constexpr D d{A()}; base-commit: d19aa6af6634b1e97f38431ad091f3b3f12baf2f -- 2.38.1