Is it standard to GOTO an end-program statement if contained procedures are allowed?

Out of four compilers I tried two allowed it and using options that usually cause extensions to be flagged did not flag it as an extension; and two generated errors at compilation. Using the extension/feature therefore is not portable so it would be nice to have it clarified so the developers have a definitive statement indicating if it is an extension or not. As it stands a bug report saying it is not flagged as extension could be argued against; as well as a bug report saying it does not work. So I personally would appreciate a definitive clarification from the committee .

It appears so.

Which compilers actually accept it? (Since retiring, I no longer have access to the plethora of compilers I used to.)

Ifort, ifx and g95 accept this program and print In subroutine. Gfortran, AMD flang and lfortran do not.

 implicit none
  call eh
  goto 666
contains
  subroutine eh
    print *,'In subroutine'
  end subroutine eh
666 end program

A goto statement within an internal subprogram referencing the end statement for the host program unit is not permitted because it would reference a label in a different inclusive scope. Discussion about the contains statement is a red-herring.

The code in the original post is standard compliant Fortran. Compilers that fail to accept it are in error.

Here is a simplified code to zero in on what works.

program gotoxxx
   goto 10
contains
10 end program gotoxxx

$ gfortran goto.f90
goto.f90:2:10:

    2 |    goto 10
      |          1
Error: Label 10 referenced at (1) is never defined

$ nagfor goto.f90
NAG Fortran Compiler Release 7.2(Shin-Urayasu) Build 7200
[NAG Fortran Compiler normal termination]

If the CONTAINS statement is removed, then both compilers compile the code without warnings or errors. Also, if the goto statement is replaced with a write statement with an err=10 branch, then the same thing happens with both compilers, so the problem is not limited to just goto branches.

All of those statements are part of the scoping unit for the main program, as per the syntax rule for a main-program (F2023 R1401) and there being no other scoping units (such as internal subprograms) in the example source. This includes the contains statement, not that I can think of any situation where that might be significant.

End statements for main programs are explicitly called out as being executable statements that are valid branch targets (5.3.3, 11.2.1), the goto statement is referencing a label of a statement that is within the same inclusive scope (C1174) … we’re all good to go [to].