aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2005-08-05 16:01:54 -0700
committerRichard Henderson <rth@gcc.gnu.org>2005-08-05 16:01:54 -0700
commitbb1ecfe8a92497f7040e522ffbf0572b00b92492 (patch)
treead686c8439d31d25ef09c4a852f5a872604eaa5e
parent0e44ef6254bfa00961521b596e0d3ea703119ec0 (diff)
downloadgcc-bb1ecfe8a92497f7040e522ffbf0572b00b92492.zip
gcc-bb1ecfe8a92497f7040e522ffbf0572b00b92492.tar.gz
gcc-bb1ecfe8a92497f7040e522ffbf0572b00b92492.tar.bz2
re PR middle-end/21728 (Nonlocal goto from an unused nested function)
PR 21728 * tree-cfg.c (remove_bb): Transmute DECL_NONLOCAL labels into FORCED_LABEL labels. From-SVN: r102786
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr21728.c10
-rw-r--r--gcc/tree-cfg.c18
3 files changed, 31 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 95076b9..3a9b189 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-05 Richard Henderson <rth@redhat.com>
+
+ PR 21728
+ * tree-cfg.c (remove_bb): Transmute DECL_NONLOCAL labels into
+ FORCED_LABEL labels.
+
2005-08-05 J"orn Rennecke <joern.rennecke@st.com>
PR middle-end/23135
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr21728.c b/gcc/testsuite/gcc.c-torture/compile/pr21728.c
new file mode 100644
index 0000000..991cb38
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr21728.c
@@ -0,0 +1,10 @@
+int main (void)
+{
+ __label__ l1;
+ void __attribute__((used)) q(void)
+ {
+ goto l1;
+ }
+
+ l1:;
+}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index b5a0696..70dca21 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -1983,11 +1983,23 @@ remove_bb (basic_block bb)
{
tree stmt = bsi_stmt (i);
if (TREE_CODE (stmt) == LABEL_EXPR
- && FORCED_LABEL (LABEL_EXPR_LABEL (stmt)))
+ && (FORCED_LABEL (LABEL_EXPR_LABEL (stmt))
+ || DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt))))
{
- basic_block new_bb = bb->prev_bb;
- block_stmt_iterator new_bsi = bsi_start (new_bb);
+ basic_block new_bb;
+ block_stmt_iterator new_bsi;
+
+ /* A non-reachable non-local label may still be referenced.
+ But it no longer needs to carry the extra semantics of
+ non-locality. */
+ if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
+ {
+ DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)) = 0;
+ FORCED_LABEL (LABEL_EXPR_LABEL (stmt)) = 1;
+ }
+ new_bb = bb->prev_bb;
+ new_bsi = bsi_start (new_bb);
bsi_remove (&i);
bsi_insert_before (&new_bsi, stmt, BSI_NEW_STMT);
}