Skip to content

Commit 647537a

Browse files
author
Patrick Palka
committed
c++: missing SFINAE for non-constant consteval calls [PR104620]
Here we weren't respecting SFINAE when evaluating a call to a consteval function, which caused us to reject the new testcase below. This patch fixes this by making build_over_call use the SFINAE-friendly version of cxx_constant_value. This change causes us to no longer diagnose ahead of time a couple of non-constant non-dependent consteval calls in consteval-if2.C with -fchecking=2. These errors were apparently coming from the call to fold_non_dependent_expr in build_non_dependent_expr (for the RHS of the +=) despite complain=tf_none being passed. Now that build_over_call respects the value of complain during constant evaluation of a consteval call, the errors are gone. That the errors are also gone without -fchecking=2 is a regression caused by r12-7264-gc19f317a78c0e4 and is the subject of PR104620. As described in comment #5, I think it's basically an accident that we were diagnosing these two calls correctly before r12-7264, so perhaps we can live without these errors for GCC 12. Thus this patch just XFAILs the two tests. PR c++/104620 gcc/cp/ChangeLog: * call.cc (build_over_call): Use cxx_constant_value_sfinae instead of cxx_constant_value to evaluate a consteval call. * constexpr.cc (cxx_constant_value_sfinae): Add decl parameter and pass it to cxx_eval_outermost_constant_expr. * cp-tree.h (cxx_constant_value_sfinae): Add decl parameter. * pt.cc (fold_targs_r): Pass NULL_TREE as decl parameter to cxx_constant_value_sfinae. gcc/testsuite/ChangeLog: * g++.dg/cpp23/consteval-if2.C: XFAIL two dg-error tests where the argument to the non-constant non-dependent consteval call is wrapped by NON_DEPENDENT_EXPR. * g++.dg/cpp2a/consteval30.C: New test.
1 parent fb488cb commit 647537a

File tree

6 files changed

+19
-7
lines changed

6 files changed

+19
-7
lines changed

gcc/cp/call.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -9939,7 +9939,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
99399939
obj_arg = TREE_OPERAND (addr, 0);
99409940
}
99419941
}
9942-
call = cxx_constant_value (call, obj_arg);
9942+
call = cxx_constant_value_sfinae (call, obj_arg, complain);
99439943
if (obj_arg && !error_operand_p (call))
99449944
call = build2 (INIT_EXPR, void_type_node, obj_arg, call);
99459945
call = convert_from_reference (call);

gcc/cp/constexpr.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -7960,10 +7960,10 @@ cxx_constant_value (tree t, tree decl)
79607960
/* As above, but respect SFINAE. */
79617961

79627962
tree
7963-
cxx_constant_value_sfinae (tree t, tsubst_flags_t complain)
7963+
cxx_constant_value_sfinae (tree t, tree decl, tsubst_flags_t complain)
79647964
{
79657965
bool sfinae = !(complain & tf_error);
7966-
tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true);
7966+
tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, true, false, decl);
79677967
if (sfinae && !TREE_CONSTANT (r))
79687968
r = error_mark_node;
79697969
return r;

gcc/cp/cp-tree.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -8414,7 +8414,7 @@ extern bool require_constant_expression (tree);
84148414
extern bool require_rvalue_constant_expression (tree);
84158415
extern bool require_potential_rvalue_constant_expression (tree);
84168416
extern tree cxx_constant_value (tree, tree = NULL_TREE);
8417-
extern tree cxx_constant_value_sfinae (tree, tsubst_flags_t);
8417+
extern tree cxx_constant_value_sfinae (tree, tree, tsubst_flags_t);
84188418
extern void cxx_constant_dtor (tree, tree);
84198419
extern tree cxx_constant_init (tree, tree = NULL_TREE);
84208420
extern tree maybe_constant_value (tree, tree = NULL_TREE, bool = false);

gcc/cp/pt.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -19811,7 +19811,7 @@ fold_targs_r (tree targs, tsubst_flags_t complain)
1981119811
&& !glvalue_p (elt)
1981219812
&& !TREE_CONSTANT (elt))
1981319813
{
19814-
elt = cxx_constant_value_sfinae (elt, complain);
19814+
elt = cxx_constant_value_sfinae (elt, NULL_TREE, complain);
1981519815
if (elt == error_mark_node)
1981619816
return false;
1981719817
}

gcc/testsuite/g++.dg/cpp23/consteval-if2.C

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ qux (int x)
7777
}
7878
else
7979
{
80-
r += foo (8 * x); // { dg-error "is not a constant expression" }
80+
r += foo (8 * x); // { dg-error "is not a constant expression" "" { xfail *-*-* } }
8181
}
8282
if ! consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } }
8383
{
84-
r += foo (32 * x);// { dg-error "is not a constant expression" }
84+
r += foo (32 * x);// { dg-error "is not a constant expression" "" { xfail *-*-* } }
8585
}
8686
if consteval // { dg-warning "'if consteval' only available with" "" { target c++20_only } }
8787
{
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Test SFINAE for a non-constant consteval call.
2+
// { dg-do compile { target c++20 } }
3+
4+
consteval int deref(const int* x) { return *x; }
5+
6+
template<const int* P, int = deref(P)> // { dg-bogus "null pointer" }
7+
constexpr int f(int) { return 0; }
8+
9+
template<const int* P>
10+
constexpr int f(...) { return 1; }
11+
12+
static_assert(f<nullptr>(0) == 1);

0 commit comments

Comments
 (0)