Skip to content

[flang] Preserve compiler directives in -E output #133959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 4, 2025
Merged

Conversation

klausler
Copy link
Contributor

@klausler klausler commented Apr 1, 2025

No longer require -fopenmp or -fopenacc with -E, unless specific version number options are also required for predefined macros. This means that most source can be preprocessed with -E and then later compiled with -fopenmp, -fopenacc, or neither.

This means that OpenMP conditional compilation lines (!$) are also passed through to -E output. The tricky part of this patch was dealing with the fact that those conditional lines can also contain regular Fortran line continuation, and that now has to be deferred when !$ lines are interspersed.

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Thanks for this improvement for OpenMP/OpenACC -E output.

No longer require -fopenmp or -fopenacc with -E, unless specific
version number options are also required for predefined macros.
This means that most source can be preprocessed with -E and then
later compiled with -fopenmp, -fopenacc, or neither.

This means that OpenMP conditional compilation lines (!$) are
also passed through to -E output.  The tricky part of this patch
was dealing with the fact that those conditional lines can also
contain regular Fortran line continuation, and that now has to be
deferred when !$ lines are interspersed.
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:openmp flang:parser labels Apr 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 4, 2025

@llvm/pr-subscribers-flang-parser

@llvm/pr-subscribers-flang-openmp

Author: Peter Klausler (klausler)

Changes

No longer require -fopenmp or -fopenacc with -E, unless specific version number options are also required for predefined macros. This means that most source can be preprocessed with -E and then later compiled with -fopenmp, -fopenacc, or neither.

This means that OpenMP conditional compilation lines (!$) are also passed through to -E output. The tricky part of this patch was dealing with the fact that those conditional lines can also contain regular Fortran line continuation, and that now has to be deferred when !$ lines are interspersed.


Patch is 22.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133959.diff

10 Files Affected:

  • (modified) flang/lib/Parser/parsing.cpp (+50-18)
  • (modified) flang/lib/Parser/prescan.cpp (+96-79)
  • (modified) flang/lib/Parser/token-sequence.cpp (+1)
  • (modified) flang/test/Parser/OpenMP/compiler-directive-continuation.f90 (+25-14)
  • (modified) flang/test/Parser/OpenMP/sentinels.f (+5-5)
  • (modified) flang/test/Parser/continuation-in-conditional-compilation.f (+3-2)
  • (modified) flang/test/Preprocessing/bug126459.F90 (+3-3)
  • (modified) flang/test/Preprocessing/line-in-contin.F90 (+1-1)
  • (modified) flang/test/Preprocessing/pp132.f90 (+3-1)
  • (modified) flang/test/Preprocessing/preprocessed-dirs.F90 (+1-1)
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index 8fcac7b3cacb1..5f486cbf8e4c8 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -79,16 +79,24 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
       .set_expandIncludeLines(!options.prescanAndReformat ||
           options.expandIncludeLinesInPreprocessedOutput)
       .AddCompilerDirectiveSentinel("dir$");
