The gimplification of LOOP_STMT has a systematic end label definition,
that may be unused. For example, an endless loop maybe gimplified to:
<D.5765>:
# USE = anything
# CLB = anything
totoD.5747 ();
goto <D.5765>;
<D.5749>:
Later, the gimple_seq_may_fallthru() will decide that this block can
fallthru as the last statement is a single label that may be jumped to
from somewhere else.
Only defining this label if we also emit jumps to it helps the compiler
correctly decide if the block can fallthru or not.
In particular, if a function, with a local object needing finalization
and the No_Return aspect, is an endless loop then the spurious warning
that the function is still returning is not emitted anymore.
gcc/ada/ChangeLog:
* gcc-interface/trans.cc (gnat_to_gnu) <N_Exit_Statement>: Mark
the label tree as used.
(gnat_gimplify_stmt) <LOOP_STMT>: Do not emit end label
definition in unused.
Tested on x86_64-pc-linux-gnu, committed on master.
---
gcc/ada/gcc-interface/trans.cc | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
@@ -7993,13 +7993,17 @@ gnat_to_gnu (Node_Id gnat_node)
break;
case N_Exit_Statement:
- gnu_result
- = build2 (EXIT_STMT, void_type_node,
- (Present (Condition (gnat_node))
- ? gnat_to_gnu (Condition (gnat_node)) : NULL_TREE),
- (Present (Name (gnat_node))
- ? get_gnu_tree (Entity (Name (gnat_node)))
- : LOOP_STMT_LABEL (gnu_loop_stack->last ()->stmt)));
+ {
+ tree end_loop_label = Present (Name (gnat_node))
+ ? get_gnu_tree (Entity (Name (gnat_node)))
+ : LOOP_STMT_LABEL (gnu_loop_stack->last ()->stmt);
+ gnu_result
+ = build2 (EXIT_STMT, void_type_node,
+ (Present (Condition (gnat_node))
+ ? gnat_to_gnu (Condition (gnat_node)) : NULL_TREE),
+ end_loop_label);
+ TREE_USED (end_loop_label) = 1;
+ }
break;
case N_Simple_Return_Statement:
@@ -9532,6 +9536,8 @@ gnat_gimplify_stmt (tree *stmt_p)
gnu_cond
= build3 (COND_EXPR, void_type_node, gnu_cond, NULL_TREE,
build1 (GOTO_EXPR, void_type_node, gnu_end_label));
+
+ TREE_USED (gnu_end_label) = 1;
}
/* Set to emit the statements of the loop. */
@@ -9541,8 +9547,9 @@ gnat_gimplify_stmt (tree *stmt_p)
end label if there's a top condition, then the update if it's at
the top, then the body of the loop, then a conditional jump to
the end label if there's a bottom condition, then the update if
- it's at the bottom, and finally a jump to the start label and the
- definition of the end label. */
+ it's at the bottom, and finally a jump to the start label and if
+ there's a top or bottom condition, the definition of the end
+ label. */
append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
gnu_start_label),
stmt_p);
@@ -9565,9 +9572,10 @@ gnat_gimplify_stmt (tree *stmt_p)
SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (gnu_end_label));
append_to_statement_list (t, stmt_p);
- append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
- gnu_end_label),
- stmt_p);
+ if (TREE_USED (gnu_end_label))
+ append_to_statement_list (build1 (LABEL_EXPR, void_type_node,
+ gnu_end_label),
+ stmt_p);
return GS_OK;
}