[flang-commits] [PATCH] D121162: [flang] Make uninitialized allocatable components explicitly NULL() in structure constructors

Peter Klausler via Phabricator via flang-commits flang-commits at lists.llvm.org
Mon Mar 7 13:54:48 PST 2022


klausler created this revision.
klausler added a reviewer: vdonaldson.
klausler added a project: Flang.
Herald added a subscriber: jdoerfert.
Herald added a reviewer: sscalpone.
Herald added a project: All.
klausler requested review of this revision.

When a structure constructor does not initialize an allocatable component,
ensure that the typed expression representation contains an explicit
NULL() for the component.  Expression semantics already copies default
initialized expressions for nonallocatable components into structure
constructors.  This change is expected to simplify lowering.


https://reviews.llvm.org/D121162

Files:
  flang/lib/Evaluate/check-expression.cpp
  flang/lib/Semantics/expression.cpp
  flang/test/Semantics/modfile45.f90
  flang/test/Semantics/oldparam02.f90


Index: flang/test/Semantics/oldparam02.f90
===================================================================
--- flang/test/Semantics/oldparam02.f90
+++ flang/test/Semantics/oldparam02.f90
@@ -12,6 +12,7 @@
   !CHECK: error: Must be a constant value
   parameter p2 = x2
   !CHECK: error: Whole assumed-size array 'x3' may not appear here without subscripts
+  !CHECK: error: Must be a constant value
   parameter p3 = x3
   !CHECK: error: Must be a constant value
   parameter p4 = x4
Index: flang/test/Semantics/modfile45.f90
===================================================================
--- /dev/null
+++ flang/test/Semantics/modfile45.f90
@@ -0,0 +1,24 @@
+! RUN: %python %S/test_modfile.py %s %flang_fc1
+! Ensures that uninitialized allocatable components in a structure constructor
+! appear with explicit NULL() in the expression representation.
+module m
+  type t
+    real, allocatable :: x1, x2, x3
+  end type
+  type t2
+    type(t) :: a = t(NULL(),x2=NULL())
+  end type
+end module
+
+!Expect: m.mod
+!module m
+!type::t
+!real(4),allocatable::x1
+!real(4),allocatable::x2
+!real(4),allocatable::x3
+!end type
+!type::t2
+!type(t)::a=t(x1=NULL(),x2=NULL(),x3=NULL())
+!end type
+!intrinsic::null
+!end
Index: flang/lib/Semantics/expression.cpp
===================================================================
--- flang/lib/Semantics/expression.cpp
+++ flang/lib/Semantics/expression.cpp
@@ -1766,7 +1766,8 @@
                 *symbol);
           }
         } else if (IsAllocatable(*symbol) && IsBareNullPointer(&*value)) {
-          // NULL() with no arguments allowed by 7.5.10 para 6 for ALLOCATABLE
+          // NULL() with no arguments allowed by 7.5.10 para 6 for ALLOCATABLE.
+          result.Add(*symbol, Expr<SomeType>{NullPointer{}});
         } else if (auto symType{DynamicType::From(symbol)}) {
           if (IsAllocatable(*symbol) && symType->IsUnlimitedPolymorphic() &&
               valueType) {
@@ -1795,10 +1796,12 @@
   // Ensure that unmentioned component objects have default initializers.
   for (const Symbol &symbol : components) {
     if (!symbol.test(Symbol::Flag::ParentComp) &&
-        unavailable.find(symbol.name()) == unavailable.cend() &&
-        !IsAllocatable(symbol)) {
-      if (const auto *details{
-              symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
+        unavailable.find(symbol.name()) == unavailable.cend()) {
+      if (IsAllocatable(symbol)) {
+        // Set all remaining allocatables to explicit NULL()
+        result.Add(symbol, Expr<SomeType>{NullPointer{}});
+      } else if (const auto *details{
+                     symbol.detailsIf<semantics::ObjectEntityDetails>()}) {
         if (details->init()) {
           result.Add(symbol, common::Clone(*details->init()));
         } else { // C799
Index: flang/lib/Evaluate/check-expression.cpp
===================================================================
--- flang/lib/Evaluate/check-expression.cpp
+++ flang/lib/Evaluate/check-expression.cpp
@@ -175,6 +175,12 @@
   template <typename T> bool operator()(const Expr<T> &x) {
     return std::visit([=](const auto &y) { return (*this)(y); }, x.u);
   }
+  bool operator()(const Expr<SomeType> &x) {
+    if (IsNullPointer(x)) {
+      return true;
+    }
+    return std::visit([this](const auto &y) { return (*this)(y); }, x.u);
+  }
   template <typename A> bool operator()(const A *x) { return x && (*this)(*x); }
   template <typename A> bool operator()(const std::optional<A> &x) {
     return x && (*this)(*x);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D121162.413627.patch
Type: text/x-patch
Size: 3531 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220307/db09eacd/attachment-0001.bin>


More information about the flang-commits mailing list