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
This commit is contained in:
parent
bb9160aeb0
commit
e9fa2f6ded
@ -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);
|
||||
|
@ -1,3 +1,8 @@
|
||||
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
|
||||
|
71
gcc/testsuite/g++.dg/cpp1y/constexpr-88983.C
Normal file
71
gcc/testsuite/g++.dg/cpp1y/constexpr-88983.C
Normal file
@ -0,0 +1,71 @@
|
||||
// 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, "");
|
Loading…
Reference in New Issue
Block a user