[flang-commits] [flang] [flang] Don't tokenize an exponent that isn't one (PR #117061)
via flang-commits
flang-commits at lists.llvm.org
Wed Nov 20 13:38:25 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-parser
Author: Peter Klausler (klausler)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/117061.diff
2 Files Affected:
- (modified) flang/lib/Parser/prescan.cpp (+23-8)
- (added) flang/test/Preprocessing/not-an-exponent.F90 (+24)
``````````diff
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index 1d2f1e97668792..e4e52345e40dc6 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -815,18 +815,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
``````````
</details>
https://github.com/llvm/llvm-project/pull/117061
More information about the flang-commits
mailing list