Dear All, This patch introduces an error if the to and from arguments of move_alloc contain the same object or its subobjects. Please see the comment in the testcase for an explanation and the link to the clf discussion.
Bootstraps and regtests on FC21/x86_64 - OK for trunk? Paul 2016-11-05 Paul Thomas <pa...@gcc.gnu.org> * check.c (gfc_check_move_alloc): Introduce error to prevent aliasing between to and from arguments. 2016-11-05 Paul Thomas <pa...@gcc.gnu.org> * gfortran.dg/move_alloc_17.f03: New test.
Index: gcc/fortran/check.c =================================================================== *** gcc/fortran/check.c (revision 241868) --- gcc/fortran/check.c (working copy) *************** gfc_check_move_alloc (gfc_expr *from, gf *** 3342,3347 **** --- 3342,3357 ---- return false; } + /* F2003 12.4.1.7 */ + 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; + } + /* CLASS arguments: Make sure the vtab of from is present. */ if (to->ts.type == BT_CLASS && !UNLIMITED_POLY (from)) gfc_find_vtab (&from->ts); Index: gcc/testsuite/gfortran.dg/move_alloc_17.f90 =================================================================== *** gcc/testsuite/gfortran.dg/move_alloc_17.f90 (revision 0) --- gcc/testsuite/gfortran.dg/move_alloc_17.f90 (working copy) *************** *** 0 **** --- 1,21 ---- + ! { dg-do compile } + ! + ! The call to MOVE_ALLOC below caused a seg fault in runtime. + ! This was discussed in: + ! https://groups.google.com/forum/#!topic/comp.lang.fortran/ZVLqXFYDZ0M + ! Richard Maine proposed that the code violated the restrictions on + ! actual arguments in F2003 12.4.1.7 and so the fix asserts that the + ! TO and FROM arguments cannot be the same object or subobjects thereof. + ! + ! + program test_move_alloc + type :: linked_list + type(linked_list), allocatable :: link + integer :: value + end type linked_list + type(linked_list) :: test + + allocate(test % link) + allocate(test % link % link) + call move_alloc(test % link, test % link % link) ! { dg-error "aliasing restrictions" } + end program test_move_alloc