Re: [PATCH v2] c++: P2448 - Relaxing some constexpr restrictions [PR106649]

2022-11-16 Thread Jason Merrill via Gcc-patches

On 11/15/22 19:30, Marek Polacek wrote:

On Mon, Nov 14, 2022 at 06:00:58PM -0500, Jason Merrill wrote:

On 11/9/22 10:53, Marek Polacek wrote:

This patch implements C++23 P2448, which lifts more restrictions on the
constexpr keyword.  It's effectively going the way of being just a hint
(hello, inline!).

This gist is relatively simple: in C++23, a constexpr function's return
type/parameter type doesn't have to be a literal type; and you can have
a constexpr function for which no invocation satisfies the requirements
of a core constant expression.  For example,

void f(int& i); // not constexpr

constexpr void g(int& i) {
  f(i); // unconditionally calls a non-constexpr function
}

is now OK, even though there isn't an invocation of 'g' that would be
a constant expression.  Maybe 'f' will be made constexpr soon, or maybe
this depends on the version of C++ used, and similar.  The patch is
unfortunately not that trivial.  The important bit is to use the new
require_potential_rvalue_constant_expression_fncheck in
maybe_save_constexpr_fundef (and where appropriate).  It has a new flag
that says that we're checking the body of a constexpr function, and in
that case it's OK to find constructs that aren't a constant expression.

Since it's useful to be able to check for problematic constructs even
in C++23, this patch implements a new warning, -Winvalid-constexpr,
which is a pedwarn turned on by default in C++20 and earlier, and which
can be turned on in C++23 as well, in which case it's an ordinary warning.
This I implemented by using the new function constexpr_error, used in
p_c_e_1 and friends.  (In some cases I believe fundef_p will be always
false (= hard error), but it made sense to me to be consistent and use
constexpr_error throughout p_c_e_1.)

While working on this I think I found a bug, see constexpr-nonlit15.C
and .  This patch doesn't address that.

I also don't love that in C++23, if you don't use -Winvalid-constexpr,
and call a constexpr function that in fact isn't constexpr-ready yet,
sometimes all you get is an error saying "called in a constant expression"
like in constexpr-nonlit12.C.  This could be remedied by some tweaks to
explain_invalid_constexpr_fn, I reckon (it gives up on !DECL_DEFAULTED_FN).


And also in maybe_save_constexpr_fn: if -Wno-invalid-constexpr, "complain"
should be false so we save the definition for explain_invalid_constexpr_fn
to refer to.


I did something similar: don't return if warn_invalid_constexpr == 0.
I thought I'd just adjust the initializer for 'complain' but due to
constexpr-ice4.C we should call is_valid_constexpr_fn even when
warn_invalid_constexpr is 0.  The only non-testsuite changes are to
maybe_save_constexpr_fundef and explain_invalid_constexpr_fn.

Updated patch below, now we emit a better diagnostic for
constexpr-nonlit12.C even with -std=c++23.  And also in C++20 with
-Wno-invalid-constexpr.


Great.


Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch implements C++23 P2448, which lifts more restrictions on the
constexpr keyword.  It's effectively going the way of being just a hint
(hello, inline!).

This gist is relatively simple: in C++23, a constexpr function's return
type/parameter type doesn't have to be a literal type; and you can have
a constexpr function for which no invocation satisfies the requirements
of a core constant expression.  For example,

   void f(int& i); // not constexpr

   constexpr void g(int& i) {
 f(i); // unconditionally calls a non-constexpr function
   }

is now OK, even though there isn't an invocation of 'g' that would be
a constant expression.  Maybe 'f' will be made constexpr soon, or maybe
this depends on the version of C++ used, and similar.  The patch is
unfortunately not that trivial.  The important bit is to use the new
require_potential_rvalue_constant_expression_fncheck in
maybe_save_constexpr_fundef (and where appropriate).  It has a new flag
that says that we're checking the body of a constexpr function, and in
that case it's OK to find constructs that aren't a constant expression.

Since it's useful to be able to check for problematic constructs even
in C++23, this patch implements a new warning, -Winvalid-constexpr,
which is a pedwarn turned on by default in C++20 and earlier, and which
can be turned on in C++23 as well, in which case it's an ordinary warning.
This I implemented by using the new function constexpr_error, used in
p_c_e_1 and friends.  (In some cases I believe fundef_p will be always
false (= hard error), but it made sense to me to be consistent and use
constexpr_error throughout p_c_e_1.)

While working on this I think I found a bug, see constexpr-nonlit15.C
and .  This patch doesn't address that.

This patch includes changes to diagnose the problem if the user doesn't
use -Winvalid-constexpr and calls a constexpr function that in fact isn't
constexpr-ready yet: 

