[flang-commits] [flang] beb437e - [flang] Don't crash in error recovery situation

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Tue Aug 8 11:14:29 PDT 2023


Author: Peter Klausler
Date: 2023-08-08T11:14:24-07:00
New Revision: beb437ed7e2b0eba1395a590115a6ade083f2f85

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

LOG: [flang] Don't crash in error recovery situation

When folding the TRANSFER() intrinsic function, there's a CHECK()
that the initial image was built without error.  However, there is one
condition that elicits a warning -- a derived type SOURCE= with an
allocatable or dynamic component.  Remove this CHECK().

Fixes llvm-test-suite/Fortran/gfortran/regression/transfer_null_1.f90.

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

Added: 
    

Modified: 
    flang/include/flang/Evaluate/initial-image.h
    flang/lib/Evaluate/fold.cpp
    flang/lib/Evaluate/initial-image.cpp
    flang/test/Semantics/null01.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Evaluate/initial-image.h b/flang/include/flang/Evaluate/initial-image.h
index 7cf01a85ba4b09..7c8f986f853a34 100644
--- a/flang/include/flang/Evaluate/initial-image.h
+++ b/flang/include/flang/Evaluate/initial-image.h
@@ -22,12 +22,7 @@ namespace Fortran::evaluate {
 
 class InitialImage {
 public:
-  enum Result {
-    Ok,
-    NotAConstant,
-    OutOfRange,
-    SizeMismatch,
-  };
+  enum Result { Ok, NotAConstant, OutOfRange, SizeMismatch };
 
   explicit InitialImage(std::size_t bytes) : data_(bytes) {}
   InitialImage(InitialImage &&that) = default;

diff  --git a/flang/lib/Evaluate/fold.cpp b/flang/lib/Evaluate/fold.cpp
index 0c5d2c24079c83..dfcc2599a555e5 100644
--- a/flang/lib/Evaluate/fold.cpp
+++ b/flang/lib/Evaluate/fold.cpp
@@ -275,11 +275,15 @@ std::optional<Expr<SomeType>> FoldTransfer(
     if (totalBytes < std::size_t{1000000} &&
         (elements == 0 || totalBytes / elements == *sourceBytes)) {
       InitialImage image{*sourceBytes};
-      InitialImage::Result imageResult{
-          image.Add(0, *sourceBytes, *source, context)};
-      CHECK(imageResult == InitialImage::Ok);
-      return image.AsConstant(
-          context, *moldType, moldLength, *extents, true /*pad with 0*/);
+      auto status{image.Add(0, *sourceBytes, *source, context)};
+      if (status == InitialImage::Ok) {
+        return image.AsConstant(
+            context, *moldType, moldLength, *extents, true /*pad with 0*/);
+      } else {
+        // Can fail due to an allocatable or automatic component;
+        // a warning will also have been produced.
+        CHECK(status == InitialImage::NotAConstant);
+      }
     }
   }
   return std::nullopt;

diff  --git a/flang/lib/Evaluate/initial-image.cpp b/flang/lib/Evaluate/initial-image.cpp
index a5f77a603ddb4e..a0fe4ec95da94d 100644
--- a/flang/lib/Evaluate/initial-image.cpp
+++ b/flang/lib/Evaluate/initial-image.cpp
@@ -35,12 +35,10 @@ auto InitialImage::Add(ConstantSubscript offset, std::size_t bytes,
             AddPointer(offset + component.offset(), indExpr.value());
           } else if (IsAllocatable(component) || IsAutomatic(component)) {
             return NotAConstant;
-          } else {
-            Result added{Add(offset + component.offset(), component.size(),
-                indExpr.value(), context)};
-            if (added != Ok) {
-              return added;
-            }
+          } else if (auto result{Add(offset + component.offset(),
+                         component.size(), indExpr.value(), context)};
+                     result != Ok) {
+            return result;
           }
         }
         offset += elementBytes;

diff  --git a/flang/test/Semantics/null01.f90 b/flang/test/Semantics/null01.f90
index c56701004f77a8..02a68147a7527a 100644
--- a/flang/test/Semantics/null01.f90
+++ b/flang/test/Semantics/null01.f90
@@ -1,4 +1,4 @@
-! RUN: %python %S/test_errors.py %s %flang_fc1
+! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
 ! NULL() intrinsic function error tests
 
 subroutine test
@@ -103,6 +103,8 @@ function f3()
   print *, sin(null(rp0))
   !ERROR: A NULL() pointer is not allowed for 'source=' intrinsic argument
   print *, transfer(null(rp0),ip0)
+  !WARNING: Source of TRANSFER contains allocatable or pointer component %ra0
+  print *, transfer(dt4(null()),[0])
   !ERROR: NULL() may not be used as an expression in this context
   select case(null(ip0))
   end select


        


More information about the flang-commits mailing list