[pushed] c++: don't do constexpr folding in unevaluated context
Commit Message
The implicit constexpr patch revealed that we were doing constant evaluation
of arbitrary expressions in unevaluated contexts, leading to failure when we
tried to evaluate e.g. a call to declval. This is wrong more generally;
only manifestly-constant-evaluated expressions should be evaluated within
an unevaluated operand.
Making this change revealed a case we were failing to mark as manifestly
constant-evaluated.
Tested x86_64-pc-linux-gnu, applying to trunk.
gcc/cp/ChangeLog:
* constexpr.c (maybe_constant_value): Don't evaluate
in an unevaluated operand unless manifestly const-evaluated.
(fold_non_dependent_expr_template): Likewise.
* decl.c (compute_array_index_type_loc): This context is
manifestly constant-evaluated.
---
gcc/cp/constexpr.c | 7 +++++++
gcc/cp/decl.c | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
base-commit: 267318a2857a42922c3ca033dac4690172b17683
@@ -7696,6 +7696,10 @@ maybe_constant_value (tree t, tree decl, bool manifestly_const_eval)
return r;
}
+ /* Don't evaluate an unevaluated operand. */
+ if (cp_unevaluated_operand)
+ return t;
+
uid_sensitive_constexpr_evaluation_checker c;
r = cxx_eval_outermost_constant_expr (t, true, true, false, false, decl);
gcc_checking_assert (r == t
@@ -7759,6 +7763,9 @@ fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
return t;
}
+ if (cp_unevaluated_operand && !manifestly_const_eval)
+ return t;
+
tree r = cxx_eval_outermost_constant_expr (t, true, true,
manifestly_const_eval,
false, object);
@@ -11000,7 +11000,7 @@ compute_array_index_type_loc (location_t name_loc, tree name, tree size,
cp_convert (ssizetype, integer_one_node,
complain),
complain);
- itype = maybe_constant_value (itype);
+ itype = maybe_constant_value (itype, NULL_TREE, true);
}
if (!TREE_CONSTANT (itype))