On 10/29/18 2:07 PM, Marek Polacek wrote:
On Wed, Oct 24, 2018 at 05:16:33PM -0400, Jason Merrill wrote:
On 10/11/18 8:56 PM, Marek Polacek wrote:
Here potential_constant_expression_1 rejects the testcase because the body of
the for loop calls a non-constexpr function. But the range is empty so the
function would never get called.
The trick with evaluating the for-condition doesn't work here, because we're
dealing with a converted range-based for and can't evaluate
__for_begin != __for_end
because the constexpr cache doesn't have the values of these two VAR_DECLs.
So either we can use this ugly hack (more specialized), or just not check the
body of the loop (more general), similarly to what we do (don't do) with
switch.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2018-10-11 Marek Polacek <pola...@redhat.com>
PR c++/87594 - constexpr rejects-valid with range-based for.
* constexpr.c (potential_constant_expression_1) <case FOR_STMT>: Return
true for a converted ange-based for-statement.
* g++.dg/cpp1y/constexpr-loop8.C: New test.
diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 4fa8c965a9d..685ca743859 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -5827,6 +5827,17 @@ potential_constant_expression_1 (tree t, bool want_rval,
bool strict, bool now,
tmp = cxx_eval_outermost_constant_expr (tmp, true);
if (integer_zerop (tmp))
return true;
+ /* See if this is
+ __for_begin != __for_end
+ cp_convert_range_for created for us. If so, this is a converted
+ range-based for-statement, and we're not able to evaluate this
+ condition, so we might end up skipping the body entirely. */
+ else if (TREE_CODE (tmp) == NE_EXPR
+ && VAR_P (TREE_OPERAND (tmp, 0))
+ && DECL_NAME (TREE_OPERAND (tmp, 0)) == for_begin_identifier
+ && VAR_P (TREE_OPERAND (tmp, 1))
+ && DECL_NAME (TREE_OPERAND (tmp, 1)) == for_end_identifier)
+ return true;
This seems over-specific; any other condition we can't immediately evaluate
also might not ever be true. So I think we want to return here unless the
condition is always true. Likewise for WHILE_STMT.
Yeah, that makes a lot of sense. Thus:
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2018-10-29 Marek Polacek <pola...@redhat.com>
PR c++/87594 - constexpr rejects-valid with range-based for.
* constexpr.c (potential_constant_expression_1): If the condition
can't be evaluated, return true.
OK.
Jason