Commit e9fa2f6d by Marek Polacek Committed by Marek Polacek

PR c++/88983 - ICE with switch in constexpr function.

	* constexpr.c (cxx_eval_switch_expr): Use SWITCH_COND and SWITCH_BODY.
	(cxx_eval_constant_expression) <case COND_EXPR>: Don't look for the
	label in the else branch if we found it in the then branch.

	* g++.dg/cpp1y/constexpr-88983.C: New test.

From-SVN: r268438
parent bb9160ae
......@@ -6,6 +6,11 @@
* decl.c (reshape_init_r): Don't reshape a digested initializer.
Return the initializer for COMPOUND_LITERAL_P.
PR c++/88983 - ICE with switch in constexpr function.
* constexpr.c (cxx_eval_switch_expr): Use SWITCH_COND and SWITCH_BODY.
(cxx_eval_constant_expression) <case COND_EXPR>: Don't look for the
label in the else branch if we found it in the then branch.
2019-01-30 Jason Merrill <jason@redhat.com>
PR c++/88752 - ICE with lambda and constexpr if.
......
......@@ -4140,13 +4140,13 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
bool *non_constant_p, bool *overflow_p,
tree *jump_target)
{
tree cond = TREE_OPERAND (t, 0);
tree cond = SWITCH_COND (t);
cond = cxx_eval_constant_expression (ctx, cond, false,
non_constant_p, overflow_p);
VERIFY_CONSTANT (cond);
*jump_target = cond;
tree body = TREE_OPERAND (t, 1);
tree body = SWITCH_BODY (t);
constexpr_ctx new_ctx = *ctx;
constexpr_switch_state css = css_default_not_seen;
new_ctx.css_state = &css;
......@@ -4681,6 +4681,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case COND_EXPR:
if (jump_target && *jump_target)
{
tree orig_jump = *jump_target;
/* When jumping to a label, the label might be either in the
then or else blocks, so process then block first in skipping
mode first, and if we are still in the skipping mode at its end,
......@@ -4688,7 +4689,19 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
lval, non_constant_p, overflow_p,
jump_target);
if (*jump_target)
/* It's possible that we found the label in the then block. But
it could have been followed by another jumping statement, e.g.
say we're looking for case 1:
if (cond)
{
// skipped statements
case 1:; // clears up *jump_target
return 1; // and sets it to a RETURN_EXPR
}
else { ... }
in which case we need not go looking to the else block.
(goto is not allowed in a constexpr function.) */
if (*jump_target == orig_jump)
r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
lval, non_constant_p, overflow_p,
jump_target);
......
2019-01-31 Marek Polacek <polacek@redhat.com>
PR c++/88983 - ICE with switch in constexpr function.
* g++.dg/cpp1y/constexpr-88983.C: New test.
2019-01-31 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/88669
......
// PR c++/88983
// { dg-do compile { target c++14 } }
constexpr int
fn1 (int ay)
{
switch (ay)
{
if (1)
{
case 1:
return 1;
}
else
{
default:;
}
}
return 0;
}
constexpr int
fn2 (int ay)
{
switch (ay)
{
if (1)
{
case 1:
break;
}
else
{
default:;
}
}
return 0;
}
constexpr int
fn3 (int ay)
{
int i = 0;
while (i++ < 100)
{
if (i == 1)
return 1;
switch (ay)
{
if (1)
{
case 1:
continue;
}
else
{
default:;
return -1;
}
}
return -1;
}
return -1;
}
static_assert (fn1 (1) == 1, "");
static_assert (fn2 (1) == 0, "");
static_assert (fn3 (1) == 1, "");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment