aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Parser/token-sequence.cpp
diff options
context:
space:
mode:
authorPeter Klausler <35819229+klausler@users.noreply.github.com>2023-10-31 12:35:01 -0700
committerGitHub <noreply@github.com>2023-10-31 12:35:01 -0700
commit297230acdadd667fda379debd7dda20ace4f7213 (patch)
treef7aaa8eb64ef2eeb5780cd2df0daed7696475406 /flang/lib/Parser/token-sequence.cpp
parent2d4ada215ebb3062947c399cf20d386aa78619a6 (diff)
downloadllvm-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.cpp22
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;
}