[flang-commits] [flang] c8b50b8 - [flang] Prevent character length setting with dangling ac-do-variable.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Mon May 8 16:57:17 PDT 2023


Author: Slava Zakharin
Date: 2023-05-08T16:57:07-07:00
New Revision: c8b50b860068bb9116c17ad3d8b616285eb68c71

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

LOG: [flang] Prevent character length setting with dangling ac-do-variable.

This fixes LEN inquiry on array constructors where the length
expression includes references to the ac-do-variable.

Reviewed By: klausler

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

Added: 
    

Modified: 
    flang/lib/Semantics/expression.cpp
    flang/test/Evaluate/rewrite01.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 1440147feecdf..6047f8da441b1 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1475,7 +1475,20 @@ class ArrayConstructorContext {
         ArrayConstructor<T> result{MakeSpecific<T>(std::move(values_))};
         if constexpr (T::category == TypeCategory::Character) {
           if (auto len{type_->LEN()}) {
-            if (IsConstantExpr(*len)) {
+            // The ac-do-variables may be treated as constant expressions,
+            // if some conditions on ac-implied-do-control hold (10.1.12 (12)).
+            // At the same time, they may be treated as constant expressions
+            // only in the context of the ac-implied-do, but setting
+            // the character length here may result in complete elimination
+            // of the ac-implied-do. For example:
+            //   character(10) :: c
+            //   ... len([(c(i:i), integer(8)::i = 1,4)])
+            // would be evaulated into:
+            //   ... int(max(0_8,i-i+1_8),kind=4)
+            // with a dangling reference to the ac-do-variable.
+            // Prevent this by checking for the ac-do-variable references
+            // in the 'len' expression.
+            if (!ContainsAnyImpliedDoIndex(*len) && IsConstantExpr(*len)) {
               result.set_LEN(std::move(*len));
             }
           }

diff  --git a/flang/test/Evaluate/rewrite01.f90 b/flang/test/Evaluate/rewrite01.f90
index cbcbfb97189c7..0fa3581a3799f 100644
--- a/flang/test/Evaluate/rewrite01.f90
+++ b/flang/test/Evaluate/rewrite01.f90
@@ -234,10 +234,13 @@ function return_allocatable()
 subroutine array_ctor_implied_do_index(x, j)
   integer :: x(:)
   integer(8) :: j
+  character(10) :: c
   !CHECK: PRINT *, size([INTEGER(4)::(x(1_8:i:1_8),INTEGER(8)::i=1_8,2_8,1_8)])
   print *, size([(x(1:i), integer(8)::i=1,2)])
   !CHECK: PRINT *, int(0_8+2_8*(0_8+max((j-1_8+1_8)/1_8,0_8)),kind=4)
   print *, size([(x(1:j), integer(8)::i=1,2)])
+  !CHECK: PRINT *, len([(c(i:i),INTEGER(8)::i=1_8,4_8,1_8)])
+  print *, len([(c(i:i), integer(8)::i = 1,4)])
 end subroutine
 
 end module


        


More information about the flang-commits mailing list