aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2016-11-09 10:10:41 +0000
committerPaul Thomas <pault@gcc.gnu.org>2016-11-09 10:10:41 +0000
commitbfcb501d83778b8f2b4cc52672b940e62e611e17 (patch)
tree0d8e1de5220e91df46a0b4b6535bac00cdaf549a /gcc
parente15861c2da5fc3b5822eedb8669c7331a6edda00 (diff)
downloadgcc-bfcb501d83778b8f2b4cc52672b940e62e611e17.zip
gcc-bfcb501d83778b8f2b4cc52672b940e62e611e17.tar.gz
gcc-bfcb501d83778b8f2b4cc52672b940e62e611e17.tar.bz2
check.c (gfc_check_move_alloc): Prevent error that avoids aliasing between to and from arguments from rejecting...
2016-11-09 Paul Thomas <pault@gcc.gnu.org> * check.c (gfc_check_move_alloc): Prevent error that avoids aliasing between to and from arguments from rejecting valid code. 2016-11-09 Paul Thomas <pault@gcc.gnu.org> * gfortran.dg/move_alloc_18.f90: New test. From-SVN: r241995
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/check.c42
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/move_alloc_18.f9021
4 files changed, 67 insertions, 6 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 6c39866..bb0beb7 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2016-11-09 Paul Thomas <pault@gcc.gnu.org>
+
+ * check.c (gfc_check_move_alloc): Prevent error that avoids
+ aliasing between to and from arguments from rejecting valid
+ code.
+
2016-11-09 Janus Weil <janus@gcc.gnu.org>
PR fortran/71894
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 142cdac..265fe22 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -3342,14 +3342,44 @@ gfc_check_move_alloc (gfc_expr *from, gfc_expr *to)
return false;
}
- /* F2003 12.4.1.7 */
- if (to->expr_type == EXPR_VARIABLE && from->expr_type ==EXPR_VARIABLE
+ /* This is based losely on F2003 12.4.1.7. It is intended to prevent
+ the likes of to = sym->cmp1->cmp2 and from = sym->cmp1, where cmp1
+ and cmp2 are allocatable. After the allocation is transferred,
+ the 'to' chain is broken by the nullification of the 'from'. A bit
+ of reflection reveals that this can only occur for derived types
+ with recursive allocatable components. */
+ if (to->expr_type == EXPR_VARIABLE && from->expr_type == EXPR_VARIABLE
&& !strcmp (to->symtree->n.sym->name, from->symtree->n.sym->name))
{
- gfc_error ("The FROM and TO arguments at %L are either the same object "
- "or subobjects thereof and so violate aliasing restrictions "
- "(F2003 12.4.1.7)", &to->where);
- return false;
+ gfc_ref *to_ref, *from_ref;
+ to_ref = to->ref;
+ from_ref = from->ref;
+ bool aliasing = true;
+
+ for (; from_ref && to_ref;
+ from_ref = from_ref->next, to_ref = to_ref->next)
+ {
+ if (to_ref->type != from->ref->type)
+ aliasing = false;
+ else if (to_ref->type == REF_ARRAY
+ && to_ref->u.ar.type != AR_FULL
+ && from_ref->u.ar.type != AR_FULL)
+ /* Play safe; assume sections and elements are different. */
+ aliasing = false;
+ else if (to_ref->type == REF_COMPONENT
+ && to_ref->u.c.component != from_ref->u.c.component)
+ aliasing = false;
+
+ if (!aliasing)
+ break;
+ }
+
+ if (aliasing)
+ {
+ gfc_error ("The FROM and TO arguments at %L violate aliasing "
+ "restrictions (F2003 12.4.1.7)", &to->where);
+ return false;
+ }
}
/* CLASS arguments: Make sure the vtab of from is present. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a7e0250..f3438be 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-09 Paul Thomas <pault@gcc.gnu.org>
+
+ * gfortran.dg/move_alloc_18.f90: New test.
+
2016-11-09 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR middle-end/78256
diff --git a/gcc/testsuite/gfortran.dg/move_alloc_18.f90 b/gcc/testsuite/gfortran.dg/move_alloc_18.f90
new file mode 100644
index 0000000..bc72d5d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/move_alloc_18.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+!
+! Test that the anti-aliasing restriction does not knock out valid code.
+!
+! Contributed by Andrew Balwin on
+! https://groups.google.com/forum/#!topic/comp.lang.fortran/oiXdl1LPb_s
+!
+ PROGRAM TEST
+ IMPLICIT NONE
+
+ TYPE FOOBAR
+ INTEGER, ALLOCATABLE :: COMP(:)
+ END TYPE
+
+ TYPE (FOOBAR) :: MY_ARRAY(6)
+
+ ALLOCATE (MY_ARRAY(1)%COMP(10))
+
+ CALL MOVE_ALLOC (MY_ARRAY(1)%COMP, MY_ARRAY(2)%COMP)
+
+ END PROGRAM TEST