-  if (options.features.IsEnabled(LanguageFeature::OpenACC)) {
+  bool noneOfTheAbove{!options.features.IsEnabled(LanguageFeature::OpenACC) &&
+      !options.features.IsEnabled(LanguageFeature::OpenMP) &&
+      !options.features.IsEnabled(LanguageFeature::CUDA)};
+  if (options.features.IsEnabled(LanguageFeature::OpenACC) ||
+      (options.prescanAndReformat && noneOfTheAbove)) {
     prescanner.AddCompilerDirectiveSentinel("$acc");
   }
-  if (options.features.IsEnabled(LanguageFeature::OpenMP)) {
+  if (options.features.IsEnabled(LanguageFeature::OpenMP) ||
+      (options.prescanAndReformat && noneOfTheAbove)) {
     prescanner.AddCompilerDirectiveSentinel("$omp");
     prescanner.AddCompilerDirectiveSentinel("$"); // OMP conditional line
   }
-  if (options.features.IsEnabled(LanguageFeature::CUDA)) {
+  if (options.features.IsEnabled(LanguageFeature::CUDA) ||
+      (options.prescanAndReformat && noneOfTheAbove)) {
     prescanner.AddCompilerDirectiveSentinel("$cuf");
     prescanner.AddCompilerDirectiveSentinel("@cuf");
+  }
+  if (options.features.IsEnabled(LanguageFeature::CUDA)) {
     preprocessor_.Define("_CUDA", "1");
   }
   ProvenanceRange range{allSources.AddIncludedFile(
@@ -119,11 +127,13 @@ void Parsing::EmitPreprocessedSource(
   int sourceLine{0};
   int column{1};
   bool inDirective{false};
+  bool ompConditionalLine{false};
   bool inContinuation{false};
   bool lineWasBlankBefore{true};
   const AllSources &allSources{allCooked().allSources()};
-  // All directives that flang support are known to have a length of 3 chars
-  constexpr int directiveNameLength{3};
+  // All directives that flang supports are known to have a length of 4 chars,
+  // except for OpenMP conditional compilation lines (!$).
+  constexpr int directiveNameLength{4};
   // We need to know the current directive in order to provide correct
   // continuation for the directive
   std::string directive;
@@ -133,6 +143,7 @@ void Parsing::EmitPreprocessedSource(
       out << '\n'; // TODO: DOS CR-LF line ending if necessary
       column = 1;
       inDirective = false;
+      ompConditionalLine = false;
       inContinuation = false;
       lineWasBlankBefore = true;
       ++sourceLine;
@@ -153,16 +164,21 @@ void Parsing::EmitPreprocessedSource(
         return ch;
       }};
 
+      bool inDirectiveSentinel{false};
       if (ch == '!' && lineWasBlankBefore) {
         // Other comment markers (C, *, D) in original fixed form source
         // input card column 1 will have been deleted or normalized to !,
         // which signifies a comment (directive) in both source forms.
         inDirective = true;
-      }
-      bool inDirectiveSentinel{
-          inDirective && directive.size() < directiveNameLength};
-      if (inDirectiveSentinel && IsLetter(ch)) {
-        directive += getOriginalChar(ch);
+        inDirectiveSentinel = true;
+      } else if (inDirective && !ompConditionalLine &&
+          directive.size() < directiveNameLength) {
+        if (IsLetter(ch) || ch == '$' || ch == '@') {
+          directive += getOriginalChar(ch);
+          inDirectiveSentinel = true;
+        } else if (directive == "$"s) {
+          ompConditionalLine = true;
+        }
       }
 
       std::optional<SourcePosition> position{provenance
@@ -199,9 +215,16 @@ void Parsing::EmitPreprocessedSource(
         // column limit override option.
         // OpenMP and OpenACC directives' continuations should have the
         // corresponding sentinel at the next line.
-        const auto continuation{
-            inDirective ? "&\n!$" + directive + "&" : "&\n     &"s};
-        out << continuation;
+        out << "&\n";
+        if (inDirective) {
+          if (ompConditionalLine) {
+            out << "!$   &";
+          } else {
+            out << '!' << directive << '&';
+          }
+        } else {
+          out << "     &";
+        }
         column = 7; // start of fixed form source field
         ++sourceLine;
         inContinuation = true;
@@ -212,11 +235,20 @@ void Parsing::EmitPreprocessedSource(
           out << ' ';
         }
       }
-      if (!inContinuation && !inDirectiveSentinel && position &&
-          position->column <= 72 && ch != ' ') {
-        // Preserve original indentation
-        for (; column < position->column; ++column) {
-          out << ' ';
+      if (ch != ' ') {
+        if (ompConditionalLine) {
+          // Only digits can stay in the label field
+          if (!(ch >= '0' && ch <= '9')) {
+            for (; column < 7; ++column) {
+              out << ' ';
+            }
+          }
+        } else if (!inContinuation && !inDirectiveSentinel && position &&
+            position->column <= 72) {
+          // Preserve original indentation
+          for (; column < position->column; ++column) {
+            out << ' ';
+          }
         }
       }
       out << getOriginalChar(ch);
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 755cb18cb8caf..31fdadeddef53 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -150,16 +150,18 @@ void Prescanner::Statement() {
       CHECK(*at_ == '!');
     }
     std::optional<int> condOffset;
+    bool isFFOpenMPCondCompilation{false};
     if (directiveSentinel_[0] == '$' && directiveSentinel_[1] == '\0') {
       // OpenMP conditional compilation line.
       condOffset = 2;
+      isFFOpenMPCondCompilation = inFixedForm_;
     } else if (directiveSentinel_[0] == '@' && directiveSentinel_[1] == 'c' &&
         directiveSentinel_[2] == 'u' && directiveSentinel_[3] == 'f' &&
         directiveSentinel_[4] == '\0') {
       // CUDA conditional compilation line.
       condOffset = 5;
     }
-    if (condOffset) {
+    if (condOffset && !preprocessingOnly_) {
       at_ += *condOffset, column_ += *condOffset;
       if (auto payload{IsIncludeLine(at_)}) {
         FortranInclude(at_ + *payload);
@@ -171,6 +173,8 @@ void Prescanner::Statement() {
       }
     } else {
       // Compiler directive.  Emit normalized sentinel, squash following spaces.
+      // Conditional compilation lines (!$) take this path in -E mode too
+      // so that -fopenmp only has to appear on the later compilation.
       EmitChar(tokens, '!');
       ++at_, ++column_;
       for (const char *sp{directiveSentinel_}; *sp != '\0';
@@ -178,10 +182,23 @@ void Prescanner::Statement() {
         EmitChar(tokens, *sp);
       }
       if (IsSpaceOrTab(at_)) {
-        EmitChar(tokens, ' ');
         while (int n{IsSpaceOrTab(at_)}) {
+          if (isFFOpenMPCondCompilation) {
+            EmitChar(tokens, ' ');
+          }
           at_ += n, ++column_;
         }
+        if (isFFOpenMPCondCompilation && column_ == 6) {
+          if (*at_ == '0') {
+            EmitChar(tokens, ' ');
+          } else {
+            tokens.CloseToken();
+            EmitChar(tokens, '&');
+          }
+          ++at_, ++column_;
+        } else {
+          EmitChar(tokens, ' ');
+        }
       }
       tokens.CloseToken();
     }
@@ -330,7 +347,7 @@ void Prescanner::Statement() {
 void Prescanner::CheckAndEmitLine(
     TokenSequence &tokens, Provenance newlineProvenance) {
   tokens.CheckBadFortranCharacters(
-      messages_, *this, disableSourceContinuation_);
+      messages_, *this, disableSourceContinuation_ || preprocessingOnly_);
   // Parenthesis nesting check does not apply while any #include is
   // active, nor on the lines before and after a top-level #include,
   // nor before or after conditional source.
@@ -1260,10 +1277,12 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
   }
   tabInCurrentLine_ = false;
   char col1{*nextLine_};
-  if (IsFixedFormCommentChar(col1)) {
-    int j{1};
-    if (InCompilerDirective()) {
-      // Must be a continued compiler directive.
+  if (InCompilerDirective()) {
+    if (preprocessingOnly_ && directiveSentinel_[0] == '$' &&
+        directiveSentinel_[1] == '\0') {
+      // in -E mode, don't treat "!$   &" as a continuation
+    } else if (IsFixedFormCommentChar(col1)) {
+      int j{1};
       for (; j < 5; ++j) {
         char ch{directiveSentinel_[j - 1]};
         if (ch == '\0') {
@@ -1273,28 +1292,19 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
           return nullptr;
         }
       }
-    } else if (features_.IsEnabled(LanguageFeature::OpenMP)) {
-      // Fixed Source Form Conditional Compilation Sentinels.
-      if (nextLine_[1] != '$') {
-        return nullptr;
-      }
-      j++;
-    } else {
-      return nullptr;
-    }
-    for (; j < 5; ++j) {
-      if (nextLine_[j] != ' ') {
-        return nullptr;
+      for (; j < 5; ++j) {
+        if (nextLine_[j] != ' ') {
+          return nullptr;
+        }
       }
-    }
-    const char *col6{nextLine_ + 5};
-    if (*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
-      if (mightNeedSpace && !IsSpace(nextLine_ + 6)) {
-        insertASpace_ = true;
+      const char *col6{nextLine_ + 5};
+      if (*col6 != '\n' && *col6 != '0' && !IsSpaceOrTab(col6)) {
+        if (mightNeedSpace && !IsSpace(nextLine_ + 6)) {
+          insertASpace_ = true;
+        }
+        return nextLine_ + 6;
       }
-      return nextLine_ + 6;
     }
-    return nullptr;
   } else {
     // Normal case: not in a compiler directive.
     if (col1 == '&' &&
@@ -1334,59 +1344,60 @@ const char *Prescanner::FixedFormContinuationLine(bool mightNeedSpace) {
 }
 
 const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
-  const char *p{nextLine_};
+  const char *lineStart{nextLine_};
+  const char *p{lineStart};
   if (p >= limit_) {
     return nullptr;
   }
   p = SkipWhiteSpaceIncludingEmptyMacros(p);
-  if (*p == '!') {
-    ++p;
-    if (InCompilerDirective()) {
+  if (InCompilerDirective()) {
+    if (preprocessingOnly_ && directiveSentinel_[0] == '$' &&
+        directiveSentinel_[1] == '\0') {
+      // in -E mode, don't treat !$ as a continuation
+    } else if (*p++ == '!') {
       for (const char *s{directiveSentinel_}; *s != '\0'; ++p, ++s) {
         if (*s != ToLowerCaseLetter(*p)) {
-          return nullptr;
+          return nullptr; // not the same directive class
         }
       }
-    } else if (features_.IsEnabled(LanguageFeature::OpenMP) && *p == '$') {
-      ++p;
-    } else {
-      return nullptr;
-    }
-    p = SkipWhiteSpace(p);
-    if (*p == '&') {
-      if (!ampersand) {
-        insertASpace_ = true;
+      p = SkipWhiteSpace(p);
+      if (*p == '&') {
+        if (!ampersand) {
+          insertASpace_ = true;
+        }
+        return p + 1;
+      } else if (ampersand) {
+        return p;
       }
-      return p + 1;
-    } else if (ampersand) {
-      return p;
-    } else {
-      return nullptr;
     }
-  } else {
-    if (*p == '&') {
-      return p + 1;
-    } else if (*p == '!' || *p == '\n' || *p == '#') {
-      return nullptr;
-    } else if (ampersand || IsImplicitContinuation()) {
-      if (continuationInCharLiteral_) {
-        // 'a'&            -> 'a''b' == "a'b"
-        //   'b'
-        if (features_.ShouldWarn(
-                common::LanguageFeature::MiscSourceExtensions)) {
-          Say(common::LanguageFeature::MiscSourceExtensions,
-              GetProvenanceRange(p, p + 1),
-              "Character literal continuation line should have been preceded by '&'"_port_en_US);
-        }
-      } else if (p > nextLine_) {
-        --p;
-      } else {
-        insertASpace_ = true;
+    return nullptr;
+  }
+  if (p[0] == '!' && p[1] == '$' && !preprocessingOnly_ &&
+      features_.IsEnabled(LanguageFeature::OpenMP)) {
+    // !$ conditional line can be a continuation
+    p = lineStart = SkipWhiteSpace(p + 2);
+  }
+  if (*p == '&') {
+    return p + 1;
+  } else if (*p == '!' || *p == '\n' || *p == '#') {
+    return nullptr;
+  } else if (ampersand || IsImplicitContinuation()) {
+    if (continuationInCharLiteral_) {
+      // 'a'&            -> 'a''b' == "a'b"
+      //   'b'
+      if (features_.ShouldWarn(common::LanguageFeature::MiscSourceExtensions)) {
+        Say(common::LanguageFeature::MiscSourceExtensions,
+            GetProvenanceRange(p, p + 1),
+            "Character literal continuation line should have been preceded by '&'"_port_en_US);
       }
-      return p;
+    } else if (p > lineStart) {
+      --p;
     } else {
-      return nullptr;
+      insertASpace_ = true;
     }
+    return p;
+  } else {
+    return nullptr;
   }
 }
 
@@ -1419,6 +1430,8 @@ bool Prescanner::FreeFormContinuation() {
     } else if (*p == '!') { // & ! comment - ok
     } else if (ampersand && isPossibleMacroCall_ && (*p == ',' || *p == ')')) {
       return false; // allow & at end of a macro argument
+    } else if (ampersand && preprocessingOnly_ && !parenthesisNesting_) {
+      return false; // allow & at start of line, maybe after !$
     } else if (features_.ShouldWarn(LanguageFeature::CruftAfterAmpersand)) {
       Say(LanguageFeature::CruftAfterAmpersand, GetProvenance(p),
           "missing ! before comment after &"_warn_en_US);
@@ -1481,35 +1494,37 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
     }
     *sp++ = ToLowerCaseLetter(*p);
   }
+  if (sp == sentinel) {
+    return std::nullopt;
+  }
+  *sp = '\0';
   // A fixed form OpenMP conditional compilation sentinel must satisfy the
   // following criteria, for initial lines:
   // - Columns 3 through 5 must have only white space or numbers.
   // - Column 6 must be space or zero.
-  if (column == 3 && sentinel[0] == '$') {
-    const char *q{p};
-    for (int col{3}; col < 6; ++col, ++q) {
-      if (!IsSpaceOrTab(q) && !IsDecimalDigit(*q)) {
+  bool isOpenMPConditional{sp == &sentinel[1] && sentinel[0] == '$'};
+  bool hadDigit{false};
+  if (isOpenMPConditional) {
+    for (; column < 6; ++column, ++p) {
+      if (IsDecimalDigit(*p)) {
+        hadDigit = true;
+      } else if (!IsSpaceOrTab(p)) {
         return std::nullopt;
       }
     }
-    if (*q != ' ' && *q != '0') {
-      return std::nullopt;
-    }
   }
   if (column == 6) {
     if (*p == '0') {
       ++p;
     } else if (int n{IsSpaceOrTab(p)}) {
       p += n;
+    } else if (isOpenMPConditional && preprocessingOnly_ && !hadDigit) {
+      // In -E mode, "!$   &" is treated as a directive
     } else {
       // This is a Continuation line, not an initial directive line.
       return std::nullopt;
     }
   }
-  if (sp == sentinel) {
-    return std::nullopt;
-  }
-  *sp = '\0';
   if (const char *ss{IsCompilerDirectiveSentinel(
           sentinel, static_cast<std::size_t>(sp - sentinel))}) {
     return {
@@ -1575,7 +1590,8 @@ std::optional<std::pair<const char *, const char *>>
 Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
   char sentinel[8];
   for (std::size_t j{0}; j + 1 < sizeof sentinel && *p != '\n'; ++p, ++j) {
-    if (int n{*p == '&' ? 1 : IsSpaceOrTab(p)}) {
+    if (int n{IsSpaceOrTab(p)};
+        n || !(IsLetter(*p) || *p == '$' || *p == '@')) {
       if (j > 0) {
         sentinel[j] = '\0';
         p = SkipWhiteSpaceIncludingEmptyMacros(p + n);
@@ -1668,7 +1684,8 @@ void Prescanner::SourceFormChange(std::string &&dir) {
 bool Prescanner::CompilerDirectiveContinuation(
     TokenSequence &tokens, const char *origSentinel) {
   if (inFixedForm_ || tokens.empty() ||
-      tokens.TokenAt(tokens.SizeInTokens() - 1) != "&") {
+      tokens.TokenAt(tokens.SizeInTokens() - 1) != "&" ||
+      (preprocessingOnly_ && !parenthesisNesting_)) {
     return false;
   }
   LineClassification followingLine{ClassifyLine(nextLine_)};
diff --git a/flang/lib/Parser/token-sequence.cpp b/flang/lib/Parser/token-sequence.cpp
index cdbe89b1eb441..fb1ea5965f338 100644
--- a/flang/lib/Parser/token-sequence.cpp
+++ b/flang/lib/Parser/token-sequence.cpp
@@ -318,6 +318,7 @@ llvm::raw_ostream &TokenSequence::Dump(llvm::raw_ostream &o) const {
     o << '[' << j << "] @ " << start_[j] << " '" << TokenAt(j).ToString()
       << "'\n";
   }
+  provenances_.Dump(o << "provenances_:\n");
   return o;
 }
 
diff --git a/flang/test/Parser/OpenMP/compiler-directive-continuation.f90 b/flang/test/Parser/OpenMP/compiler-directive-continuation.f90
index 87e4a72c54294..7ace109272302 100644
--- a/flang/test/Parser/OpenMP/compiler-directive-continuation.f90
+++ b/flang/test/Parser/OpenMP/compiler-directive-continuation.f90
@@ -1,12 +1,18 @@
-! RUN: %flang_fc1 -fopenmp -E %s 2>&1 | FileCheck %s --check-prefix=CHECK-OMP
-! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s 
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s --strict-whitespace --check-prefix=CHECK-E
+! RUN: %flang_fc1 -fopenmp -fdebug-unparse %s 2>&1 | FileCheck %s --check-prefix=CHECK-OMP
+! RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OMP
 
-
-! Test in mixed way, i.e., combination of Fortran free source form 
+! Test in mixed way, i.e., combination of Fortran free source form
 ! and free source form with conditional compilation sentinel.
 ! CHECK-LABEL: subroutine mixed_form1()
-! CHECK-OMP: i = 1 +100+ 1000+ 10 + 1 +1000000000 + 1000000
-! CHECK: i = 1 + 10 + 10000 + 1000000
+! CHECK-E:{{^}}      i = 1 &
+! CHECK-E:{{^}}!$    +100&
+! CHECK-E:{{^}}!$    &+ 1000&
+! CHECK-E:{{^}}      &+ 10 + 1&
+! CHECK-E:{{^}}!$    & +100000&
+! CHECK-E:{{^}}      &0000 + 1000000
+! CHECK-OMP: i=1001001112_4
+! CHECK-NO-OMP: i=1010011_4
 subroutine mixed_form1()
    i = 1 &
   !$+100&
@@ -14,13 +20,13 @@ subroutine mixed_form1()
    &+ 10 + 1&
   !$& +100000&
    &0000 + 1000000
-end subroutine	
-
+end subroutine
 
 ! Testing continuation lines in only Fortran Free form Source
 ! CHECK-LABEL: subroutine mixed_form2()
-! CHECK-OMP: i = 1 +10 +100 + 1000 + 10000
-! CHECK: i = 1 +10 +100 + 1000 + 10000
+! CHECK-E:{{^}}      i = 1 +10 +100 + 1000 + 10000
+! CHECK-OMP: i=11111_4
+! CHECK-NO-OMP: i=11111_4
 subroutine mixed_form2()
    i = 1 &
    +10 &
@@ -29,16 +35,21 @@ subroutine mixed_form2()
    + 10000
 end subroutine
 
-
 ! Testing continuation line in only free source form conditional compilation sentinel.
 ! CHECK-LABEL: subroutine mixed_form3()
-! CHECK-OMP: i=0
-! CHECK-OMP: i = 1 +10 +100+1000
+! CHECK-E:{{^}}!$    i=0
+! CHECK-E:{{^}}!$    i = 1 &
+! CHECK-E:{{^}}!$    & +10 &
+! CHECK-E:{{^}}!$    &+100&
+! CHECK-E:{{^}}!$    +1000
+! CHECK-OMP: i=0_4
+! CHECK-OMP: i=1111_4
+! CHECK-NO-OMP-NOT: i=0_4
 subroutine mixed_form3()
    !$ i=0
    !$ i = 1 &
    !$ & +10 &
    !$&+100&
-   !$ +1000 
+   !$ +1000
 end subroutine
 
diff --git a/flang/test/Parser/OpenMP/sentinels.f b/flang/test/Parser/OpenMP/sentinels.f
index f41ff13bcdd34..299b83e2abba8 100644
--- a/flang/test/Parser/OpenMP/sentinels.f
+++ b/flang/test/Parser/OpenMP/sentinels.f
@@ -1,4 +1,4 @@
-! RUN: %flang_fc1 -fopenmp -E %s | FileCheck %s
+! RUN: %flang_fc1 -E %s | FileCheck %s
 ! CHECK:      program main
 ! CHECK:       interface
 ! CHECK:        subroutine sub(a, b)
@@ -60,13 +60,13 @@ subroutine sub(a, b)
 c$  +&         , "comment"
 
 ! Test valid chars in initial and continuation lines.
-! CHECK:      "msg2"
-! CHECK-SAME: "msg3"
+! CHECK: !$ 20 PRINT *, "msg2"
+! CHECK: !$ & , "msg3"
 c$ 20 PRINT *, "msg2"
 c$   &         , "msg3"
 
-! CHECK:      "msg4"
-! CHECK-SAME: "msg5"
+! CHECK: !$ PRINT *, "msg4",
+! CHECK: !$ & "msg5"
 c$   0PRINT *, "msg4",
 c$   +         "msg5"
       end
diff --git a/flang/test/Parser/continuation-in-conditional-compilation.f b/flang/test/Parser/continuation-in-conditional-compilation.f
index 987112301e335..35525b4fda582 100644
--- a/flang/test/Parser/continuation-in-conditional-compilation.f
+++ b/flang/test/Parser/continuation-in-conditional-compilation.f
@@ -1,6 +1,7 @@
-! RUN: %flang_fc1 -fopenmp -fopenacc -E %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -E %s 2>&1 | FileCheck %s
       program main
-! CHECK: k01=1+ 1
+! CHECK:       k01=1+
+! CHECK: !$   & 1
       k01=1+
 !$   &  1
 
diff --git a/flang/test/Preprocessing/bug126459.F90 b/flang/test/Preprocessing/bug1...
[truncated]

@klausler klausler merged commit 5942f02 into llvm:main Apr 4, 2025
14 checks passed
@klausler klausler deleted the bug377 branch April 4, 2025 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:openmp flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants