Skip to content

[flang] Don't tokenize an exponent that isn't one #117061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 21, 2024

Conversation

klausler
Copy link
Contributor

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 #115676.

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 llvm#115676.
@klausler klausler requested a review from vdonaldson November 20, 2024 21:37
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:parser labels Nov 20, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2024

@llvm/pr-subscribers-flang-parser

Author: Peter Klausler (klausler)

Changes

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 #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 --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

@klausler klausler merged commit bb23ac6 into llvm:main Nov 21, 2024
11 checks passed
@klausler klausler deleted the bug115676 branch November 21, 2024 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:parser flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Flang] Preprocessor does not work correctly in if statement
3 participants