[PATCH v2] c++: P2448 - Relaxing some constexpr restrictions [PR106649]

2022-11-15 Thread Marek Polacek via Gcc-patches
On Mon, Nov 14, 2022 at 06:00:58PM -0500, Jason Merrill wrote:
> On 11/9/22 10:53, Marek Polacek wrote:
> > This patch implements C++23 P2448, which lifts more restrictions on the
> > constexpr keyword.  It's effectively going the way of being just a hint
> > (hello, inline!).
> > 
> > This gist is relatively simple: in C++23, a constexpr function's return
> > type/parameter type doesn't have to be a literal type; and you can have
> > a constexpr function for which no invocation satisfies the requirements
> > of a core constant expression.  For example,
> > 
> >void f(int& i); // not constexpr
> > 
> >constexpr void g(int& i) {
> >  f(i); // unconditionally calls a non-constexpr function
> >}
> > 
> > is now OK, even though there isn't an invocation of 'g' that would be
> > a constant expression.  Maybe 'f' will be made constexpr soon, or maybe
> > this depends on the version of C++ used, and similar.  The patch is
> > unfortunately not that trivial.  The important bit is to use the new
> > require_potential_rvalue_constant_expression_fncheck in
> > maybe_save_constexpr_fundef (and where appropriate).  It has a new flag
> > that says that we're checking the body of a constexpr function, and in
> > that case it's OK to find constructs that aren't a constant expression.
> > 
> > Since it's useful to be able to check for problematic constructs even
> > in C++23, this patch implements a new warning, -Winvalid-constexpr,
> > which is a pedwarn turned on by default in C++20 and earlier, and which
> > can be turned on in C++23 as well, in which case it's an ordinary warning.
> > This I implemented by using the new function constexpr_error, used in
> > p_c_e_1 and friends.  (In some cases I believe fundef_p will be always
> > false (= hard error), but it made sense to me to be consistent and use
> > constexpr_error throughout p_c_e_1.)
> > 
> > While working on this I think I found a bug, see constexpr-nonlit15.C
> > and .  This patch doesn't address that.
> > 
> > I also don't love that in C++23, if you don't use -Winvalid-constexpr,
> > and call a constexpr function that in fact isn't constexpr-ready yet,
> > sometimes all you get is an error saying "called in a constant expression"
> > like in constexpr-nonlit12.C.  This could be remedied by some tweaks to
> > explain_invalid_constexpr_fn, I reckon (it gives up on !DECL_DEFAULTED_FN).
> 
> And also in maybe_save_constexpr_fn: if -Wno-invalid-constexpr, "complain"
> should be false so we save the definition for explain_invalid_constexpr_fn
> to refer to.

I did something similar: don't return if warn_invalid_constexpr == 0.
I thought I'd just adjust the initializer for 'complain' but due to
constexpr-ice4.C we should call is_valid_constexpr_fn even when
warn_invalid_constexpr is 0.  The only non-testsuite changes are to
maybe_save_constexpr_fundef and explain_invalid_constexpr_fn.

Updated patch below, now we emit a better diagnostic for 
constexpr-nonlit12.C even with -std=c++23.  And also in C++20 with
-Wno-invalid-constexpr.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch implements C++23 P2448, which lifts more restrictions on the
constexpr keyword.  It's effectively going the way of being just a hint
(hello, inline!).

This gist is relatively simple: in C++23, a constexpr function's return
type/parameter type doesn't have to be a literal type; and you can have
a constexpr function for which no invocation satisfies the requirements
of a core constant expression.  For example,

  void f(int& i); // not constexpr

  constexpr void g(int& i) {
f(i); // unconditionally calls a non-constexpr function
  }

is now OK, even though there isn't an invocation of 'g' that would be
a constant expression.  Maybe 'f' will be made constexpr soon, or maybe
this depends on the version of C++ used, and similar.  The patch is
unfortunately not that trivial.  The important bit is to use the new
require_potential_rvalue_constant_expression_fncheck in
maybe_save_constexpr_fundef (and where appropriate).  It has a new flag
that says that we're checking the body of a constexpr function, and in
that case it's OK to find constructs that aren't a constant expression.

Since it's useful to be able to check for problematic constructs even
in C++23, this patch implements a new warning, -Winvalid-constexpr,
which is a pedwarn turned on by default in C++20 and earlier, and which
can be turned on in C++23 as well, in which case it's an ordinary warning.
This I implemented by using the new function constexpr_error, used in
p_c_e_1 and friends.  (In some cases I believe fundef_p will be always
false (= hard error), but it made sense to me to be consistent and use
constexpr_error throughout p_c_e_1.)

While working on this I think I found a bug, see constexpr-nonlit15.C
and .  This patch doesn't address that.

This patch includes changes to diagnose the problem if the user doesn't