aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2023-08-30 14:18:56 +0200
committerMikael Morin <mikael@gcc.gnu.org>2023-08-30 14:20:05 +0200
commitd58150452976c4ca65ddc811fac78ef956fa96b0 (patch)
tree416ad179572be1fe7560d2625dbf2428c031fdb9 /gcc/testsuite
parentcaa7a99a052929d5970677c5b639e1fa5166e334 (diff)
downloadgcc-d58150452976c4ca65ddc811fac78ef956fa96b0.zip
gcc-d58150452976c4ca65ddc811fac78ef956fa96b0.tar.gz
gcc-d58150452976c4ca65ddc811fac78ef956fa96b0.tar.bz2
fortran: Restore interface to its previous state on error [PR48776]
Keep memory of the content of the current interface body being parsed and restore it to its previous state if it has been modified at the time a parse attempt fails. This fixes memory errors and random segmentation faults caused by dangling symbol pointers kept in interfaces' linked lists of symbols. If a parsing attempt fails and symbols are freed, they should also be removed from the current interface linked list. As the list of symbol is a linked list, and parsing only adds new symbols to the head of the list, all that is needed to track the previous content of the list is a pointer to its previous head. This adds such a pointer, and the restoration of the list of symbols to that pointer on error. PR fortran/48776 gcc/fortran/ChangeLog: * gfortran.h (gfc_drop_interface_elements_before): New prototype. (gfc_current_interface_head): Return a reference to the pointer. * interface.cc (gfc_current_interface_head): Ditto. (free_interface_elements_until): New function, generalizing gfc_free_interface. (gfc_free_interface): Use free_interface_elements_until. (gfc_drop_interface_elements_before): New function. * parse.cc (current_interface_ptr, previous_interface_head): New static variables. (current_interface_valid_p, get_current_interface_ptr): New functions. (decode_statement): Initialize previous_interface_head. (reject_statement): Restore current interface pointer to point to previous_interface_head. gcc/testsuite/ChangeLog: * gfortran.dg/interface_procedure_1.f90: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/gfortran.dg/interface_procedure_1.f9023
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/testsuite/gfortran.dg/interface_procedure_1.f90 b/gcc/testsuite/gfortran.dg/interface_procedure_1.f90
new file mode 100644
index 0000000..6a58b6a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_procedure_1.f90
@@ -0,0 +1,23 @@
+! { dg-do compile }
+! { dg-additional-options "-std=f95" }
+!
+! PR fortran/48776
+! The following used to generate a segmentation fault in the front-end,
+! because a pointer to the get1 symbol was remaining in the get interface
+! after the procedure statement was rejected and the symbol freed.
+
+ interface get
+ procedure get1 ! { dg-error "Fortran 2003: PROCEDURE statement" }
+ end interface
+
+ integer :: h
+ call set1 (get (h)) ! { dg-error "no specific function for the generic 'get'" }
+contains
+ subroutine set1 (a)
+ integer, intent(in) :: a
+ end subroutine
+
+ integer function get1 (s)
+ integer :: s
+ end function
+end