[flang-commits] [flang] 189c083 - [flang] Fix edge case with Hollerith
peter klausler via flang-commits
flang-commits at lists.llvm.org
Mon Aug 10 11:32:26 PDT 2020
Author: peter klausler
Date: 2020-08-10T11:31:41-07:00
New Revision: 189c0833dfd654f08a8655ca765e11e8890a92ae
URL: https://github.com/llvm/llvm-project/commit/189c0833dfd654f08a8655ca765e11e8890a92ae
DIFF: https://github.com/llvm/llvm-project/commit/189c0833dfd654f08a8655ca765e11e8890a92ae.diff
LOG: [flang] Fix edge case with Hollerith
To prevent mistokenization of CHARACTER*2HXY as a Hollerith
literal constant while allowing it in DATA A/2*2HXY/, there's
a little state that tracks whether a / has been seen earlier
in the same statement. But it was being reset on each line,
not statement, so Hollerith in a DATA statement continuation
line was incorrectly tokenized. Fixed.
Differential Revision: https://reviews.llvm.org/D85571
Added:
flang/test/Preprocessing/hollerith.f
Modified:
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
Removed:
################################################################################
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index face0d20e4fc..9e90f7f6228f 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -110,7 +110,7 @@ void Prescanner::Statement() {
case LineClassification::Kind::CompilerDirective:
directiveSentinel_ = line.sentinel;
CHECK(InCompilerDirective());
- BeginSourceLineAndAdvance();
+ BeginStatementAndAdvance();
if (inFixedForm_) {
CHECK(IsFixedFormCommentChar(*at_));
} else {
@@ -144,7 +144,7 @@ void Prescanner::Statement() {
}
break;
case LineClassification::Kind::Source:
- BeginSourceLineAndAdvance();
+ BeginStatementAndAdvance();
if (inFixedForm_) {
LabelField(tokens);
} else if (skipLeadingAmpersand_) {
@@ -226,7 +226,7 @@ void Prescanner::Statement() {
TokenSequence Prescanner::TokenizePreprocessorDirective() {
CHECK(nextLine_ < limit_ && !inPreprocessorDirective_);
inPreprocessorDirective_ = true;
- BeginSourceLineAndAdvance();
+ BeginStatementAndAdvance();
TokenSequence tokens;
while (NextToken(tokens)) {
}
@@ -497,12 +497,8 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
} while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_)));
if (*at_ == '\'' || *at_ == '"') {
QuotedCharacterLiteral(tokens, start);
- preventHollerith_ = false;
- } else {
- // Subtle: Don't misrecognize labeled DO statement label as Hollerith
- // when the loop control variable starts with 'H'.
- preventHollerith_ = true;
}
+ preventHollerith_ = false;
} else if (*at_ == '*') {
if (EmitCharAndAdvance(tokens, '*') == '*') {
EmitCharAndAdvance(tokens, '*');
@@ -510,7 +506,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
// Subtle ambiguity:
// CHARACTER*2H declares H because *2 is a kind specifier
// DATAC/N*2H / is repeated Hollerith
- preventHollerith_ = !slashInCurrentLine_;
+ preventHollerith_ = !slashInCurrentStatement_;
}
} else {
char ch{*at_};
@@ -530,7 +526,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
// token comprises two characters
EmitCharAndAdvance(tokens, nch);
} else if (ch == '/') {
- slashInCurrentLine_ = true;
+ slashInCurrentStatement_ = true;
}
}
tokens.CloseToken();
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index c4fdeae6e15e..595f8f701185 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -95,9 +95,6 @@ class Prescanner {
at_ = at;
column_ = 1;
tabInCurrentLine_ = false;
- slashInCurrentLine_ = false;
- preventHollerith_ = false;
- delimiterNesting_ = 0;
}
void BeginSourceLineAndAdvance() {
@@ -105,6 +102,13 @@ class Prescanner {
NextLine();
}
+ void BeginStatementAndAdvance() {
+ BeginSourceLineAndAdvance();
+ slashInCurrentStatement_ = false;
+ preventHollerith_ = false;
+ delimiterNesting_ = 0;
+ }
+
Provenance GetProvenance(const char *sourceChar) const {
return startProvenance_ + (sourceChar - start_);
}
@@ -199,8 +203,8 @@ class Prescanner {
const char *at_{nullptr}; // next character to process; < nextLine_
int column_{1}; // card image column position of next character
bool tabInCurrentLine_{false};
- bool slashInCurrentLine_{false};
- bool preventHollerith_{false};
+ bool slashInCurrentStatement_{false};
+ bool preventHollerith_{false}; // CHARACTER*4HIMOM not Hollerith
bool inCharLiteral_{false};
bool inPreprocessorDirective_{false};
diff --git a/flang/test/Preprocessing/hollerith.f b/flang/test/Preprocessing/hollerith.f
new file mode 100644
index 000000000000..0c920e0678e1
--- /dev/null
+++ b/flang/test/Preprocessing/hollerith.f
@@ -0,0 +1,14 @@
+! RUN: %f18 -E %s 2>&1 | FileCheck %s
+! CHECK: character*1hi
+! CHECK: dataa/1*1h /
+! CHECK: datab/1*1h /
+! CHECK: do1h=1,2
+ CHARACTER*1H I
+ CHARACTER*1 A,B
+ INTEGER H
+ DATA A/1*1H /
+ DATA B/
+ +1*1H /
+ DO1H =1,2
+ 1 CONTINUE
+ END
More information about the flang-commits
mailing list