mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
gimplify: Fix ICE in collect_fallthrough_labels [PR122773]
In r16-4212 I had to tweak two spots in the gimplifier to ignore gotos jumping to labels with the new VACUOUS_INIT_LABEL_P flag (set by C++ FE when implementing goto/case interceptors with extra .DEFERRED_INIT calls, so that jumps over vacuous initialization are handled properly with the C++26 erroneous behavior requirements). Except as the following testcase shows, the checks blindly assumed that gimple_goto_dest operand is a LABEL_DECL, which is not the case for computed jumps. The following patch checks that gimple_goto_dest argument is a LABEL_DECL before testing VACUOUS_INIT_LABEL_P flag on it. 2025-11-21 Jakub Jelinek <jakub@redhat.com> PR middle-end/122773 * gimplify.cc (collect_fallthrough_labels): Check whether gimple_goto_dest is a LABEL_DECL before testing VACUOUS_INIT_LABEL_P. (expand_FALLTHROUGH_r): Likewise. * gcc.dg/pr122773.c: New test.
This commit is contained in:
committed by
Jakub Jelinek
parent
c435bbdd22
commit
3012aad2dc
@@ -2673,6 +2673,7 @@ collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
|
||||
gsi_next (gsi_p);
|
||||
}
|
||||
|
||||
tree lab;
|
||||
/* Remember the last statement. Skip labels that are of no interest
|
||||
to us. */
|
||||
if (gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_LABEL)
|
||||
@@ -2691,7 +2692,9 @@ collect_fallthrough_labels (gimple_stmt_iterator *gsi_p,
|
||||
;
|
||||
else if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
|
||||
&& gimple_code (gsi_stmt (*gsi_p)) == GIMPLE_GOTO
|
||||
&& VACUOUS_INIT_LABEL_P (gimple_goto_dest (gsi_stmt (*gsi_p))))
|
||||
&& (lab = gimple_goto_dest (gsi_stmt (*gsi_p)))
|
||||
&& TREE_CODE (lab) == LABEL_DECL
|
||||
&& VACUOUS_INIT_LABEL_P (lab))
|
||||
;
|
||||
else if (!is_gimple_debug (gsi_stmt (*gsi_p)))
|
||||
prev = gsi_stmt (*gsi_p);
|
||||
@@ -2928,9 +2931,12 @@ expand_FALLTHROUGH_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
|
||||
|
||||
gimple_stmt_iterator gsi2 = *gsi_p;
|
||||
stmt = gsi_stmt (gsi2);
|
||||
tree lab;
|
||||
if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
|
||||
&& gimple_code (stmt) == GIMPLE_GOTO
|
||||
&& VACUOUS_INIT_LABEL_P (gimple_goto_dest (stmt)))
|
||||
&& (lab = gimple_goto_dest (stmt))
|
||||
&& TREE_CODE (lab) == LABEL_DECL
|
||||
&& VACUOUS_INIT_LABEL_P (lab))
|
||||
{
|
||||
/* Handle for C++ artificial -ftrivial-auto-var-init=
|
||||
sequences. Those look like:
|
||||
|
||||
25
gcc/testsuite/gcc.dg/pr122773.c
Normal file
25
gcc/testsuite/gcc.dg/pr122773.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* PR middle-end/122773 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-Wimplicit-fallthrough -O2 -ftrivial-auto-var-init=zero" } */
|
||||
|
||||
void *l;
|
||||
int
|
||||
foo (int x)
|
||||
{
|
||||
__label__ l1, l2, l3;
|
||||
static void *l[] = { &&l1, &&l2, &&l3 };
|
||||
switch (0)
|
||||
{
|
||||
case 0:
|
||||
while (0)
|
||||
;
|
||||
goto *l[x];
|
||||
}
|
||||
l1:
|
||||
++x;
|
||||
l2:
|
||||
++x;
|
||||
l3:
|
||||
++x;
|
||||
return x;
|
||||
}
|
||||
Reference in New Issue
Block a user