diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -242,6 +242,11 @@ compilers, so it is not supported. * f18 doesn't impose a limit on the number of continuation lines allowed for a single statement. +* When a type-bound procedure declaration statement has neither interface + nor attributes, the "::" before the bindings is optional, even + if a binding has renaming with "=> proc". + The colons are not necessary for an unambiguous parse, C768 + notwithstanding. ### Extensions supported when enabled by options diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -522,6 +522,9 @@ // R749 type-bound-procedure-stmt -> // PROCEDURE [[, bind-attr-list] ::] type-bound-proc-decl-list | // PROCEDURE ( interface-name ) , bind-attr-list :: binding-name-list +// The "::" is required by the standard (C768) in the first production if +// any type-bound-proc-decl has a "=>', but it's not strictly necessary to +// avoid a bad parse. TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US, "PROCEDURE" >> (construct( @@ -531,6 +534,15 @@ "," >> nonemptyList(Parser{}), ok), localRecovery("expected list of binding names"_err_en_US, "::" >> listOfNames, SkipTo<'\n'>{}))) || + construct(construct< + TypeBoundProcedureStmt::WithoutInterface>( + pure>(), + nonemptyList( + "expected type bound procedure declarations"_err_en_US, + construct(name, + maybe(extension( + "type-bound procedure statement should have '::' if it has '=>'"_port_en_US, + "=>" >> name)))))) || construct( construct( optionalListBeforeColons(Parser{}), diff --git a/flang/test/Parser/missing-colons.f90 b/flang/test/Parser/missing-colons.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/missing-colons.f90 @@ -0,0 +1,13 @@ +! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s +module m + type t + contains +!CHECK: portability: type-bound procedure statement should have '::' if it has '=>' + procedure p => sub + end type + contains + subroutine sub(x) + class(t), intent(in) :: x + end subroutine +end module +