summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Morin <mikael@gcc.gnu.org>2022-01-28 21:00:57 (GMT)
committerMikael Morin <mikael@gcc.gnu.org>2022-02-13 15:46:46 (GMT)
commit57da34939703a6e6d3267a0d25d1fb9369d3ac0e (patch)
tree980531df7698c39dd08c736aa5f60f7bc7f4c9b4
parent7e204bd2f189850cb940677c99d8d93eb7dd40cd (diff)
downloadgcc-57da34939703a6e6d3267a0d25d1fb9369d3ac0e.zip
gcc-57da34939703a6e6d3267a0d25d1fb9369d3ac0e.tar.gz
gcc-57da34939703a6e6d3267a0d25d1fb9369d3ac0e.tar.bz2
fortran: Unshare associate var charlen [PR104228]
PR104228 showed that character lengths were shared between associate variable and associate targets. This is problematic when the associate target is itself a variable and gets a variable to hold the length, as the length variable is added (and all the variables following it in the chain) to both the associate variable scope and the target variable scope. This caused an ICE when compiling with -O0 -fsanitize=address. This change forces the creation of a separate character length for the associate variable. It also forces the initialization of the character length variable to avoid regressing associate_32 and associate_47 tests. PR fortran/104228 gcc/fortran/ChangeLog: * resolve.cc (resolve_assoc_var): Also create a new character length for non-dummy associate targets. * trans-stmt.cc (trans_associate_var): Initialize character length even if no temporary is used for the associate variable. gcc/testsuite/ChangeLog: * gfortran.dg/asan/associate_58.f90: New test. * gfortran.dg/asan/associate_59.f90: New test.
-rw-r--r--gcc/fortran/resolve.cc1
-rw-r--r--gcc/fortran/trans-stmt.cc2
-rw-r--r--gcc/testsuite/gfortran.dg/asan/associate_58.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/asan/associate_59.f9019
4 files changed, 39 insertions, 2 deletions
diff --git a/gcc/fortran/resolve.cc b/gcc/fortran/resolve.cc
index 835a478..266e41e 100644
--- a/gcc/fortran/resolve.cc
+++ b/gcc/fortran/resolve.cc
@@ -9227,7 +9227,6 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
sym->ts.u.cl = target->ts.u.cl;
if (sym->ts.deferred && target->expr_type == EXPR_VARIABLE
- && target->symtree->n.sym->attr.dummy
&& sym->ts.u.cl == target->ts.u.cl)
{
sym->ts.u.cl = gfc_new_charlen (sym->ns, NULL);
diff --git a/gcc/fortran/trans-stmt.cc b/gcc/fortran/trans-stmt.cc
index 04f8147..30b6bd5 100644
--- a/gcc/fortran/trans-stmt.cc
+++ b/gcc/fortran/trans-stmt.cc
@@ -1918,7 +1918,7 @@ trans_associate_var (gfc_symbol *sym, gfc_wrapped_block *block)
gfc_conv_expr_descriptor (&se, e);
if (sym->ts.type == BT_CHARACTER
- && !se.direct_byref && sym->ts.deferred
+ && sym->ts.deferred
&& !sym->attr.select_type_temporary
&& VAR_P (sym->ts.u.cl->backend_decl)
&& se.string_length != sym->ts.u.cl->backend_decl)
diff --git a/gcc/testsuite/gfortran.dg/asan/associate_58.f90 b/gcc/testsuite/gfortran.dg/asan/associate_58.f90
new file mode 100644
index 0000000..b5ea754
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/asan/associate_58.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-additional-options "-O0" }
+!
+! PR fortran/104228
+! The code generated code for the program below wrongly pushed the Y character
+! length variable to both P and S scope, which was leading to an ICE when
+! address sanitizer was in effect
+
+program p
+ character(:), save, allocatable :: x(:)
+ call s
+contains
+ subroutine s
+ associate (y => x)
+ y = [x]
+ end associate
+ end
+end
+
diff --git a/gcc/testsuite/gfortran.dg/asan/associate_59.f90 b/gcc/testsuite/gfortran.dg/asan/associate_59.f90
new file mode 100644
index 0000000..9bfb2bf
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/asan/associate_59.f90
@@ -0,0 +1,19 @@
+! { dg-do compile }
+! { dg-additional-options "-O0" }
+!
+! PR fortran/104228
+! The code generated code for the program below wrongly pushed the Y character
+! length variable to both P and S scope, which was leading to an ICE when
+! address sanitizer was in effect
+
+program p
+ character(:), allocatable :: x(:)
+ call s
+contains
+ subroutine s
+ associate (y => x)
+ y = [x]
+ end associate
+ end
+end
+