Skip to content

Commit dba757a

Browse files
authored
[flang] Rework preprocessor fix for replacement in kind suffixes (#135406)
Recent work to better handle macro replacement in literal constant kind suffixes isn't handling fixed form well, leading to a crash in Fujitsu test 0113/0113_0073.F. The look-ahead needs to be done with the higher-level prescanner functions that skip over fixed form comment fields after column 72. Rework.
1 parent da6f493 commit dba757a

File tree

2 files changed

+43
-32
lines changed

2 files changed

+43
-32
lines changed

flang/lib/Parser/prescan.cpp

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -891,51 +891,57 @@ bool Prescanner::HandleExponent(TokenSequence &tokens) {
891891
if (char ed{ToLowerCaseLetter(*at_)}; ed == 'e' || ed == 'd') {
892892
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
893893
// not the start of an identifier that could be a macro.
894-
const char *p{SkipWhiteSpace(at_ + 1)};
895-
if (*p == '+' || *p == '-') {
896-
p = SkipWhiteSpace(p + 1);
897-
}
898-
if (IsDecimalDigit(*p)) { // it's an exponent
899-
EmitCharAndAdvance(tokens, ed);
900-
if (*at_ == '+' || *at_ == '-') {
901-
EmitCharAndAdvance(tokens, *at_);
902-
}
894+
const char *startAt{at_};
895+
int startColumn{column_};
896+
TokenSequence possible;
897+
EmitCharAndAdvance(possible, *at_);
898+
if (*at_ == '+' || *at_ == '-') {
899+
EmitCharAndAdvance(possible, *at_);
900+
}
901+
if (IsDecimalDigit(*at_)) { // it's an exponent; scan it
903902
while (IsDecimalDigit(*at_)) {
904-
EmitCharAndAdvance(tokens, *at_);
903+
EmitCharAndAdvance(possible, *at_);
905904
}
905+
possible.CloseToken();
906+
tokens.CloseToken();
907+
tokens.Put(possible);
906908
return true;
907909
}
910+
// Not an exponent; backtrack
911+
at_ = startAt;
912+
column_ = startColumn;
908913
}
909914
return false;
910915
}
911916

912917
bool Prescanner::HandleKindSuffix(TokenSequence &tokens) {
913-
if (*at_ == '_' && IsLegalInIdentifier(at_[1])) {
914-
// The kind specifier might be a macro (with or without its leading
915-
// underscore); put it into its own token if it has been defined.
916-
const char *p{at_ + 1};
917-
while (IsLegalInIdentifier(*++p)) {
918-
}
919-
if (CharBlock id{at_, static_cast<std::size_t>(p - at_)};
920-
preprocessor_.IsNameDefined(id)) {
921-
// In 1.0e0_foo, "_foo" is a defined name; retain the
922-
// underscore
923-
tokens.CloseToken();
924-
} else {
925-
EmitCharAndAdvance(tokens, '_');
926-
if (CharBlock id{at_, static_cast<std::size_t>(p - at_)};
927-
preprocessor_.IsNameDefined(id)) {
928-
// In 1.0e0_foo, "foo" is a defined name
929-
tokens.CloseToken();
930-
}
931-
}
918+
if (*at_ != '_') {
919+
return false;
920+
}
921+
TokenSequence withUnderscore, separate;
922+
EmitChar(withUnderscore, '_');
923+
EmitCharAndAdvance(separate, '_');
924+
if (IsLegalInIdentifier(*at_)) {
925+
separate.CloseToken();
926+
EmitChar(withUnderscore, *at_);
927+
EmitCharAndAdvance(separate, *at_);
932928
while (IsLegalInIdentifier(*at_)) {
933-
EmitCharAndAdvance(tokens, *at_);
929+
EmitChar(withUnderscore, *at_);
930+
EmitCharAndAdvance(separate, *at_);
934931
}
935-
return true;
932+
}
933+
withUnderscore.CloseToken();
934+
separate.CloseToken();
935+
tokens.CloseToken();
936+
if (separate.SizeInTokens() == 2 &&
937+
preprocessor_.IsNameDefined(separate.TokenAt(1)) &&
938+
!preprocessor_.IsNameDefined(withUnderscore.ToCharBlock())) {
939+
// "_foo" is not defined, but "foo" is
940+
tokens.Put(separate); // '_' "foo"
936941
} else {
937-
return false;
942+
tokens.Put(withUnderscore); // "_foo"
938943
}
944+
return true;
939945
}
940946

941947
bool Prescanner::HandleExponentAndOrKindSuffix(TokenSequence &tokens) {

flang/test/Preprocessing/bug518.F

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
! RUN: %flang -fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
2+
! CHECK: k=1_4
3+
k= 1_99999999
4+
&4
5+
end

0 commit comments

Comments
 (0)