-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[flang] Handle continuation line edge case #74751
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
Conversation
@llvm/pr-subscribers-flang-parser Author: Peter Klausler (klausler) ChangesFor repeated quote marks in a character literal that are separated by free form line continuation without a leading ampersand character on the continuation line, also handle the case of spaces at the beginning of the continuation line. For example, PRINT *, 'don'& 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_12.f90 and .../continuation_13.f90. Full diff: https://github.com/llvm/llvm-project/pull/74751.diff 3 Files Affected:
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 449ea60144424a..ac68b54a50ca18 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;
+ charLiteralQuote_ = quote;
const auto emit{[&](char ch) { EmitChar(tokens, ch); }};
const auto insert{[&](char ch) { EmitInsertedChar(tokens, ch); }};
bool isEscaped{false};
@@ -749,17 +750,10 @@ 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;
- }
}
}
inCharLiteral_ = false;
+ charLiteralQuote_.reset();
}
void Prescanner::Hollerith(
@@ -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 (charLiteralQuote_ && *p == *charLiteralQuote_) {
+ // 'a'& -> 'a''b' == "a'b"
+ // 'b'
+ if (features_.ShouldWarn(
+ common::LanguageFeature::MiscSourceExtensions)) {
+ Say(GetProvenanceRange(p, p + 1),
+ "Repeated quote mark in 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 16b2c6165f611c..efeda592813ea7 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_;
+ std::optional<char> charLiteralQuote_;
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
index 66252010d89c46..1cc44d29c87463 100644
--- a/flang/test/Parser/continuation-before-quote.f90
+++ b/flang/test/Parser/continuation-before-quote.f90
@@ -4,6 +4,9 @@ subroutine test
!CHECK: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
print *, 'needs an '&
'ampersand'''
+!CHECK: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
+ print *, 'also needs an '&
+ 'ampersand'''
!CHECK-NOT: portability: Repeated quote mark in character literal continuation line should have been preceded by '&'
print *, 'has an '&
&'ampersand'''
|
5f064bc
to
ef3acb9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm seeing failing tests with these changes. Here's the list:
Failed Tests (14):
Flang :: Lower/OpenMP/FIR/unstructured.f90
Flang :: Lower/OpenMP/unstructured.f90
Flang :: Lower/array-expression.f90
Flang :: Lower/assigned-goto.f90
Flang :: Lower/associate-construct.f90
Flang :: Lower/block.f90
Flang :: Lower/computed-goto.f90
Flang :: Lower/irreducible.f90
Flang :: Lower/loops.f90
Flang :: Lower/select-case-statement.f90
Flang :: Lower/submodule.f90
Flang :: Lower/transformational-intrinsics.f90
Flang :: Semantics/allocate09.f90
Flang :: Semantics/typeinfo01.f90
Here's an excerpt from the log file for the first one:
Command Output (stderr):
--
RUN: at line 3: bbc /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90 -fopenmp -emit-fir -hlfir=false -o "-" | /local/home/psteinfeld/main/klausler/build/bin/FileCheck /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90
+ bbc /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90 -fopenmp -emit-fir -hlfir=false -o -
+ /local/home/psteinfeld/main/klausler/build/bin/FileCheck /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90
bbc: could not scan /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90
/local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90:21:19: error: bad character ('!') in Fortran token
subroutine ss1(n) ! unstructured code followed by a structured OpenMP construct
^
FileCheck error: '<stdin>' is empty.
FileCheck command line: /local/home/psteinfeld/main/klausler/build/bin/FileCheck /local/home/psteinfeld/main/klausler/flang/test/Lower/OpenMP/FIR/unstructured.f90
Everything passes for me -- I always run tests for every build -- and it's basically impossible these tests could have been broken by a prescanner fix. EDIT: These are tests that my builds may not run. Will investigate further. |
I was surprised, too. So I did a build from scratch and ran You can take a look at my builds on ice4. My build from your repository is in /local/home/psteinfeld/main/klausler. My build with the files from Or, if there's an additional test you'd like me to run, I'd be glad to do that, too. |
Note that I've done two different builds -- one from a cloned version of your workspace and the other from llvm-project/main with just the two If it makes a difference, I'm building with GCC 9.3.0. |
That gives me an idea. Let me get back to you on this. Thanks for all your time thus far. |
ef3acb9
to
13ff0e0
Compare
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.
13ff0e0
to
c71eb11
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This latest version builds and tests correctly.
Thanks for the quick fix!
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.