[flang-commits] [flang] bb23ac6 - [flang] Don't tokenize an exponent that isn't one (#117061)
via flang-commits
flang-commits at lists.llvm.org
Thu Nov 21 10:48:57 PST 2024
Author: Peter Klausler
Date: 2024-11-21T10:48:53-08:00
New Revision: bb23ac65a1e25747231a10240e78c7ce336602bf
URL: https://github.com/llvm/llvm-project/commit/bb23ac65a1e25747231a10240e78c7ce336602bf
DIFF: https://github.com/llvm/llvm-project/commit/bb23ac65a1e25747231a10240e78c7ce336602bf.diff
LOG: [flang] Don't tokenize an exponent that isn't one (#117061)
The character 'e' or 'd' (either case) shouldn't be tokenized as part of
a real literal during preprocessing if it is not followed by an
optionally-signed digit string. Doing so prevents it from being
recognized as a macro name, or as the start of one.
Fixes https://github.com/llvm/llvm-project/issues/115676.
Added:
flang/test/Preprocessing/not-an-exponent.F90
Modified:
flang/lib/Parser/prescan.cpp
Removed:
################################################################################
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index b1206c9c09319b..34e660f8d26646 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -820,18 +820,33 @@ bool Prescanner::ExponentAndKind(TokenSequence &tokens) {
if (ed != 'e' && ed != 'd') {
return false;
}
- EmitCharAndAdvance(tokens, ed);
- if (*at_ == '+' || *at_ == '-') {
- EmitCharAndAdvance(tokens, *at_);
+ // Do some look-ahead to ensure that this 'e'/'d' is an exponent,
+ // not the start of an identifier that could be a macro.
+ const char *p{at_};
+ if (int n{IsSpace(++p)}) {
+ p += n;
}
- while (IsDecimalDigit(*at_)) {
- EmitCharAndAdvance(tokens, *at_);
+ if (*p == '+' || *p == '-') {
+ if (int n{IsSpace(++p)}) {
+ p += n;
+ }
}
- if (*at_ == '_') {
- while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
+ if (IsDecimalDigit(*p)) { // it's an exponent
+ EmitCharAndAdvance(tokens, ed);
+ if (*at_ == '+' || *at_ == '-') {
+ EmitCharAndAdvance(tokens, *at_);
+ }
+ while (IsDecimalDigit(*at_)) {
+ EmitCharAndAdvance(tokens, *at_);
}
+ if (*at_ == '_') {
+ while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
+ }
+ }
+ return true;
+ } else {
+ return false;
}
- return true;
}
void Prescanner::QuotedCharacterLiteral(
diff --git a/flang/test/Preprocessing/not-an-exponent.F90 b/flang/test/Preprocessing/not-an-exponent.F90
new file mode 100644
index 00000000000000..d60d7f6c409f0e
--- /dev/null
+++ b/flang/test/Preprocessing/not-an-exponent.F90
@@ -0,0 +1,24 @@
+!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s
+#define e eeeee
+module m
+ interface operator(.e.)
+ module procedure ir,rr
+ end interface operator(.e.)
+contains
+ function ir(k1,k2)
+ intent(in)::k1,k2
+ ir=k1+k2
+ end function ir
+ function rr(k1,k2)
+ real,intent(in)::k1,k2
+ rr=k1+k2
+ end function rr
+end module m
+program main
+ use m
+!CHECK: IF (real((ir(1_4,5_4)),kind=4)/=6._4) ERROR STOP 1_4
+!CHECK: IF ((rr(1._4,5.e-1_4))/=1.5_4) ERROR STOP 2_4
+ if((1.e.5)/=6.e0) error stop 1
+ if((1..e..5)/=1.5) error stop 2
+ print *,'pass'
+end program main
More information about the flang-commits
mailing list