[flang-commits] [flang] [flang] Accept more unrecognized !DIR$ compiler directives (PR #85829)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Mar 19 10:26:51 PDT 2024


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/85829

When encountering an unparsable !DIR$ compiler directive line, accept it as a whole source line and emit a warning that it is unrecognizable.

Fixes https://github.com/llvm/llvm-project/issues/59107, https://github.com/llvm/llvm-project/issues/82212, and https://github.com/llvm/llvm-project/issues/82654.

>From 825bbc8c03ffa2538898dd49c850938d378a2b98 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 18 Mar 2024 17:12:48 -0700
Subject: [PATCH] [flang] Accept more unrecognized !DIR$ compiler directives

When encountering an unparsable !DIR$ compiler directive line,
accept it as a whole source line and emit a warning that it
is unrecognizable.

Fixes https://github.com/llvm/llvm-project/issues/59107,
https://github.com/llvm/llvm-project/issues/82212, and
https://github.com/llvm/llvm-project/issues/82654.
---
 flang/include/flang/Parser/dump-parse-tree.h  |  1 +
 .../include/flang/Parser/parse-tree-visitor.h | 12 ++++++++
 flang/include/flang/Parser/parse-tree.h       |  6 ++--
 flang/lib/Parser/Fortran-parsers.cpp          | 30 +++++++++++--------
 flang/lib/Parser/unparse.cpp                  |  4 +++
 flang/test/Parser/unrecognized-dir.f90        |  4 +++
 6 files changed, 42 insertions(+), 15 deletions(-)
 create mode 100644 flang/test/Parser/unrecognized-dir.f90

diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index b2c3d92909375c..06c168a5de612c 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -207,6 +207,7 @@ class ParseTreeDumper {
   NODE(CompilerDirective, LoopCount)
   NODE(CompilerDirective, AssumeAligned)
   NODE(CompilerDirective, NameValue)
+  NODE(CompilerDirective, Unrecognized)
   NODE(parser, ComplexLiteralConstant)
   NODE(parser, ComplexPart)
   NODE(parser, ComponentArraySpec)
diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h
index 79ea29f4b7f325..81d01dbdd65cc9 100644
--- a/flang/include/flang/Parser/parse-tree-visitor.h
+++ b/flang/include/flang/Parser/parse-tree-visitor.h
@@ -861,6 +861,18 @@ template <typename M> void Walk(CompilerDirective &x, M &mutator) {
   }
 }
 template <typename V>
+void Walk(const CompilerDirective::Unrecognized &x, V &visitor) {
+  if (visitor.Pre(x)) {
+    visitor.Post(x);
+  }
+}
+template <typename M>
+void Walk(CompilerDirective::Unrecognized &x, M &mutator) {
+  if (mutator.Pre(x)) {
+    mutator.Post(x);
+  }
+}
+template <typename V>
 void Walk(const OmpLinearClause::WithModifier &x, V &visitor) {
   if (visitor.Pre(x)) {
     Walk(x.modifier, visitor);
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index c96abfba491d4b..85e8121dd1250c 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3298,7 +3298,8 @@ struct StmtFunctionStmt {
 // Compiler directives
 // !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]...
 // !DIR$ LOOP COUNT (n1[, n2]...)
-// !DIR$ name...
+// !DIR$ name[=value] [, name[=value]]...    = can be :
+// !DIR$ <anything else>
 struct CompilerDirective {
   UNION_CLASS_BOILERPLATE(CompilerDirective);
   struct IgnoreTKR {
@@ -3316,9 +3317,10 @@ struct CompilerDirective {
     TUPLE_CLASS_BOILERPLATE(NameValue);
     std::tuple<Name, std::optional<std::uint64_t>> t;
   };
+  struct Unrecognized {};
   CharBlock source;
   std::variant<std::list<IgnoreTKR>, LoopCount, std::list<AssumeAligned>,
-      std::list<NameValue>>
+      std::list<NameValue>, Unrecognized>
       u;
 };
 
diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp
index fc81a477897a3c..fd28eea0f947d2 100644
--- a/flang/lib/Parser/Fortran-parsers.cpp
+++ b/flang/lib/Parser/Fortran-parsers.cpp
@@ -1261,24 +1261,28 @@ TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
 // Directives, extensions, and deprecated statements
 // !DIR$ IGNORE_TKR [ [(tkrdmac...)] name ]...
 // !DIR$ LOOP COUNT (n1[, n2]...)
-// !DIR$ name...
+// !DIR$ name[=value] [, name[=value]]...
+// !DIR$ <anything else>
 constexpr auto ignore_tkr{
-    "DIR$ IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
-                             maybe(parenthesized(many(letter))), name))};
+    "IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
+                        maybe(parenthesized(many(letter))), name))};
 constexpr auto loopCount{
-    "DIR$ LOOP COUNT" >> construct<CompilerDirective::LoopCount>(
-                             parenthesized(nonemptyList(digitString64)))};
-constexpr auto assumeAligned{"DIR$ ASSUME_ALIGNED" >>
+    "LOOP COUNT" >> construct<CompilerDirective::LoopCount>(
+                        parenthesized(nonemptyList(digitString64)))};
+constexpr auto assumeAligned{"ASSUME_ALIGNED" >>
     optionalList(construct<CompilerDirective::AssumeAligned>(
         indirect(designator), ":"_tok >> digitString64))};
-TYPE_PARSER(beginDirective >>
-    sourced(construct<CompilerDirective>(ignore_tkr) ||
-        construct<CompilerDirective>(loopCount) ||
-        construct<CompilerDirective>(assumeAligned) ||
+TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
+    sourced((construct<CompilerDirective>(ignore_tkr) ||
+                construct<CompilerDirective>(loopCount) ||
+                construct<CompilerDirective>(assumeAligned) ||
+                construct<CompilerDirective>(
+                    many(construct<CompilerDirective::NameValue>(
+                        name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
+            endOfStmt ||
         construct<CompilerDirective>(
-            "DIR$" >> many(construct<CompilerDirective::NameValue>(name,
-                          maybe(("="_tok || ":"_tok) >> digitString64))))) /
-        endOfStmt)
+            SkipTo<'\n'>{} >> pure<CompilerDirective::Unrecognized>()) /
+            endOfStmt))
 
 TYPE_PARSER(extension<LanguageFeature::CrayPointer>(
     "nonstandard usage: based POINTER"_port_en_US,
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index baba4863f5775f..c06458833f0729 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -1827,6 +1827,10 @@ class UnparseVisitor {
             [&](const std::list<CompilerDirective::NameValue> &names) {
               Walk("!DIR$ ", names, " ");
             },
+            [&](const CompilerDirective::Unrecognized &) {
+              Word("!DIR$ ");
+              Word(x.source.ToString());
+            },
         },
         x.u);
     Put('\n');
diff --git a/flang/test/Parser/unrecognized-dir.f90 b/flang/test/Parser/unrecognized-dir.f90
new file mode 100644
index 00000000000000..ba6fff7562e2d5
--- /dev/null
+++ b/flang/test/Parser/unrecognized-dir.f90
@@ -0,0 +1,4 @@
+! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s
+!CHECK: warning: Compiler directive was ignored
+!DIR$ Not a recognized directive
+end



More information about the flang-commits mailing list