diff options
author | Peter Klausler <35819229+klausler@users.noreply.github.com> | 2023-10-31 12:35:01 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-31 12:35:01 -0700 |
commit | 297230acdadd667fda379debd7dda20ace4f7213 (patch) | |
tree | f7aaa8eb64ef2eeb5780cd2df0daed7696475406 /flang/lib/Parser/token-sequence.cpp | |
parent | 2d4ada215ebb3062947c399cf20d386aa78619a6 (diff) | |
download | llvm-297230acdadd667fda379debd7dda20ace4f7213.zip llvm-297230acdadd667fda379debd7dda20ace4f7213.tar.gz llvm-297230acdadd667fda379debd7dda20ace4f7213.tar.bz2 |
[flang] Accept directive sentinels in macro-replaced source better (#70699)
At present, the prescanner emits an error if a source line or compiler
directive, after macro replacement or not, contains a token with a
non-Fortran character. In the particular case of the '!' character, the
code that checks for bad character will accept the '!' if it appears
after a ';', since the '!' might begin a compiler directive.
This current implementation fails when a compiler directive appears
after some other character that might (by means of further source
processing not visible to the prescanner) be replaced with a ';' or
newline.
Extend the bad character check for '!' to actually check for a compiler
directive sentinel instead.
Diffstat (limited to 'flang/lib/Parser/token-sequence.cpp')
-rw-r--r-- | flang/lib/Parser/token-sequence.cpp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/flang/lib/Parser/token-sequence.cpp b/flang/lib/Parser/token-sequence.cpp index 139d2e1..c5a630c 100644 --- a/flang/lib/Parser/token-sequence.cpp +++ b/flang/lib/Parser/token-sequence.cpp @@ -343,16 +343,23 @@ ProvenanceRange TokenSequence::GetProvenanceRange() const { } const TokenSequence &TokenSequence::CheckBadFortranCharacters( - Messages &messages) const { + Messages &messages, const Prescanner &prescanner) const { std::size_t tokens{SizeInTokens()}; - bool isBangOk{true}; for (std::size_t j{0}; j < tokens; ++j) { CharBlock token{TokenAt(j)}; char ch{token.FirstNonBlank()}; if (ch != ' ' && !IsValidFortranTokenCharacter(ch)) { - if (ch == '!' && isBangOk) { - // allow in !dir$ - } else if (ch < ' ' || ch >= '\x7f') { + if (ch == '!') { + if (prescanner.IsCompilerDirectiveSentinel(token)) { + continue; + } else if (j + 1 < tokens && + prescanner.IsCompilerDirectiveSentinel( + TokenAt(j + 1))) { // !dir$, &c. + ++j; + continue; + } + } + if (ch < ' ' || ch >= '\x7f') { messages.Say(GetTokenProvenanceRange(j), "bad character (0x%02x) in Fortran token"_err_en_US, ch & 0xff); } else { @@ -360,11 +367,6 @@ const TokenSequence &TokenSequence::CheckBadFortranCharacters( "bad character ('%c') in Fortran token"_err_en_US, ch); } } - if (ch == ';') { - isBangOk = true; - } else if (ch != ' ') { - isBangOk = false; - } } return *this; } |