[flang] Warn on missing colons (C768)
authorPeter Klausler <pklausler@nvidia.com>
Mon, 7 Nov 2022 23:51:03 +0000 (15:51 -0800)
committerPeter Klausler <pklausler@nvidia.com>
Sat, 3 Dec 2022 17:27:39 +0000 (09:27 -0800)
In a derived type definition, a type bound procedure declaration
statement with neither interface nor attributes is required by constraint
C768 to have the optional "::" between the PROCEDURE keyword and the
bindings if any binding has a renaming with "=>".  The colons are
not actually necessary for a correct and unambiguous parse, so
emit a warning when they are missing.

Differential Revision: https://reviews.llvm.org/D139065

flang/docs/Extensions.md
flang/lib/Parser/Fortran-parsers.cpp
flang/test/Parser/missing-colons.f90 [new file with mode: 0644]

index a512048..e56585e 100644 (file)
@@ -242,6 +242,11 @@ end
   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
 
index 86c3d55..5f64d33 100644 (file)
@@ -522,6 +522,9 @@ TYPE_CONTEXT_PARSER("type bound procedure binding"_en_US,
 // 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<TypeBoundProcedureStmt>(
@@ -531,6 +534,15 @@ TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US,
                      "," >> nonemptyList(Parser<BindAttr>{}), ok),
                  localRecovery("expected list of binding names"_err_en_US,
                      "::" >> listOfNames, SkipTo<'\n'>{}))) ||
+            construct<TypeBoundProcedureStmt>(construct<
+                TypeBoundProcedureStmt::WithoutInterface>(
+                pure<std::list<BindAttr>>(),
+                nonemptyList(
+                    "expected type bound procedure declarations"_err_en_US,
+                    construct<TypeBoundProcDecl>(name,
+                        maybe(extension<LanguageFeature::MissingColons>(
+                            "type-bound procedure statement should have '::' if it has '=>'"_port_en_US,
+                            "=>" >> name)))))) ||
             construct<TypeBoundProcedureStmt>(
                 construct<TypeBoundProcedureStmt::WithoutInterface>(
                     optionalListBeforeColons(Parser<BindAttr>{}),
diff --git a/flang/test/Parser/missing-colons.f90 b/flang/test/Parser/missing-colons.f90
new file mode 100644 (file)
index 0000000..ebb728c
--- /dev/null
@@ -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
+