[flang-commits] [flang] [Flang] Fix fixed-form OpenMP prescan for continuation lines (PR #213856)

via flang-commits flang-commits at lists.llvm.org
Mon Aug 10 03:21:36 PDT 2026


https://github.com/ejose02 updated https://github.com/llvm/llvm-project/pull/213856

>From 59776a86a0ad47a380a51fce2abddff4b2a9cd00 Mon Sep 17 00:00:00 2001
From: ejose <ejose at amd.com>
Date: Tue, 4 Aug 2026 07:16:12 +0000
Subject: [PATCH] [Flang] Fix fixed-form OpenMP prescan for continuation lines

Fixed-form OpenMP sources that split directives across continuation lines or use column-72 padding failed to parse.
Improve prescan handling for !$omp comment cards, padding continuation, and blank removal after directive line splicing.
---
 flang/lib/Parser/prescan.cpp                  | 27 +++++++++++++-
 .../OpenMP/fixed-form-omp-continuation.f      | 37 +++++++++++++++++++
 2 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 flang/test/Parser/OpenMP/fixed-form-omp-continuation.f

diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 262954d32f266..cc58c5bd2c5e2 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -344,6 +344,9 @@ void Prescanner::Statement() {
     while (CompilerDirectiveContinuation(tokens, line.sentinel)) {
       newlineProvenance = GetCurrentProvenance();
     }
+    if (inFixedForm_ && !preprocessingOnly_ && tokens.HasBlanks()) {
+      tokens.RemoveBlanks();
+    }
     if (preprocessingOnly_ && inFixedForm_ && InConditionalLine() &&
         nextLine_ < limit_) {
       // In -E mode, when the line after !$ conditional compilation is a
@@ -826,6 +829,22 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
       EmitChar(tokens, *at_);
       ++at_, ++column_;
       hadContinuation = SkipToNextSignificantCharacter();
+      // Fixed-form !$omp: padding / trailing `!` in cols 7-72 before newline
+      // should allow continuation to splice split identifiers.
+      if (!hadContinuation && inFixedForm_ && IsOpenMPDirective() &&
+          !preprocessingOnly_ && IsSpaceOrTab(at_)) {
+        const char *probe{at_};
+        int col{column_};
+        while (col <= fixedFormColumnLimit_ && IsSpaceOrTab(probe)) {
+          probe += IsSpaceOrTab(probe);
+          ++col;
+        }
+        if (col > fixedFormColumnLimit_ || *probe == '\n' || *probe == '\r' ||
+            (*probe == '!' && col <= fixedFormColumnLimit_)) {
+          SkipSpaces();
+          hadContinuation = SkipToNextSignificantCharacter();
+        }
+      }
       if (hadContinuation && IsLegalIdentifierStart(*at_)) {
         if (brokenToken_) {
           break;
@@ -1675,11 +1694,15 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
     }
     ++column;
   }
-  if (isOpenMPConditional) {
+  const bool isOpenMPSentinelScan{isOpenMPConditional ||
+      (features_.IsEnabled(LanguageFeature::OpenMP) &&
+          std::strcmp(sentinel, "$omp") == 0)};
+  if (isOpenMPSentinelScan) {
     for (; column <= fixedFormColumnLimit_; ++column, ++p) {
       if (IsSpaceOrTab(p)) {
       } else if (*p == '!') {
-        return std::nullopt; // !$    ! is a comment, not a directive
+        return std::nullopt; // sentinel + blanks + ! is a comment, not a
+                             // directive
       } else {
         break;
       }
diff --git a/flang/test/Parser/OpenMP/fixed-form-omp-continuation.f b/flang/test/Parser/OpenMP/fixed-form-omp-continuation.f
new file mode 100644
index 0000000000000..afa8577194ff8
--- /dev/null
+++ b/flang/test/Parser/OpenMP/fixed-form-omp-continuation.f
@@ -0,0 +1,37 @@
+! RUN: %flang_fc1 -fopenmp -ffixed-form -fdebug-unparse %s 2>&1 | FileCheck %s --ignore-case
+! RUN: %flang_fc1 -fopenmp -ffixed-form -fdebug-dump-parse-tree %s 2>&1 | FileCheck %s --check-prefix=TREE
+! Exercise fixed-form OpenMP sentinels with continuation and column-72 padding.
+      subroutine sub1
+!23456789012345678901234567890123456789012345678901234567890123456789012
+*$omp   paral
+c$ompxlel s
+c$ompyections n
+!$ompz u m _ t h r e a d s ( 2 )
+!$omp   section
+*$      print *,'in section'
+!$omp   end parallel sections
+      end subroutine
+      subroutine sub2
+!$omp sections
+!$omp sect
+!$omp  ! should be ignored, and make the continuation correct
+!$omp+ion
+      print *,'ok'
+!$omp end sections
+      end subroutine
+      program main
+      call sub1
+      call sub2
+      end program
+
+!CHECK: !$omp parallel sections num_threads(2_4)
+!CHECK: !$omp section
+!CHECK: !$omp end parallel sections
+!CHECK: !$omp sections{{$}}
+!CHECK: !$omp section{{$}}
+!CHECK: !$omp end sections{{$}}
+
+!TREE: OpenMPSectionsConstruct
+!TREE: OmpSectionDirective
+!TREE: OpenMPSectionsConstruct
+!TREE: OmpSectionDirective



More information about the flang-commits mailing list