diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h --- a/flang/lib/Parser/prescan.h +++ b/flang/lib/Parser/prescan.h @@ -95,9 +95,6 @@ at_ = at; column_ = 1; tabInCurrentLine_ = false; - slashInCurrentLine_ = false; - preventHollerith_ = false; - delimiterNesting_ = 0; } void BeginSourceLineAndAdvance() { @@ -105,6 +102,13 @@ NextLine(); } + void BeginStatementAndAdvance() { + BeginSourceLineAndAdvance(); + slashInCurrentStatement_ = false; + preventHollerith_ = false; + delimiterNesting_ = 0; + } + Provenance GetProvenance(const char *sourceChar) const { return startProvenance_ + (sourceChar - start_); } @@ -199,8 +203,8 @@ 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/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp --- a/flang/lib/Parser/prescan.cpp +++ b/flang/lib/Parser/prescan.cpp @@ -110,7 +110,7 @@ case LineClassification::Kind::CompilerDirective: directiveSentinel_ = line.sentinel; CHECK(InCompilerDirective()); - BeginSourceLineAndAdvance(); + BeginStatementAndAdvance(); if (inFixedForm_) { CHECK(IsFixedFormCommentChar(*at_)); } else { @@ -144,7 +144,7 @@ } break; case LineClassification::Kind::Source: - BeginSourceLineAndAdvance(); + BeginStatementAndAdvance(); if (inFixedForm_) { LabelField(tokens); } else if (skipLeadingAmpersand_) { @@ -226,7 +226,7 @@ TokenSequence Prescanner::TokenizePreprocessorDirective() { CHECK(nextLine_ < limit_ && !inPreprocessorDirective_); inPreprocessorDirective_ = true; - BeginSourceLineAndAdvance(); + BeginStatementAndAdvance(); TokenSequence tokens; while (NextToken(tokens)) { } @@ -497,12 +497,8 @@ } 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 @@ // 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 @@ // token comprises two characters EmitCharAndAdvance(tokens, nch); } else if (ch == '/') { - slashInCurrentLine_ = true; + slashInCurrentStatement_ = true; } } tokens.CloseToken(); diff --git a/flang/test/Preprocessing/hollerith.f b/flang/test/Preprocessing/hollerith.f new file mode 100644 --- /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