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

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 <https://gcc.gnu.org/PR107598>.  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: maybe_save_constexpr_fundef registers the function
if warn_invalid_constexpr is 0 and explain_invalid_constexpr_fn then
gives the diagnostic.

	PR c++/106649

gcc/c-family/ChangeLog:

	* c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_constexpr for
	C++23.
	* c-opts.cc (c_common_post_options): Set warn_invalid_constexpr
	depending on cxx_dialect.
	* c.opt (Winvalid-constexpr): New option.

gcc/cp/ChangeLog:

	* constexpr.cc (constexpr_error): New function.
	(is_valid_constexpr_fn): Use constexpr_error.
	(maybe_save_constexpr_fundef): Call
	require_potential_rvalue_constant_expression_fncheck rather than
	require_potential_rvalue_constant_expression.  Register the
	function if -Wno-invalid-constexpr was specified.
	(explain_invalid_constexpr_fn): Don't return early if a function marked
	'constexpr' that isn't actually a constant expression was called.
	(non_const_var_error): Add a bool parameter.  Use constexpr_error.
	(inline_asm_in_constexpr_error): Likewise.
	(cxx_eval_constant_expression): Adjust calls to non_const_var_error
	and inline_asm_in_constexpr_error.
	(potential_constant_expression_1): Add a bool parameter.  Use
	constexpr_error.
	(require_potential_rvalue_constant_expression_fncheck): New function.
	* cp-tree.h (require_potential_rvalue_constant_expression_fncheck):
	Declare.
	* method.cc (struct comp_info): Call
	require_potential_rvalue_constant_expression_fncheck rather than
	require_potential_rvalue_constant_expression.

gcc/ChangeLog:

	* doc/invoke.texi: Document -Winvalid-constexpr.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/constexpr-ctor2.C: Expect an error in c++20_down only.
	* g++.dg/cpp0x/constexpr-default-ctor.C: Likewise.
	* g++.dg/cpp0x/constexpr-diag3.C: Likewise.
	* g++.dg/cpp0x/constexpr-ex1.C: Likewise.
	* g++.dg/cpp0x/constexpr-friend.C: Likewise.
	* g++.dg/cpp0x/constexpr-generated1.C: Likewise.
	* g++.dg/cpp0x/constexpr-ice5.C: Likewise.
	* g++.dg/cpp0x/constexpr-ice6.C: Likewise.
	* g++.dg/cpp0x/constexpr-memfn1.C: Likewise.
	* g++.dg/cpp0x/constexpr-neg2.C: Likewise.
	* g++.dg/cpp0x/constexpr-non-const-arg.C: Likewise.
	* g++.dg/cpp0x/constexpr-reinterpret1.C: Likewise.
	* g++.dg/cpp0x/pr65327.C: Likewise.
	* g++.dg/cpp1y/constexpr-105050.C: Likewise.
	* g++.dg/cpp1y/constexpr-89285-2.C: Likewise.
	* g++.dg/cpp1y/constexpr-89285.C: Likewise.
	* g++.dg/cpp1y/constexpr-89785-2.C: Likewise.
	* g++.dg/cpp1y/constexpr-neg1.C: Likewise.
	* g++.dg/cpp1y/constexpr-nsdmi7b.C: Likewise.
	* g++.dg/cpp1y/constexpr-throw.C: Likewise.
	* g++.dg/cpp23/constexpr-nonlit3.C: Remove dg-error.
	* g++.dg/cpp23/constexpr-nonlit6.C: Call the test functions.
	* g++.dg/cpp23/feat-cxx2b.C: Adjust the expected value of
	__cpp_constexpr.
	* g++.dg/cpp2a/consteval3.C: Remove dg-error.
	* g++.dg/cpp2a/constexpr-new7.C: Expect an error in c++20_down only.
	* g++.dg/cpp2a/constexpr-try5.C: Remove dg-error.
	* g++.dg/cpp2a/spaceship-constexpr1.C: Expect an error in c++20_down
	only.
	* g++.dg/cpp2a/spaceship-eq3.C: Likewise.
	* g++.dg/diagnostic/constexpr1.C: Remove dg-error.
	* g++.dg/gomp/pr79664.C: Use -Winvalid-constexpr -pedantic-errors.
	* g++.dg/ubsan/vptr-4.C: Likewise.
	* g++.dg/cpp23/constexpr-nonlit10.C: New test.
	* g++.dg/cpp23/constexpr-nonlit11.C: New test.
	* g++.dg/cpp23/constexpr-nonlit12.C: New test.
	* g++.dg/cpp23/constexpr-nonlit13.C: New test.
	* g++.dg/cpp23/constexpr-nonlit14.C: New test.
	* g++.dg/cpp23/constexpr-nonlit15.C: New test.
	* g++.dg/cpp23/constexpr-nonlit16.C: New test.
	* g++.dg/cpp23/constexpr-nonlit8.C: New test.
	* g++.dg/cpp23/constexpr-nonlit9.C: New test.
47 files changed