aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2020-12-29 17:44:48 +0000
committerPaul Thomas <pault@gcc.gnu.org>2020-12-29 17:44:48 +0000
commiteeb145317b42d5203056851435457d9189a7303d (patch)
treecb2e5812591f450f58c157376d43638c34c5f325
parentfeae0af82753e06fbff6103da5fbb3b28e1ddbd7 (diff)
Fortran: Correct missing structure constructor comps. [PR97612].
2020-12-29 Paul Thomas <pault@gcc.gnu.org> gcc/fortran PR fortran/97612 * primary.c (build_actual_constructor): Missing allocatable components are set unallocated using EXPR_NULL. Then missing components are tested for a default initializer. gcc/testsuite/ PR fortran/97612 * gfortran.dg/structure_constructor_17.f90: New test.
-rw-r--r--gcc/fortran/primary.c32
-rw-r--r--gcc/testsuite/gfortran.dg/structure_constructor_17.f9021
2 files changed, 42 insertions, 11 deletions
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index a58a25924da..93d74737284 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -3003,26 +3003,36 @@ build_actual_constructor (gfc_structure_ctor_component **comp_head,
continue;
}
- /* If it was not found, try the default initializer if there's any;
+ /* If it was not found, apply NULL expression to set the component as
+ unallocated. Then try the default initializer if there's any;
otherwise, it's an error unless this is a deferred parameter. */
if (!comp_iter)
{
- if (comp->initializer)
- {
- if (!gfc_notify_std (GFC_STD_F2003, "Structure constructor "
- "with missing optional arguments at %C"))
- return false;
- value = gfc_copy_expr (comp->initializer);
- }
- else if (comp->attr.allocatable
- || (comp->ts.type == BT_CLASS
- && CLASS_DATA (comp)->attr.allocatable))
+ /* F2018 7.5.10: If an allocatable component has no corresponding
+ component-data-source, then that component has an allocation
+ status of unallocated.... */
+ if (comp->attr.allocatable
+ || (comp->ts.type == BT_CLASS
+ && CLASS_DATA (comp)->attr.allocatable))
{
if (!gfc_notify_std (GFC_STD_F2008, "No initializer for "
"allocatable component %qs given in the "
"structure constructor at %C", comp->name))
return false;
+ value = gfc_get_null_expr (&gfc_current_locus);
+ }
+ /* ....(Preceeding sentence) If a component with default
+ initialization has no corresponding component-data-source, then
+ the default initialization is applied to that component. */
+ else if (comp->initializer)
+ {
+ if (!gfc_notify_std (GFC_STD_F2003, "Structure constructor "
+ "with missing optional arguments at %C"))
+ return false;
+ value = gfc_copy_expr (comp->initializer);
}
+ /* Do not trap components such as the string length for deferred
+ length character components. */
else if (!comp->attr.artificial)
{
gfc_error ("No initializer for component %qs given in the"
diff --git a/gcc/testsuite/gfortran.dg/structure_constructor_17.f90 b/gcc/testsuite/gfortran.dg/structure_constructor_17.f90
new file mode 100644
index 00000000000..8b8230c6f7e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/structure_constructor_17.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+!
+! Test the fix for PR97612.
+!
+! Contributed by Martin Stein <mscfd@gmx.net>
+!
+program constructor_allocatable
+ implicit none
+
+ type :: s
+ integer, dimension(:), allocatable :: u
+ end type s
+
+ type :: t
+ type(s), dimension(:), allocatable :: x
+ end type t
+
+ type(t) :: a = t()
+ if (allocated (a%x)) stop 1
+
+end program constructor_allocatable