[flang-commits] [flang] [flang][OpenMP] Fix regression in !$ continuation (PR #134756)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Mon Apr 7 16:46:25 PDT 2025


https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/134756

>From 0d097cbda0ed98727cc881d2220dd8427c3ac621 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Mon, 7 Apr 2025 16:34:20 -0700
Subject: [PATCH] [flang][OpenMP] Fix regression in !$ continuation

A recent patch that obviated the need to use -fopenmp when using
the compiler to preprocess in -E mode broke a case of Fortran line
continuation when using OpenMP conditional compilation lines (!$)
when *not* in -E mode.  Fix.
---
 flang/lib/Parser/prescan.cpp | 65 +++++++++++++++++++++++-------------
 1 file changed, 42 insertions(+), 23 deletions(-)

diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 31fdadeddef53..8f5bd05365976 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -1278,17 +1278,23 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
   tabInCurrentLine_ = false;
   char col1{*nextLine_};
   if (InCompilerDirective()) {
-    if (preprocessingOnly_ && directiveSentinel_[0] == '$' &&
-        directiveSentinel_[1] == '\0') {
-      // in -E mode, don't treat "!$   &" as a continuation
+    if (directiveSentinel_[0] == '$' && directiveSentinel_[1] == '\0') {
+      if (preprocessingOnly_) {
+        // in -E mode, don't treat "!$   &" as a continuation
+        return nullptr;
+      } else if (IsFixedFormCommentChar(col1) && nextLine_[1] == '$') {
+        // accept but do not require a matching sentinel
+        if (IsLetter(nextLine_[2])) {
+          return nullptr; // not !$
+        }
+      }
     } else if (IsFixedFormCommentChar(col1)) {
       int j{1};
       for (; j < 5; ++j) {
         char ch{directiveSentinel_[j - 1]};
         if (ch == '\0') {
           break;
-        }
-        if (ch != ToLowerCaseLetter(nextLine_[j])) {
+        } else if (ch != ToLowerCaseLetter(nextLine_[j])) {
           return nullptr;
         }
       }
@@ -1297,13 +1303,15 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
           return nullptr;
         }
       }
-      const char *col6{nextLine_ + 5};
-      if (*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
-        if (mightNeedSpace && !IsSpace(nextLine_ + 6)) {
-          insertASpace_ = true;
-        }
-        return nextLine_ + 6;
+    } else {
+      return nullptr;
+    }
+    const char *col6{nextLine_ + 5};
+    if (*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
+      if (mightNeedSpace && !IsSpace(nextLine_ + 6)) {
+        insertASpace_ = true;
       }
+      return nextLine_ + 6;
     }
   } else {
     // Normal case: not in a compiler directive.
@@ -1351,26 +1359,37 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
   }
   p = SkipWhiteSpaceIncludingEmptyMacros(p);
   if (InCompilerDirective()) {
-    if (preprocessingOnly_ && directiveSentinel_[0] == '$' &&
-        directiveSentinel_[1] == '\0') {
-      // in -E mode, don't treat !$ as a continuation
+    if (directiveSentinel_[0] == '$' && directiveSentinel_[1] == '\0') {
+      if (preprocessingOnly_) {
+        // in -E mode, don't treat !$ as a continuation
+        return nullptr;
+      } else if (p[0] == '!' && p[1] == '$') {
+        // accept but do not require a matching sentinel
+        if (IsLetter(p[2])) {
+          return nullptr; // not !$
+        }
+        p += 2;
+      }
     } else if (*p++ == '!') {
       for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) {
         if (*s != ToLowerCaseLetter(*p)) {
           return nullptr; // not the same directive class
         }
       }
-      p = SkipWhiteSpace(p);
-      if (*p == '&') {
-        if (!ampersand) {
-          insertASpace_ = true;
-        }
-        return p + 1;
-      } else if (ampersand) {
-        return p;
+    } else {
+      return nullptr;
+    }
+    p = SkipWhiteSpace(p);
+    if (*p == '&') {
+      if (!ampersand) {
+        insertASpace_ = true;
       }
+      return p + 1;
+    } else if (ampersand) {
+      return p;
+    } else {
+      return nullptr;
     }
-    return nullptr;
   }
   if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ &&
       features_.IsEnabled(LanguageFeature::OpenMP)) {



More information about the flang-commits mailing list