From 8a6b4ec1c1efbeac4a710044a5885aa88b378c21 Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Sun, 27 Jun 2010 08:47:23 +0000 Subject: [PATCH] * gcc-interface/trans.c: Include tree-flow.h. (gnu_switch_label_stack): Delete. (Case_Statement_to_gnu): Do not emit the goto at the end of a case if its associated block cannot fall through. Do not emit the final label if no cases branche to it. * gcc-interface/Make-lang.in (ada/trans.o): Add $(TREE_FLOW_H). git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161461 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ada/ChangeLog | 9 +++++++++ gcc/ada/gcc-interface/Make-lang.in | 2 +- gcc/ada/gcc-interface/trans.c | 29 +++++++++++++++-------------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gnat.dg/noreturn3.adb | 27 +++++++++++++++++++++++++++ gcc/testsuite/gnat.dg/noreturn3.ads | 12 ++++++++++++ 6 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/noreturn3.adb create mode 100644 gcc/testsuite/gnat.dg/noreturn3.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 56f0a06a50f..021a07a93b5 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,12 @@ +2010-06-27 Eric Botcazou + + * gcc-interface/trans.c: Include tree-flow.h. + (gnu_switch_label_stack): Delete. + (Case_Statement_to_gnu): Do not emit the goto at the end of a case if + its associated block cannot fall through. Do not emit the final label + if no cases branche to it. + * gcc-interface/Make-lang.in (ada/trans.o): Add $(TREE_FLOW_H). + 2010-06-23 Thomas Quinot * exp_attr.adb (Expand_Access_To_Protected_Op): When rewriting a diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 9bf7a47453f..d4f37fe5374 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -1260,7 +1260,7 @@ ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \ $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@ ada/trans.o : ada/gcc-interface/trans.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h \ + $(TM_H) $(TREE_H) $(FLAGS_H) output.h tree-iterator.h $(TREE_FLOW_H) \ $(GIMPLE_H) ada/gcc-interface/ada.h ada/adadecode.h ada/types.h \ ada/atree.h ada/elists.h ada/namet.h ada/nlists.h ada/snames.h \ ada/stringt.h ada/uintp.h ada/urealp.h ada/fe.h ada/sinfo.h ada/einfo.h \ diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index aec94b03c4c..b79b4f0bc5d 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -33,6 +33,7 @@ #include "output.h" #include "libfuncs.h" /* For set_stack_check_libfunc. */ #include "tree-iterator.h" +#include "tree-flow.h" #include "gimple.h" #include "ada.h" @@ -168,9 +169,6 @@ static GTY(()) VEC(tree,gc) *gnu_return_label_stack; /* Stack of LOOP_STMT nodes. */ static GTY(()) VEC(tree,gc) *gnu_loop_label_stack; -/* Stack of labels for switch statements. */ -static GTY(()) VEC(tree,gc) *gnu_switch_label_stack; - /* The stacks for N_{Push,Pop}_*_Label. */ static GTY(()) VEC(tree,gc) *gnu_constraint_error_label_stack; static GTY(()) VEC(tree,gc) *gnu_storage_error_label_stack; @@ -1908,9 +1906,9 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute) static tree Case_Statement_to_gnu (Node_Id gnat_node) { - tree gnu_result; - tree gnu_expr; + tree gnu_result, gnu_expr, gnu_label; Node_Id gnat_when; + bool may_fallthru = false; gnu_expr = gnat_to_gnu (Expression (gnat_node)); gnu_expr = convert (get_base_type (TREE_TYPE (gnu_expr)), gnu_expr); @@ -1933,8 +1931,7 @@ Case_Statement_to_gnu (Node_Id gnat_node) /* We build a SWITCH_EXPR that contains the code with interspersed CASE_LABEL_EXPRs for each label. */ - VEC_safe_push (tree, gc, gnu_switch_label_stack, - create_artificial_label (input_location)); + gnu_label = create_artificial_label (input_location); start_stmt_group (); for (gnat_when = First_Non_Pragma (Alternatives (gnat_node)); @@ -2014,18 +2011,22 @@ Case_Statement_to_gnu (Node_Id gnat_node) containing the Case statement. */ if (choices_added_p) { - add_stmt (build_stmt_group (Statements (gnat_when), true)); - add_stmt (build1 (GOTO_EXPR, void_type_node, - VEC_last (tree, gnu_switch_label_stack))); + tree group = build_stmt_group (Statements (gnat_when), true); + bool group_may_fallthru = block_may_fallthru (group); + add_stmt (group); + if (group_may_fallthru) + { + add_stmt (build1 (GOTO_EXPR, void_type_node, gnu_label)); + may_fallthru = true; + } } } - /* Now emit a definition of the label all the cases branched to. */ - add_stmt (build1 (LABEL_EXPR, void_type_node, - VEC_last (tree, gnu_switch_label_stack))); + /* Now emit a definition of the label the cases branche to, if any. */ + if (may_fallthru) + add_stmt (build1 (LABEL_EXPR, void_type_node, gnu_label)); gnu_result = build3 (SWITCH_EXPR, TREE_TYPE (gnu_expr), gnu_expr, end_stmt_group (), NULL_TREE); - VEC_pop (tree, gnu_switch_label_stack); return gnu_result; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ea6169e486c..04fad302e9b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-06-27 Eric Botcazou + + * gnat.dg/noreturn3.ad[sb]: New test. + 2010-06-26 Jason Merrill * g++.dg/cpp0x/explicit5.C: New. diff --git a/gcc/testsuite/gnat.dg/noreturn3.adb b/gcc/testsuite/gnat.dg/noreturn3.adb new file mode 100644 index 00000000000..4457373c308 --- /dev/null +++ b/gcc/testsuite/gnat.dg/noreturn3.adb @@ -0,0 +1,27 @@ +-- { dg-do compile } + +with Ada.Exceptions; + +package body Noreturn3 is + + procedure Raise_Error (E : Enum; ErrorMessage : String) is + + function Msg return String is + begin + return "Error :" & ErrorMessage; + end; + + begin + case E is + when One => + Ada.Exceptions.Raise_Exception (Exc1'Identity, Msg); + + when Two => + Ada.Exceptions.Raise_Exception (Exc2'Identity, Msg); + + when others => + Ada.Exceptions.Raise_Exception (Exc3'Identity, Msg); + end case; + end; + +end Noreturn3; diff --git a/gcc/testsuite/gnat.dg/noreturn3.ads b/gcc/testsuite/gnat.dg/noreturn3.ads new file mode 100644 index 00000000000..d830a14910e --- /dev/null +++ b/gcc/testsuite/gnat.dg/noreturn3.ads @@ -0,0 +1,12 @@ +package Noreturn3 is + + Exc1 : Exception; + Exc2 : Exception; + Exc3 : Exception; + + type Enum is (One, Two, Three); + + procedure Raise_Error (E : Enum; ErrorMessage : String); + pragma No_Return (Raise_Error); + +end Noreturn3; -- 2.11.0