Commit 58ccbd1c by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/83553 (compiler removes body of the for-loop, although there is a case label inside)

	PR c++/83553
	* fold-const.c (struct contains_label_data): New type.
	(contains_label_1): Return non-NULL even for CASE_LABEL_EXPR, unless
	inside of a SWITCH_BODY seen during the walk.
	(contains_label_p): Use walk_tree instead of
	walk_tree_without_duplicates, prepare data for contains_label_1 and
	provide own pset.

	* c-c++-common/torture/pr83553.c: New test.

From-SVN: r255987
parent 3911519e
2017-12-23 Jakub Jelinek <jakub@redhat.com>
PR c++/83553
* fold-const.c (struct contains_label_data): New type.
(contains_label_1): Return non-NULL even for CASE_LABEL_EXPR, unless
inside of a SWITCH_BODY seen during the walk.
(contains_label_p): Use walk_tree instead of
walk_tree_without_duplicates, prepare data for contains_label_1 and
provide own pset.
2017-12-22 Jakub Jelinek <jakub@redhat.com>
PR debug/83547
......@@ -11218,22 +11218,48 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
} /* switch (code) */
}
/* Used by contains_label_[p1]. */
struct contains_label_data
{
hash_set<tree> *pset;
bool inside_switch_p;
};
/* Callback for walk_tree, looking for LABEL_EXPR. Return *TP if it is
a LABEL_EXPR; otherwise return NULL_TREE. Do not check the subtrees
of GOTO_EXPR. */
a LABEL_EXPR or CASE_LABEL_EXPR not inside of another SWITCH_EXPR; otherwise
return NULL_TREE. Do not check the subtrees of GOTO_EXPR. */
static tree
contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
contains_label_1 (tree *tp, int *walk_subtrees, void *data)
{
contains_label_data *d = (contains_label_data *) data;
switch (TREE_CODE (*tp))
{
case LABEL_EXPR:
return *tp;
case CASE_LABEL_EXPR:
if (!d->inside_switch_p)
return *tp;
return NULL_TREE;
case SWITCH_EXPR:
if (!d->inside_switch_p)
{
if (walk_tree (&SWITCH_COND (*tp), contains_label_1, data, d->pset))
return *tp;
d->inside_switch_p = true;
if (walk_tree (&SWITCH_BODY (*tp), contains_label_1, data, d->pset))
return *tp;
d->inside_switch_p = false;
*walk_subtrees = 0;
}
return NULL_TREE;
case GOTO_EXPR:
*walk_subtrees = 0;
/* fall through */
return NULL_TREE;
default:
return NULL_TREE;
......@@ -11246,8 +11272,9 @@ contains_label_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
static bool
contains_label_p (tree st)
{
return
(walk_tree_without_duplicates (&st, contains_label_1 , NULL) != NULL_TREE);
hash_set<tree> pset;
contains_label_data data = { &pset, false };
return walk_tree (&st, contains_label_1, &data, &pset) != NULL_TREE;
}
/* Fold a ternary expression of code CODE and type TYPE with operands
......
2017-12-23 Jakub Jelinek <jakub@redhat.com>
PR c++/83553
* c-c++-common/torture/pr83553.c: New test.
2017-12-22 Jakub Jelinek <jakub@redhat.com>
PR debug/83550
......
/* PR c++/83553 */
/* { dg-do run } */
int a[3];
int
foo (int n)
{
switch (n)
{
case 0:
for (n = 7, a[0]++; 0; a[2] = a[1] + 1)
{
case 2:
a[1] = a[0] + 1;
}
}
return n;
}
int
main ()
{
if (foo (0) != 7 || a[0] != 1 || a[1] || a[2])
__builtin_abort ();
if (foo (2) != 2 || a[0] != 1 || a[1] != 2 || a[2] != 3)
__builtin_abort ();
return 0;
}
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