From fe58e07668767de1adc8cab509649a485607d127 Mon Sep 17 00:00:00 2001 From: Thomas Koenig Date: Wed, 24 Aug 2005 20:04:20 +0000 Subject: [PATCH] re PR fortran/17758 (gfortran_abort and some others should be marked as noreturn) 2005-08-24 Thomas Koenig PR fortran/17758 * gfortran.h (symbol_attribute): Add noreturn to the structure. (gfc_intrinsic_sym): Add noreturn to the structure. * intrinsic.c (make_noreturn): New function. (add_subroutines): Mark subroutines abort and exit as noreturn. (gfc_intrinsic_sub_interface): Copy noreturn attribute from isym to the resolved symbol. * trans-decl.c (gfc_get_extern_function_decl): Set function as VOLATILE (== noreturn) if the noreturn attribute is set. 2005-08-24 Thomas Koenig PR fortran/17758 gfortran.dg/nonreturning_statements.f90: New test. From-SVN: r103449 --- gcc/fortran/ChangeLog | 12 +++++++++ gcc/fortran/gfortran.h | 6 ++++- gcc/fortran/intrinsic.c | 13 ++++++++++ gcc/fortran/trans-decl.c | 4 +++ gcc/testsuite/ChangeLog | 9 +++++++ .../gfortran.dg/nonreturning_statements.f90 | 25 +++++++++++++++++++ 6 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gfortran.dg/nonreturning_statements.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7fcd0ed700d..271bbc4bb46 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,15 @@ +2005-08-24 Thomas Koenig + + PR fortran/17758 + * gfortran.h (symbol_attribute): Add noreturn to the structure. + (gfc_intrinsic_sym): Add noreturn to the structure. + * intrinsic.c (make_noreturn): New function. + (add_subroutines): Mark subroutines abort and exit as noreturn. + (gfc_intrinsic_sub_interface): Copy noreturn attribute from + isym to the resolved symbol. + * trans-decl.c (gfc_get_extern_function_decl): Set function + as VOLATILE (== noreturn) if the noreturn attribute is set. + 2005-08-21 Steven G. Kargl * decl.c: Typo in comment. diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index c692ce24d37..8c4303b1e15 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -428,6 +428,10 @@ typedef struct unsigned sequence:1, elemental:1, pure:1, recursive:1; unsigned unmaskable:1, masked:1, contained:1; + /* This is set if the subroutine doesn't return. Currently, this + is only possible for intrinsic subroutines. */ + unsigned noreturn:1; + /* Set if this procedure is an alternate entry point. These procedures don't have any code associated, and the backend will turn them into thunks to the master function. */ @@ -1032,7 +1036,7 @@ typedef struct gfc_intrinsic_sym const char *name, *lib_name; gfc_intrinsic_arg *formal; gfc_typespec ts; - int elemental, pure, generic, specific, actual_ok, standard; + int elemental, pure, generic, specific, actual_ok, standard, noreturn; gfc_simplify_f simplify; gfc_check_f check; diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index a304fbd667c..180e7ae36f6 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -843,6 +843,14 @@ make_alias (const char *name, int standard) } } +/* Make the current subroutine noreturn. */ + +static void +make_noreturn(void) +{ + if (sizing == SZ_NOTHING) + next_sym[-1].noreturn = 1; +} /* Add intrinsic functions. */ @@ -2108,6 +2116,8 @@ add_subroutines (void) add_sym_0s ("abort", 1, GFC_STD_GNU, NULL); + make_noreturn(); + add_sym_1s ("cpu_time", 0, 1, BT_UNKNOWN, 0, GFC_STD_F95, gfc_check_cpu_time, NULL, gfc_resolve_cpu_time, tm, BT_REAL, dr, REQUIRED); @@ -2199,6 +2209,8 @@ add_subroutines (void) gfc_check_exit, NULL, gfc_resolve_exit, c, BT_INTEGER, di, OPTIONAL); + make_noreturn(); + add_sym_1s ("flush", 0, 1, BT_UNKNOWN, 0, GFC_STD_GNU, gfc_check_flush, NULL, gfc_resolve_flush, c, BT_INTEGER, di, OPTIONAL); @@ -3161,6 +3173,7 @@ gfc_intrinsic_sub_interface (gfc_code * c, int error_flag) return MATCH_ERROR; } + c->resolved_sym->attr.noreturn = isym->noreturn; check_intrinsic_standard (name, isym->standard, &c->loc); return MATCH_YES; diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 3488cde9096..aaa4006da63 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1001,6 +1001,10 @@ gfc_get_extern_function_decl (gfc_symbol * sym) TREE_SIDE_EFFECTS (fndecl) = 0; } + /* Mark non-returning functions. */ + if (sym->attr.noreturn) + TREE_THIS_VOLATILE(fndecl) = 1; + sym->backend_decl = fndecl; if (DECL_CONTEXT (fndecl) == NULL_TREE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e787eaa4c1c..80b184e8026 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-08-24 Thomas Koenig + + PR fortran/17758 + gfortran.dg/nonreturning_statements.f90: New test. + 2005-08-24 Nathan Sidwell PR c++/22454 @@ -120,6 +125,10 @@ PR c++/23337 * g++.dg/ext/vector2.C: New. +2005-08-16 Thomas Koenig + + * gfortran.dg/inquire-complex.f90: Correct mangled testcase. + 2005-08-16 Thomas Koenig PR libfortran/23428 diff --git a/gcc/testsuite/gfortran.dg/nonreturning_statements.f90 b/gcc/testsuite/gfortran.dg/nonreturning_statements.f90 new file mode 100644 index 00000000000..6268f72291c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/nonreturning_statements.f90 @@ -0,0 +1,25 @@ +! { dg-final { scan-assembler-not "should_be_noreturn" } } +! PR 17758 +! This checks that non-returning subroutines and statements +! really don't return by calling non-existing subroutines +! afterwards. These calls are supposed to be optimized away, so +! they won't show up in the generated assembly. +program main + character(len=5) :: c + c = '12345' + read(unit=c,fmt='(A)') i + select case(i) + case(1) + call abort + call abort_should_be_noreturn + case(2) + stop 65 + call stop_numeric_should_be_noreturn + case(3) + stop "foobar" + call stop_string_should_be_noreturn + case(4) + call exit + call exit_should_be_noreturn + end select +end program main -- 2.30.2