[flang-commits] [flang] 73a0ae0 - [flang] Fix looping on LEN type parameter usage

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Jun 22 07:05:39 PDT 2023


Author: Peter Klausler
Date: 2023-06-22T07:05:33-07:00
New Revision: 73a0ae021ec6112911b98025055b8a2e881b1376

URL: https://github.com/llvm/llvm-project/commit/73a0ae021ec6112911b98025055b8a2e881b1376
DIFF: https://github.com/llvm/llvm-project/commit/73a0ae021ec6112911b98025055b8a2e881b1376.diff

LOG: [flang] Fix looping on LEN type parameter usage

When a LEN type parameter of one PDT is being used as the value
of a LEN type parameter in another PDT, expression rewriting can
loop infinitely due to an incorrect assumption that the same PDT's
parameters are being referenced.

Fixes LLVM bug https://github.com/llvm/llvm-project/issues/63198

Differential Revision: https://reviews.llvm.org/D153465

Added: 
    flang/test/Semantics/pdt01.f90

Modified: 
    flang/include/flang/Evaluate/common.h
    flang/lib/Evaluate/fold-integer.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Evaluate/common.h b/flang/include/flang/Evaluate/common.h
index 251444d05bab3..d05072742a48c 100644
--- a/flang/include/flang/Evaluate/common.h
+++ b/flang/include/flang/Evaluate/common.h
@@ -260,6 +260,9 @@ class FoldingContext {
       const semantics::DerivedTypeSpec &spec) {
     return common::ScopedSet(pdtInstance_, &spec);
   }
+  common::Restorer<const semantics::DerivedTypeSpec *> WithoutPDTInstance() {
+    return common::ScopedSet(pdtInstance_, nullptr);
+  }
 
 private:
   parser::ContextualMessages messages_;

diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 601fa729980e6..acfa64ac40e63 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -1269,10 +1269,11 @@ Expr<TypeParamInquiry::Result> FoldOperation(
     }
   } else {
     // A "bare" type parameter: replace with its value, if that's now known
-    // in a current derived type instantiation, for KIND type parameters.
+    // in a current derived type instantiation.
     if (const auto *pdt{context.pdtInstance()}) {
+      auto restorer{context.WithoutPDTInstance()}; // don't loop
       bool isLen{false};
-      if (const semantics::Scope * scope{context.pdtInstance()->scope()}) {
+      if (const semantics::Scope * scope{pdt->scope()}) {
         auto iter{scope->find(parameterName)};
         if (iter != scope->end()) {
           const Symbol &symbol{*iter->second};

diff  --git a/flang/test/Semantics/pdt01.f90 b/flang/test/Semantics/pdt01.f90
new file mode 100644
index 0000000000000..09edd9bce82c7
--- /dev/null
+++ b/flang/test/Semantics/pdt01.f90
@@ -0,0 +1,16 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1
+! Catch error instead of crashing with infinite recursion
+! when a LEN PDT from one type is being used to define a
+! LEN PDT in another type's instantiation.
+program main
+  type t1(lp)
+    integer, len :: lp
+  end type
+  type t2(lp)
+    integer, len :: lp
+    type(t1(lp)) :: c
+  end type
+  integer local
+  !ERROR: Invalid specification expression: reference to local entity 'local'
+  type(t2(local)) :: x
+end


        


More information about the flang-commits mailing list