re PR c/44715 (Break in increment expression of "for" statement inconsistent with g++)
PR c/44715 * cp-gimplify.c (genericize_cp_loop): Call begin_bc_block only after genericizing cond and incr expressions. * doc/extend.texi: Document break and continue behavior in statement expressions. * c-c++-common/pr44715.c: New test. From-SVN: r268188
This commit is contained in:
parent
d0f2db2316
commit
372e6e6bac
@ -1,3 +1,9 @@
|
||||
2019-01-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/44715
|
||||
* doc/extend.texi: Document break and continue behavior in
|
||||
statement expressions.
|
||||
|
||||
2019-01-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/89008
|
||||
|
@ -1,5 +1,9 @@
|
||||
2019-01-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/44715
|
||||
* cp-gimplify.c (genericize_cp_loop): Call begin_bc_block only
|
||||
after genericizing cond and incr expressions.
|
||||
|
||||
PR c++/88984
|
||||
* cp-gimplify.c (genericize_switch_stmt): Move cond genericization
|
||||
before the begin_bc_block call.
|
||||
|
@ -242,14 +242,15 @@ genericize_cp_loop (tree *stmt_p, location_t start_locus, tree cond, tree body,
|
||||
tree exit = NULL;
|
||||
tree stmt_list = NULL;
|
||||
|
||||
blab = begin_bc_block (bc_break, start_locus);
|
||||
clab = begin_bc_block (bc_continue, start_locus);
|
||||
|
||||
protected_set_expr_location (incr, start_locus);
|
||||
|
||||
cp_walk_tree (&cond, cp_genericize_r, data, NULL);
|
||||
cp_walk_tree (&body, cp_genericize_r, data, NULL);
|
||||
cp_walk_tree (&incr, cp_genericize_r, data, NULL);
|
||||
|
||||
blab = begin_bc_block (bc_break, start_locus);
|
||||
clab = begin_bc_block (bc_continue, start_locus);
|
||||
|
||||
cp_walk_tree (&body, cp_genericize_r, data, NULL);
|
||||
*walk_subtrees = 0;
|
||||
|
||||
if (cond && TREE_CODE (cond) != INTEGER_CST)
|
||||
|
@ -213,7 +213,14 @@ statement expression is part of a larger expression then it is
|
||||
unspecified which other subexpressions of that expression have been
|
||||
evaluated except where the language definition requires certain
|
||||
subexpressions to be evaluated before or after the statement
|
||||
expression. In any case, as with a function call, the evaluation of a
|
||||
expression. A @code{break} or @code{continue} statement inside of
|
||||
a statement expression used in @code{while}, @code{do} or @code{for}
|
||||
loop or @code{switch} statement condition
|
||||
or @code{for} statement init or increment expressions jumps to an
|
||||
outer loop or @code{switch} statement if any (otherwise it is an error),
|
||||
rather than to the loop or @code{switch} statement in whose condition
|
||||
or init or increment expression it appears.
|
||||
In any case, as with a function call, the evaluation of a
|
||||
statement expression is not interleaved with the evaluation of other
|
||||
parts of the containing expression. For example,
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
2019-01-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c/44715
|
||||
* c-c++-common/pr44715.c: New test.
|
||||
|
||||
PR c++/88984
|
||||
* c-c++-common/pr88984.c: New test.
|
||||
|
||||
|
171
gcc/testsuite/c-c++-common/pr44715.c
Normal file
171
gcc/testsuite/c-c++-common/pr44715.c
Normal file
@ -0,0 +1,171 @@
|
||||
/* PR c/44715 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "" } */
|
||||
|
||||
void
|
||||
foo (int x, int y)
|
||||
{
|
||||
int z;
|
||||
switch (x)
|
||||
{
|
||||
case 0:
|
||||
while (({ if (y) break; 0; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
break;
|
||||
case 1:
|
||||
do
|
||||
;
|
||||
while (({ if (y) break; 0; }));
|
||||
__builtin_abort ();
|
||||
break;
|
||||
case 2:
|
||||
for (z = ({ if (y) break; 0; }); z < 5; z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
break;
|
||||
case 3:
|
||||
for (z = 0; z < ({ if (y) break; 5; }); z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
break;
|
||||
case 4:
|
||||
for (z = 0; z < 5; z += ({ if (y) break; 1; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
break;
|
||||
case 5:
|
||||
switch (({ if (y) break; 1; }))
|
||||
{
|
||||
default: break;
|
||||
}
|
||||
__builtin_abort ();
|
||||
break;
|
||||
default:
|
||||
__builtin_abort ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bar (int x, int y)
|
||||
{
|
||||
int z;
|
||||
while (x >= 0)
|
||||
{
|
||||
if (x == 0)
|
||||
{
|
||||
while (({ if (y) break; 0; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 1)
|
||||
{
|
||||
do
|
||||
;
|
||||
while (({ if (y) break; 0; }));
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 2)
|
||||
{
|
||||
for (z = ({ if (y) break; 0; }); z < 5; z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 3)
|
||||
{
|
||||
for (z = 0; z < ({ if (y) break; 5; }); z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 4)
|
||||
{
|
||||
for (z = 0; z < 5; z += ({ if (y) break; 1; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 5)
|
||||
{
|
||||
switch (({ if (y) break; 1; }))
|
||||
{
|
||||
default: break;
|
||||
}
|
||||
__builtin_abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
baz (int x, int y)
|
||||
{
|
||||
int z;
|
||||
while (x >= 0)
|
||||
{
|
||||
if (++y == 2)
|
||||
return;
|
||||
if (x == 0)
|
||||
{
|
||||
while (({ if (y) continue; 0; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 1)
|
||||
{
|
||||
do
|
||||
;
|
||||
while (({ if (y) continue; 0; }));
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 2)
|
||||
{
|
||||
for (z = ({ if (y) continue; 0; }); z < 5; z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 3)
|
||||
{
|
||||
for (z = 0; z < ({ if (y) continue; 5; }); z++)
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 4)
|
||||
{
|
||||
for (z = 0; z < 5; z += ({ if (y) continue; 1; }))
|
||||
;
|
||||
__builtin_abort ();
|
||||
}
|
||||
if (x == 5)
|
||||
{
|
||||
switch (({ if (y) continue; 1; }))
|
||||
{
|
||||
default: break;
|
||||
}
|
||||
__builtin_abort ();
|
||||
}
|
||||
}
|
||||
__builtin_abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
foo (0, 1);
|
||||
foo (1, 1);
|
||||
foo (2, 1);
|
||||
foo (3, 1);
|
||||
foo (4, 1);
|
||||
foo (5, 1);
|
||||
bar (0, 1);
|
||||
bar (1, 1);
|
||||
bar (2, 1);
|
||||
bar (3, 1);
|
||||
bar (4, 1);
|
||||
bar (5, 1);
|
||||
baz (0, 0);
|
||||
baz (1, 0);
|
||||
baz (2, 0);
|
||||
baz (3, 0);
|
||||
baz (4, 0);
|
||||
baz (5, 0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user