diff options
author | Andre Vehreschild <vehre@gcc.gnu.org> | 2021-06-23 10:09:29 +0200 |
---|---|---|
committer | Andre Vehreschild <vehre@gcc.gnu.org> | 2021-06-23 10:17:14 +0200 |
commit | da13e4ebebb07a47d5fb50eab8893f8fe38683df (patch) | |
tree | be97db67a3e6d107e10b87906ced9b9e6474ba04 /gcc/fortran/trans-intrinsic.c | |
parent | 679506c3830ea1a93c755413609bfac3538e2cbd (diff) | |
download | gcc-da13e4ebebb07a47d5fb50eab8893f8fe38683df.zip gcc-da13e4ebebb07a47d5fb50eab8893f8fe38683df.tar.gz gcc-da13e4ebebb07a47d5fb50eab8893f8fe38683df.tar.bz2 |
fortran: Fix deref of optional in gen. code. [PR100337]
gcc/fortran/ChangeLog:
PR fortran/100337
* trans-intrinsic.c (conv_co_collective): Check stat for null ptr
before dereferrencing.
gcc/testsuite/ChangeLog:
PR fortran/100337
* gfortran.dg/coarray_collectives_17.f90: New test.
Diffstat (limited to 'gcc/fortran/trans-intrinsic.c')
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index e578449..46670ba 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -11242,8 +11242,28 @@ conv_co_collective (gfc_code *code) if (flag_coarray == GFC_FCOARRAY_SINGLE) { if (stat != NULL_TREE) - gfc_add_modify (&block, stat, - fold_convert (TREE_TYPE (stat), integer_zero_node)); + { + /* For optional stats, check the pointer is valid before zero'ing. */ + if (gfc_expr_attr (stat_expr).optional) + { + tree tmp; + stmtblock_t ass_block; + gfc_start_block (&ass_block); + gfc_add_modify (&ass_block, stat, + fold_convert (TREE_TYPE (stat), + integer_zero_node)); + tmp = fold_build2 (NE_EXPR, logical_type_node, + gfc_build_addr_expr (NULL_TREE, stat), + null_pointer_node); + tmp = fold_build3 (COND_EXPR, void_type_node, tmp, + gfc_finish_block (&ass_block), + build_empty_stmt (input_location)); + gfc_add_expr_to_block (&block, tmp); + } + else + gfc_add_modify (&block, stat, + fold_convert (TREE_TYPE (stat), integer_zero_node)); + } return gfc_finish_block (&block); } |