[flang-commits] [flang] [flang] Handle continuation line edge case (PR #74751)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Thu Dec 7 11:56:38 PST 2023
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/74751
>From ef3acb9b4e97a76398f56cd7f317fcae56f236e4 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Thu, 7 Dec 2023 11:14:18 -0800
Subject: [PATCH] [flang] Handle continuation line edge case
For a character literal that is split over more than one
source line with free form line continuation using '&'
at the end of one line but missing the standard-required
'&' on the continuation line, also handle the case of spaces
at the beginning of the continuation line.
For example,
PRINT *, 'don'&
't poke the bear'
now prints "don't poke the bear", like nearly all other Fortran
compilers do.
This is not strictly standard conforming behavior, and the compiler
emits a portability warning with -pedantic.
Fixes llvm-test-suite/Fortran/gfortran/regression/continuation_1.f90,
.../continuation_12.f90, and .../continuation_13.f90.
---
flang/lib/Parser/prescan.cpp | 20 ++++++++++---------
flang/lib/Parser/prescan.h | 3 ++-
.../test/Parser/continuation-before-quote.f90 | 10 ----------
.../Parser/continuation-without-ampersand.f90 | 13 ++++++++++++
4 files changed, 26 insertions(+), 20 deletions(-)
delete mode 100644 flang/test/Parser/continuation-before-quote.f90
create mode 100644 flang/test/Parser/continuation-without-ampersand.f90
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 449ea60144424..79cdaccf1fbfe 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -706,6 +706,7 @@ void Prescanner::QuotedCharacterLiteral(
char quote{*at_};
const char *end{at_ + 1};
inCharLiteral_ = true;
+ continuationInCharLiteral_ = true;
const auto emit{[&](char ch) { EmitChar(tokens, ch); }};
const auto insert{[&](char ch) { EmitInsertedChar(tokens, ch); }};
bool isEscaped{false};
@@ -749,16 +750,9 @@ void Prescanner::QuotedCharacterLiteral(
break;
}
inCharLiteral_ = true;
- if (insertASpace_) {
- if (features_.ShouldWarn(
- common::LanguageFeature::MiscSourceExtensions)) {
- Say(GetProvenanceRange(at_, end),
- "Repeated quote mark in character literal continuation line should have been preceded by '&'"_port_en_US);
- }
- insertASpace_ = false;
- }
}
}
+ continuationInCharLiteral_ = false;
inCharLiteral_ = false;
}
@@ -1122,7 +1116,15 @@ const char *Prescanner::FreeFormContinuationLine(bool ampersand) {
} else if (*p == '!' || *p == '\n' || *p == '#') {
return nullptr;
} else if (ampersand || IsImplicitContinuation()) {
- if (p > nextLine_) {
+ if (continuationInCharLiteral_) {
+ // 'a'& -> 'a''b' == "a'b"
+ // 'b'
+ if (features_.ShouldWarn(
+ common::LanguageFeature::MiscSourceExtensions)) {
+ Say(GetProvenanceRange(p, p + 1),
+ "Character literal continuation line should have been preceded by '&'"_port_en_US);
+ }
+ } else if (p > nextLine_) {
--p;
} else {
insertASpace_ = true;
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 16b2c6165f611..a757efb473f3e 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -217,7 +217,8 @@ class Prescanner {
bool tabInCurrentLine_{false};
bool slashInCurrentStatement_{false};
bool preventHollerith_{false}; // CHARACTER*4HIMOM not Hollerith
- bool inCharLiteral_{false};
+ bool inCharLiteral_;
+ bool continuationInCharLiteral_;
bool inPreprocessorDirective_{false};
// In some edge cases of compiler directive continuation lines, it
diff --git a/flang/test/Parser/continuation-before-quote.f90 b/flang/test/Parser/continuation-before-quote.f90
deleted file mode 100644
index 66252010d89c4..0000000000000
--- a/flang/test/Parser/continuation-before-quote.f90
+++ /dev/null
@@ -1,10 +0,0 @@
-! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
-! Continuation between repeated quotation marks
-subroutine test
-!CHECK: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
- print *, 'needs an '&
-'ampersand'''
-!CHECK-NOT: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
- print *, 'has an '&
-&'ampersand'''
-end
diff --git a/flang/test/Parser/continuation-without-ampersand.f90 b/flang/test/Parser/continuation-without-ampersand.f90
new file mode 100644
index 0000000000000..5c3f23235edcc
--- /dev/null
+++ b/flang/test/Parser/continuation-without-ampersand.f90
@@ -0,0 +1,13 @@
+! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s
+! Continuation between repeated quotation marks
+subroutine test
+!CHECK: portability: Character literal continuation line should have been preceded by '&'
+ print *, 'needs an '&
+'ampersand'''
+!CHECK: portability: Character literal continuation line should have been preceded by '&'
+ print *, 'also needs an '&
+ 'ampersand'''
+!CHECK-NOT: portability: Character literal continuation line should have been preceded by '&'
+ print *, 'has an '&
+&'ampersand'''
+end
More information about the flang-commits
mailing list