Re: [Patch, fortran] PR126909 - Lost statement label in a program with a CONTAINS section
Paul Richard Thomas <[email protected]>
| Newsgroups | gmane.comp.gcc.patches,gmane.comp.gcc.fortran |
|---|---|
| Message-ID | <CAGkQGi+x9msakhZi-TXKsL0WcsvN4QNeYGQT-OfKSchpDW-EMw@mail.gmail.com> |
Hi Steve, Thanks for the review. The attached is a very much cleaner resubmission, which handles statement labels at the end of subroutines and functions that have contained blocks. It regression tests cleanly. OK for mainline? I am not sure that your second example is standard defying. Surely the normal rules of host association apply to labels in the same way as entities? FYI, ifx and flang do not catch it. Cheers Paul On Thu, 20 Aug 2026 at 17:24, Steve Kargl <[email protected]> wrote: > > On 8/20/26 03:12, Paul Richard Thomas wrote: > > Please find attached a rather trivial fix for this PR. > > > > The patch passes regression testing on FC44/x86_64. OK for mainline? > > > > Paul > > Paul, > > Thanks for the patch, but I fear it's a bit more > complicated. The patch only treats a labeled > 'end program' statement, but I think it needs to > deal with additional 'branch target statements' > (F2018, 3.18). That is, it needs to also consider > things like > > subroutine lost() > call sub() > goto 11 > contains > subroutine sub() > goto 10 > 10 return > end subroutine sub > 11 end subroutine lost > > and, it needs to catch invalid labels such as > > F2018, 6.2.5 Statement labels > ... > The same statement label shall not be given to more than > one statement in its scope. > > subroutine lost() > call sub() > goto 10 > contains > subroutine sub() > goto 10 > 10 return > end subroutine sub > 10 end subroutine lost > > -- > steve > >
resubmit.patch
(text/x-patch, 4.2 KB)
From 3606368c76db6fe2a44376cee2d1aa40e80c529c Mon Sep 17 00:00:00 2001 From: Paul Thomas <[email protected]> Date: Sat, 22 Aug 2026 09:37:05 +0100 Subject: [PATCH] Fortran: Lost statement label in a program with a CONTAINS section [PR126909] 2026-08-22 Paul Thomas <[email protected]> gcc/fortran PR fortran/126909 * parse.cc (accept_statement): After a contains section, a new namespace is started and, without correction, the new statement the label, if there is one, would be stored there.Go back to the containing namespace and store it there. Likewise add the labelled return statement to the previous entry on the state stack. gcc/testsuite PR fortran/126909 * gfortran.dg/pr126909.f90: New test. --- gcc/fortran/parse.cc | 28 +++++++++- gcc/testsuite/gfortran.dg/pr126909.f90 | 77 ++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr126909.f90 diff --git a/gcc/fortran/parse.cc b/gcc/fortran/parse.cc index 47b443c4a5f..311dfedabce 100644 --- a/gcc/fortran/parse.cc +++ b/gcc/fortran/parse.cc @@ -3253,8 +3253,32 @@ accept_statement (gfc_statement st) case ST_END_SUBROUTINE: if (gfc_statement_label != NULL) { - new_st.op = EXEC_RETURN; - add_statement (); + /* After a contains section, a new namespace is started together with + a new state_stack. The statement label must be attached to the + previous state after finding the label in its namespace. */ + if (gfc_state_stack->head == NULL + && gfc_state_stack->previous + && gfc_state_stack->previous->sym + && gfc_state_stack->previous->sym->ns + && gfc_state_stack->previous->sym->ns->parent == NULL) + { + int value = gfc_current_ns->st_labels->value; + gfc_state_data *previous_state = gfc_state_stack; + gfc_namespace *old_ns = gfc_current_ns; + gfc_current_ns = gfc_state_stack->previous->sym->ns; + new_st.here = gfc_get_st_label (value); + new_st.here->defined = ST_LABEL_TARGET; + new_st.op = EXEC_RETURN; + gfc_state_stack = gfc_state_stack->previous; + add_statement (); + gfc_state_stack = previous_state; + gfc_current_ns = old_ns; + } + else + { + new_st.op = EXEC_RETURN; + add_statement (); + } } else { diff --git a/gcc/testsuite/gfortran.dg/pr126909.f90 b/gcc/testsuite/gfortran.dg/pr126909.f90 new file mode 100644 index 00000000000..bb95d9d7cdf --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr126909.f90 @@ -0,0 +1,77 @@ +! {dg-do run } +! { dg-options "-fdump-tree-original" } +! +! Test the fix for PR126909, in which END PROGRAM/FUNCTION/SUBROUTINE labels +! were not being generated correctly, when preceded by contain sections. +! +! Contributed by Steve Kargl <[email protected]> +! +Module tally + integer :: ctr = 0 +contains + integer function two_power_n_plus (n, base) + integer, intent(IN) :: n, base + two_power_n_plus = 2**n + base + end function two_power_n_plus +end module + +program lost + use tally + interface + function yet_more_lost() result(i) + integer :: i + end function yet_more_lost + end interface + + goto 9 + stop 1 +9 ctr = two_power_n_plus (1, ctr) + call sub() + call more_lost() + if (yet_more_lost () /= 42) stop 2 + if (ctr /= 126) stop 3 + goto 10 + stop 4 + contains + subroutine sub() + ctr = two_power_n_plus (2, ctr) + goto 11 + stop 5 +11 end subroutine sub +10 end program lost + +subroutine more_lost + use tally + goto 9 + stop 6 +9 ctr = two_power_n_plus (3, ctr) + call sub2() + goto 10 + stop 7 + contains + subroutine sub2() + ctr = two_power_n_plus (4, ctr) + goto 11 + stop 8 +11 end subroutine sub2 +10 end subroutine more_lost + +function yet_more_lost() result(i) + use tally + integer :: i + i = 42 + goto 9 + stop 9 +9 ctr = two_power_n_plus (5, ctr) + call sub3() + goto 10 + stop 10 + contains + subroutine sub3() + ctr = two_power_n_plus (6, ctr) + goto 11 + stop 11 +11 end subroutine sub3 +10 end function yet_more_lost + +! { dg-final { scan-tree-dump-times "label.000010" 6 "original" } } -- 2.55.0