aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <Thomas.Koenig@online.de>2005-08-24 20:04:20 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2005-08-24 20:04:20 +0000
commitfe58e07668767de1adc8cab509649a485607d127 (patch)
treeee3f72b0e9a25230193623fc852517df5c61a9e2 /gcc
parent1a1e6a9d4a1c8cfb8aef4d7f18fe4c68444f9317 (diff)
downloadgcc-fe58e07668767de1adc8cab509649a485607d127.zip
gcc-fe58e07668767de1adc8cab509649a485607d127.tar.gz
gcc-fe58e07668767de1adc8cab509649a485607d127.tar.bz2
re PR fortran/17758 (gfortran_abort and some others should be marked as noreturn)
2005-08-24 Thomas Koenig <Thomas.Koenig@online.de> 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 <Thomas.Koenig@online.de> PR fortran/17758 gfortran.dg/nonreturning_statements.f90: New test. From-SVN: r103449
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/gfortran.h6
-rw-r--r--gcc/fortran/intrinsic.c13
-rw-r--r--gcc/fortran/trans-decl.c4
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gfortran.dg/nonreturning_statements.f9025
6 files changed, 68 insertions, 1 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7fcd0ed..271bbc4 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2005-08-24 Thomas Koenig <Thomas.Koenig@online.de>
+
+ 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 <kargls@comcast.net>
* decl.c: Typo in comment.
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index c692ce2..8c4303b 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 a304fbd..180e7ae 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 3488cde..aaa4006 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 e787eaa..80b184e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-08-24 Thomas Koenig <Thomas.Koenig@online.de>
+
+ PR fortran/17758
+ gfortran.dg/nonreturning_statements.f90: New test.
+
2005-08-24 Nathan Sidwell <nathan@codesourcery.com>
PR c++/22454
@@ -122,6 +127,10 @@
2005-08-16 Thomas Koenig <Thomas.Koenig@online.de>
+ * gfortran.dg/inquire-complex.f90: Correct mangled testcase.
+
+2005-08-16 Thomas Koenig <Thomas.Koenig@online.de>
+
PR libfortran/23428
* gfortran.dg/inquire-complex.f90: New test case.
diff --git a/gcc/testsuite/gfortran.dg/nonreturning_statements.f90 b/gcc/testsuite/gfortran.dg/nonreturning_statements.f90
new file mode 100644
index 0000000..6268f72
--- /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