[flang] Preserve useResultSymbolShape_ option when folding array constructor shape
authorJean Perier <jperier@nvidia.com>
Fri, 24 Feb 2023 08:06:14 +0000 (09:06 +0100)
committerJean Perier <jperier@nvidia.com>
Fri, 24 Feb 2023 08:06:30 +0000 (09:06 +0100)
By default evaluate::GetShape(expr) may return a compiler generated expression
using symbols that are part of function interfaces if there are function
references in "expr".
It is not right to replace an inquiry of "expr" with such compiler
generated expression since the call context would be lost, along with
the meaning of the inquiry expression.
Inquiry folding uses GetContextFreeShape(expr) that sets-up
useResultSymbolShape_ in GetShapeHelper to prevent such bad rewrites. But this did not
work properly with array constructor: GetShapeHelper made a call to
GetShape, ignoring and losing the "useResultSymbolShape_" instruction.

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

flang/include/flang/Evaluate/shape.h
flang/test/Evaluate/rewrite01.f90

index 9183c7d..0539d8f 100644 (file)
@@ -168,8 +168,9 @@ private:
     return common::visit(
         common::visitors{
             [&](const Expr<T> &x) -> MaybeExtentExpr {
-              if (auto xShape{
-                      context_ ? GetShape(*context_, x) : GetShape(x)}) {
+              if (auto xShape{!useResultSymbolShape_ ? (*this)(x)
+                          : context_                 ? GetShape(*context_, x)
+                                                     : GetShape(x)}) {
                 // Array values in array constructors get linearized.
                 return GetSize(std::move(*xShape));
               } else {
index d841699..e971ff2 100644 (file)
@@ -195,4 +195,15 @@ subroutine associate_tests(p)
   end associate
 end subroutine
 
+!CHECK-LABEL: array_constructor
+subroutine array_constructor()
+  interface
+    function return_allocatable()
+     real, allocatable :: return_allocatable(:)
+    end function
+  end interface
+  !CHECK: PRINT *, size([REAL(4)::return_allocatable(),return_allocatable()])
+  print *, size([return_allocatable(), return_allocatable()])
+end subroutine
+
 end module