[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