Skip to content

Commit 52afb8d

Browse files
authored
[flang] Don't retain FIXED/FREE compiler directives (llvm#160780)
Some old code in the prescanner, antedating the current -E output mechanisms, retains the !DIR$ FIXED and !DIR$ FREE directives in the input, and will even generate them to append to the scanned source from source and include files to restore the fixed/free source form distinction. But these directives have not been needed since the -E output generator began generating source form insensitive output, and they can confuse the parser's error recovery when the appended directives follow the END statement. Change their handling so that they're read and respected by the prescanner but no longer retained in either the -E output or the cooked character stream passed on to the parser. Fixes a regression reported by @DanielCChen after PR 159834.
1 parent 6399d47 commit 52afb8d

File tree

3 files changed

+24
-19
lines changed

3 files changed

+24
-19
lines changed

flang/lib/Parser/prescan.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,7 @@ void Prescanner::Prescan(ProvenanceRange range) {
9797
while (!IsAtEnd()) {
9898
Statement();
9999
}
100-
if (inFixedForm_ != beganInFixedForm) {
101-
std::string dir{"!dir$ "};
102-
if (beganInFixedForm) {
103-
dir += "fixed";
104-
} else {
105-
dir += "free";
106-
}
107-
dir += '\n';
108-
TokenSequence tokens{dir, allSources_.AddCompilerInsertion(dir).start()};
109-
tokens.Emit(cooked_);
110-
}
100+
inFixedForm_ = beganInFixedForm;
111101
}
112102

113103
void Prescanner::Statement() {
@@ -324,10 +314,11 @@ void Prescanner::Statement() {
324314
}
325315
NormalizeCompilerDirectiveCommentMarker(*preprocessed);
326316
preprocessed->ToLowerCase();
327-
SourceFormChange(preprocessed->ToString());
328-
CheckAndEmitLine(
329-
preprocessed->ClipComment(*this, true /* skip first ! */),
330-
newlineProvenance);
317+
if (!SourceFormChange(preprocessed->ToString())) {
318+
CheckAndEmitLine(
319+
preprocessed->ClipComment(*this, true /* skip first ! */),
320+
newlineProvenance);
321+
}
331322
break;
332323
case LineClassification::Kind::Source:
333324
if (inFixedForm_) {
@@ -370,14 +361,16 @@ void Prescanner::Statement() {
370361
}
371362
}
372363
tokens.ToLowerCase();
373-
SourceFormChange(tokens.ToString());
364+
if (!SourceFormChange(tokens.ToString())) {
365+
CheckAndEmitLine(tokens, newlineProvenance);
366+
}
374367
} else { // Kind::Source
375368
tokens.ToLowerCase();
376369
if (inFixedForm_) {
377370
EnforceStupidEndStatementRules(tokens);
378371
}
372+
CheckAndEmitLine(tokens, newlineProvenance);
379373
}
380-
CheckAndEmitLine(tokens, newlineProvenance);
381374
}
382375
directiveSentinel_ = nullptr;
383376
}
@@ -1774,11 +1767,15 @@ Prescanner::LineClassification Prescanner::ClassifyLine(
17741767
return classification;
17751768
}
17761769

1777-
void Prescanner::SourceFormChange(std::string &&dir) {
1770+
bool Prescanner::SourceFormChange(std::string &&dir) {
17781771
if (dir == "!dir$ free") {
17791772
inFixedForm_ = false;
1773+
return true;
17801774
} else if (dir == "!dir$ fixed") {
17811775
inFixedForm_ = true;
1776+
return true;
1777+
} else {
1778+
return false;
17821779
}
17831780
}
17841781

flang/lib/Parser/prescan.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ class Prescanner {
225225
LineClassification ClassifyLine(const char *) const;
226226
LineClassification ClassifyLine(
227227
TokenSequence &, Provenance newlineProvenance) const;
228-
void SourceFormChange(std::string &&);
228+
bool SourceFormChange(std::string &&);
229229
bool CompilerDirectiveContinuation(TokenSequence &, const char *sentinel);
230230
bool SourceLineContinuation(TokenSequence &);
231231

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!RUN: %flang -E %s 2>&1 | FileCheck %s
2+
!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
3+
!CHECK-NOT: dir$
4+
!CHECK-NOT: error:
5+
!dir$ fixed
6+
continue
7+
!dir$ free
8+
end

0 commit comments

Comments
 (0)