[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