[flang-commits] [flang] 96aa481 - [flang] Make uninitialized allocatable components explicitly NULL() in structure constructors
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Mar 7 16:41:51 PST 2022
Author: Peter Klausler
Date: 2022-03-07T16:41:38-08:00
New Revision: 96aa48100c0b332b6e6821b664ad2fa5615c976a
URL: https://github.com/llvm/llvm-project/commit/96aa48100c0b332b6e6821b664ad2fa5615c976a
DIFF: https://github.com/llvm/llvm-project/commit/96aa48100c0b332b6e6821b664ad2fa5615c976a.diff
LOG: [flang] Make uninitialized allocatable components explicitly NULL() in structure constructors
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.
Differential Revision: https://reviews.llvm.org/D121162
Added:
flang/test/Semantics/modfile45.f90
Modified:
flang/lib/Evaluate/check-expression.cpp
flang/lib/Semantics/expression.cpp
flang/test/Semantics/oldparam02.f90
Removed:
################################################################################
diff --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index 06be4da621bcd..dd8424e7728df 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -175,6 +175,12 @@ struct IsActuallyConstantHelper {
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);
diff --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 095e191048f2e..2fcc7735c8757 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -1766,7 +1766,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(
*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 @@ MaybeExpr ExpressionAnalyzer::Analyze(
// 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
diff --git a/flang/test/Semantics/modfile45.f90 b/flang/test/Semantics/modfile45.f90
new file mode 100644
index 0000000000000..ff31c809db8e3
--- /dev/null
+++ b/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
diff --git a/flang/test/Semantics/oldparam02.f90 b/flang/test/Semantics/oldparam02.f90
index 4d8746af1b244..d3f56ee8d1d73 100644
--- a/flang/test/Semantics/oldparam02.f90
+++ b/flang/test/Semantics/oldparam02.f90
@@ -12,6 +12,7 @@ subroutine subr(x1,x2,x3,x4,x5)
!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
More information about the flang-commits
mailing list