]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fortran: Unshare associate var charlen [PR104228]
authorMikael Morin <mikael@gcc.gnu.org>
Fri, 28 Jan 2022 21:00:57 +0000 (22:00 +0100)
committerMikael Morin <mikael@gcc.gnu.org>
Sun, 13 Feb 2022 15:46:46 +0000 (16:46 +0100)
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.

gcc/fortran/resolve.cc
gcc/fortran/trans-stmt.cc
gcc/testsuite/gfortran.dg/asan/associate_58.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/asan/associate_59.f90 [new file with mode: 0644]

index 835a4783718235c926ede81daebfe0242d2af102..266e41e25b199ffcf22881ee037e844546c214d2 100644 (file)
@@ -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);
index 04f8147d23b4f38b278ef8011774bc89d1e88f08..30b6bd5dd2a37acbfea2df5bd9e31b47ee51830e 100644 (file)
@@ -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 (file)
index 0000000..b5ea754
--- /dev/null
@@ -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 (file)
index 0000000..9bfb2bf
--- /dev/null
@@ -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
+