aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2024-07-18 08:51:35 +0100
committerPaul Thomas <pault@gcc.gnu.org>2024-07-18 08:51:35 +0100
commitc3aa339ea50f050caf7ed2e497f5499ec2d7b9cc (patch)
treeab5ab5533ae4b1fbfb5b55c6ffdb71c8eb215970 /gcc/fortran
parentcee56fe0ba757cae17dcc4be216cea88be76e740 (diff)
downloadgcc-c3aa339ea50f050caf7ed2e497f5499ec2d7b9cc.zip
gcc-c3aa339ea50f050caf7ed2e497f5499ec2d7b9cc.tar.gz
gcc-c3aa339ea50f050caf7ed2e497f5499ec2d7b9cc.tar.bz2
Fortran: Suppress bogus used uninitialized warnings [PR108889].
2024-07-18 Paul Thomas <pault@gcc.gnu.org> gcc/fortran PR fortran/108889 * gfortran.h: Add bit field 'allocated_in_scope' to gfc_symbol. * trans-array.cc (gfc_array_allocate): Set 'allocated_in_scope' after allocation if not a component reference. (gfc_alloc_allocatable_for_assignment): If 'allocated_in_scope' not set, not a component ref and not allocated, set the array bounds and offset to give zero length in all dimensions. Then set allocated_in_scope. gcc/testsuite/ PR fortran/108889 * gfortran.dg/pr108889.f90: New test.
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/gfortran.h4
-rw-r--r--gcc/fortran/trans-array.cc43
2 files changed, 47 insertions, 0 deletions
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index ed1213a..c1fb896 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -1950,6 +1950,10 @@ typedef struct gfc_symbol
/* Set if this should be passed by value, but is not a VALUE argument
according to the Fortran standard. */
unsigned pass_as_value:1;
+ /* Set if an allocatable array variable has been allocated in the current
+ scope. Used in the suppression of uninitialized warnings in reallocation
+ on assignment. */
+ unsigned allocated_in_scope:1;
/* Reference counter, used for memory management.
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 140d933..6d3b63b 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -6580,6 +6580,8 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg,
else
gfc_add_expr_to_block (&se->pre, set_descriptor);
+ expr->symtree->n.sym->allocated_in_scope = 1;
+
return true;
}
@@ -11060,6 +11062,8 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
stmtblock_t realloc_block;
stmtblock_t alloc_block;
stmtblock_t fblock;
+ stmtblock_t loop_pre_block;
+ gfc_ref *ref;
gfc_ss *rss;
gfc_ss *lss;
gfc_array_info *linfo;
@@ -11260,6 +11264,45 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
array1, build_int_cst (TREE_TYPE (array1), 0));
cond_null= gfc_evaluate_now (cond_null, &fblock);
+ /* If the data is null, set the descriptor bounds and offset. This suppresses
+ the maybe used uninitialized warning and forces the use of malloc because
+ the size is zero in all dimensions. Note that this block is only executed
+ if the lhs is unallocated and is only applied once in any namespace.
+ Component references are not subject to the warnings. */
+ for (ref = expr1->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT)
+ break;
+
+ if (!expr1->symtree->n.sym->allocated_in_scope && !ref)
+ {
+ gfc_start_block (&loop_pre_block);
+ for (n = 0; n < expr1->rank; n++)
+ {
+ gfc_conv_descriptor_lbound_set (&loop_pre_block, desc,
+ gfc_rank_cst[n],
+ gfc_index_one_node);
+ gfc_conv_descriptor_ubound_set (&loop_pre_block, desc,
+ gfc_rank_cst[n],
+ gfc_index_zero_node);
+ gfc_conv_descriptor_stride_set (&loop_pre_block, desc,
+ gfc_rank_cst[n],
+ gfc_index_zero_node);
+ }
+
+ tmp = gfc_conv_descriptor_offset (desc);
+ gfc_add_modify (&loop_pre_block, tmp, gfc_index_zero_node);
+
+ tmp = fold_build2_loc (input_location, EQ_EXPR,
+ logical_type_node, array1,
+ build_int_cst (TREE_TYPE (array1), 0));
+ tmp = build3_v (COND_EXPR, tmp,
+ gfc_finish_block (&loop_pre_block),
+ build_empty_stmt (input_location));
+ gfc_prepend_expr_to_block (&loop->pre, tmp);
+
+ expr1->symtree->n.sym->allocated_in_scope = 1;
+ }
+
tmp = build3_v (COND_EXPR, cond_null,
build1_v (GOTO_EXPR, jump_label1),
build_empty_stmt (input_location));