[flang-commits] [flang] [Flang] Fix fixed-form OpenMP prescan for continuation lines (PR #213856)
via flang-commits
flang-commits at lists.llvm.org
Tue Aug 4 02:12:28 PDT 2026
https://github.com/ejose02 updated https://github.com/llvm/llvm-project/pull/213856
>From 039cec2ce38bc246bb61085784d87eb33d8829f0 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..9cea62d01a62c
--- /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
+!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