The following program should print "1", "2". It does so with ifort but with gfortran it prints "1", "0". type t integer :: i end type t type, extends(t) :: t2 integer :: j end type t2 class(t), allocatable :: a allocate(a, source=t2(1,2)) print *,a%i if(a%i /= 1) call abort() select type (a) type is (t2) print *,a%j if(a%j /= 2) call abort() end select end The dump shows that the type is wrong for the assignment: { struct t2 D.1377; struct t2 t2.0; t2.0.t.i = 1; t2.0.j = 2; D.1377 = t2.0; *a.$data = VIEW_CONVERT_EXPR<struct t>(D.1377); }
Certainly mine. I should have thought of this case when fixing PR41581. The cure is for sure: Index: gcc/fortran/trans-stmt.c =================================================================== --- gcc/fortran/trans-stmt.c (Revision 152720) +++ gcc/fortran/trans-stmt.c (Arbeitskopie) @@ -4091,6 +4091,18 @@ gfc_trans_allocate (gfc_code * code) gfc_free_expr (sz); tmp = gfc_build_memcpy_call (dst.expr, src.expr, len.expr); } + else if (al->expr->ts.type == BT_CLASS + && rhs->ts.u.derived != expr->ts.u.derived) + { + gfc_se dst,src; + gfc_init_se (&dst, NULL); + gfc_init_se (&src, NULL); + gfc_conv_expr (&dst, expr); + gfc_conv_expr (&src, rhs); + gfc_add_block_to_block (&block, &src.pre); + tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&rhs->ts)); + tmp = gfc_build_memcpy_call (dst.expr, src.expr, tmp); + } else tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr), rhs, false);
Problem: The patch in comment #1 regresses on class_allocate_1.f03: gfortran-4.5 class_allocate_1.f03 -O1 class_allocate_1.f03: In function ‘MAIN__’: class_allocate_1.f03:57:0: internal compiler error: in tree_annotate_all_with_location, at gimplify.c:892
(In reply to comment #2) > Problem: The patch in comment #1 regresses on class_allocate_1.f03: In addition to this there are two more test cases failing: Native configuration is x86_64-unknown-linux-gnu === gfortran tests === Schedule of variations: unix Running target unix Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target. Using /usr/share/dejagnu/config/unix.exp as generic interface file for target. Using /home/jweil/gcc45/trunk/gcc/testsuite/config/default.exp as tool-and-target-specific interface file. Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/debug/debug.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/dg.exp ... FAIL: gfortran.dg/class_allocate_1.f03 -O1 (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O1 (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -O2 (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O2 (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer -funroll-loops (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer -funroll-loops (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -g (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -O3 -g (test for excess errors) FAIL: gfortran.dg/class_allocate_1.f03 -Os (internal compiler error) FAIL: gfortran.dg/class_allocate_1.f03 -Os (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O0 (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O1 (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O2 (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O3 -fomit-frame-pointer (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O3 -fomit-frame-pointer -funroll-loops (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -O3 -g (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_4.f03 -Os (test for excess errors) FAIL: gfortran.dg/dynamic_dispatch_5.f03 -O (test for excess errors) Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/gomp/gomp.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/graphite/graphite.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/guality/guality.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/lto/lto.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.dg/vect/vect.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.fortran-torture/compile/compile.exp ... Running /home/jweil/gcc45/trunk/gcc/testsuite/gfortran.fortran-torture/execute/execute.exp ... === gfortran Summary === # of expected passes 32786 # of unexpected failures 23 # of expected failures 30 # of unresolved testcases 15 # of unsupported tests 60 /home/jweil/gcc45/build/gcc/testsuite/gfortran/../../gfortran version 4.5.0 20091015 (experimental) [trunk revision 152844] (GCC)
(In reply to comment #3) > In addition to this there are two more test cases failing: Sorry, these were fake (my local source tree was messed up). The only real failure is class_allocate_1.f03, from which one can extract a reduced test case: implicit none type t1 integer :: a end type type, extends(t1) :: t2 integer :: b end type class(t1),pointer :: cp type(t2) :: x allocate(cp, source = x) end which gives the same error at -O1 and above: internal compiler error: in tree_annotate_all_with_location, at gimplify.c:892
(In reply to comment #4) > internal compiler error: in tree_annotate_all_with_location, at gimplify.c:892 This goes away with the following patchlet: Index: gcc/fortran/trans-expr.c =================================================================== --- gcc/fortran/trans-expr.c (Revision 153538) +++ gcc/fortran/trans-expr.c (Arbeitskopie) @@ -4888,7 +4888,10 @@ gfc_build_memcpy_call (tree dst, tree src, tree le /* Construct call to __builtin_memcpy. */ tmp = build_call_expr_loc (input_location, built_in_decls[BUILT_IN_MEMCPY], 3, dst, src, len); - return fold_convert (void_type_node, tmp); + if (TREE_CODE (tmp) == NOP_EXPR) + return tmp; + else + return fold_convert (void_type_node, tmp); } The source of the problem was that the memcpy call (void) __builtin_memcpy ((void *) cp.$data, (void *) &x, 8); is being replaced at -O1 by: (*(struct t2 * {ref-all}) SAVE_EXPR <cp.$data> = x;, (void *) SAVE_EXPR <cp.$data>;); which 'gfc_build_memcpy_call' was not able to cope with. I.e. the 'fold_convert' would produce an COMPOUND_EXPR, which later on would trigger the error in 'tree_annotate_all_with_location'.
The patches in comment #1 and #5 seem to work as advertized (currently regtesting). After having looked at the f2003 standard draft, I understand that allocate(a, source=t2(1,2)) is equivalent to allocate(t2::a) a%i=1 a%j=2 With this change the compilation fails with: pr41714_db.f90:12.3: a%j=2 1 Error: 'j' at (1) is not a member of the 't' structure Did I missed something in the standard or is this a bug?
(In reply to comment #6) > Did I missed something in the standard or is this a bug? Probably the former!-(If I move a%j=2 inside the "type is (t2)" block, the code compiles without error).
Subject: Bug 41714 Author: janus Date: Mon Oct 26 09:08:03 2009 New Revision: 153547 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153547 Log: 2009-10-26 Janus Weil <janus@gcc.gnu.org> PR fortran/41714 * gimple.h (tree_annotate_all_with_location): Remove prototype. * gimplify.c (tree_should_carry_location_p, tree_annotate_one_with_location,tree_annotate_all_with_location): Remove obsolete functions. 2009-10-26 Janus Weil <janus@gcc.gnu.org> PR fortran/41714 * trans.c (gfc_trans_code): Remove call to 'tree_annotate_all_with_location'. Location should already be set. * trans-openmp.c (gfc_trans_omp_workshare): Ditto. * trans-stmt.c (gfc_trans_allocate): Do correct data initialization for CLASS variables with SOURCE tag, plus some cleanup. 2009-10-26 Janus Weil <janus@gcc.gnu.org> PR fortran/41714 * gfortran.dg/class_allocate_4.f03: New test. Added: trunk/gcc/testsuite/gfortran.dg/class_allocate_4.f03 Modified: trunk/gcc/ChangeLog trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-openmp.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/fortran/trans.c trunk/gcc/gimple.h trunk/gcc/gimplify.c trunk/gcc/testsuite/ChangeLog
Fixed with r153547. Closing.