This test case: module foo type bar integer :: i contains generic :: assignment (=) => assgn_bar procedure, private :: assgn_bar end type bar contains elemental subroutine assgn_bar (a, b) class (bar), intent (inout) :: a class (bar), intent (in) :: b select type (b) type is (bar) a%i = b%i end select return end subroutine assgn_bar end module foo program main use foo type (bar), allocatable :: foobar(:) allocate (foobar(2)) foobar = [bar(1), bar(2)] end program Gives: gfc init.f90 <During initialization> Error: Non-scalar base object at (1) currently not implemented Not a very helpful message if the error is in a large file. Feedback from help@gfortran.org
(Program compiles with ifort 12, but segfaults at run time.)
Slightly reduced test case: module foo type bar contains generic :: assignment (=) => assgn procedure :: assgn end type contains elemental subroutine assgn (a, b) class (bar), intent (inout) :: a class (bar), intent (in) :: b end subroutine end module use foo type (bar) :: foobar(2) foobar = bar() end
Ok, in fact we just fail to propagate the locus when replacing the assignment with the corresponding type-bound call. The following one-liner fixes it: Index: gcc/fortran/interface.c =================================================================== --- gcc/fortran/interface.c (revision 175100) +++ gcc/fortran/interface.c (working copy) @@ -3242,6 +3242,7 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns) c->expr1 = gfc_get_expr (); build_compcall_for_operator (c->expr1, actual, tb_base, tbo, gname); c->expr1->value.compcall.assign = 1; + c->expr1->where = c->loc; c->expr2 = NULL; c->op = EXEC_COMPCALL; With this one gets the correct error message: foobar = [bar(1), bar(2)] 1 Error: Non-scalar base object at (1) currently not implemented Will commit as obvious after regtesting.
Author: janus Date: Thu Jun 16 21:45:26 2011 New Revision: 175113 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175113 Log: 2011-06-16 Janus Weil <janus@gcc.gnu.org> PR fortran/49074 * interface.c (gfc_extend_assign): Propagate the locus from the assignment to the type-bound procedure call. 2011-06-16 Janus Weil <janus@gcc.gnu.org> PR fortran/49074 * gfortran.dg/typebound_assignment_3.f03: New. Added: trunk/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/interface.c trunk/gcc/testsuite/ChangeLog
r175113 fixes the problem on trunk. Is it worth backporting this to 4.6?
Author: janus Date: Sun Jun 19 21:05:18 2011 New Revision: 175194 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175194 Log: 2011-06-19 Janus Weil <janus@gcc.gnu.org> PR fortran/47601 * module.c (mio_component_ref): Handle components of extended types. * symbol.c (gfc_find_component): Return if sym is NULL. PR fortran/48699 * check.c (gfc_check_move_alloc): If 'TO' argument is polymorphic, make sure the vtab is present. PR fortran/49074 * interface.c (gfc_extend_assign): Propagate the locus from the assignment to the type-bound procedure call. PR fortran/49417 * module.c (mio_component): Make sure the 'class_ok' attribute is set for use-associated CLASS components. * parse.c (parse_derived): Check for 'class_ok' attribute. * resolve.c (resolve_fl_derived): Ditto. 2011-06-19 Janus Weil <janus@gcc.gnu.org> PR fortran/47601 * gfortran.dg/extends_13.f03: New. PR fortran/48699 * gfortran.dg/move_alloc_5.f90: New. PR fortran/49074 * gfortran.dg/typebound_assignment_3.f03: New. PR fortran/49417 * gfortran.dg/class_43.f03: New. Added: branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/class_43.f03 branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/extends_13.f03 branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/move_alloc_5.f90 branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03 Modified: branches/gcc-4_6-branch/gcc/fortran/ChangeLog branches/gcc-4_6-branch/gcc/fortran/check.c branches/gcc-4_6-branch/gcc/fortran/interface.c branches/gcc-4_6-branch/gcc/fortran/module.c branches/gcc-4_6-branch/gcc/fortran/parse.c branches/gcc-4_6-branch/gcc/fortran/resolve.c branches/gcc-4_6-branch/gcc/fortran/symbol.c branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Since the fix is that simple, I decided to backport it. Also, hoping that class arrays will get implemented soon (in 4.7?), the 4.6 branch may be the only place where this patch is really effective. Anyway, Closing.
Author: pault Date: Sun Dec 11 20:42:23 2011 New Revision: 182210 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=182210 Log: 2011-12-11 Paul Thomas <pault@gcc.gnu.org> Tobias Burnus <burnus@gcc.gnu.org> PR fortran/41539 PR fortran/43214 PR fortran/43969 PR fortran/44568 PR fortran/46356 PR fortran/46990 PR fortran/49074 * interface.c(symbol_rank): Return the rank of the _data component of class objects. (compare_parameter): Also compare the derived type of the class _data component for type mismatch. Similarly, return 1 if the formal and _data ranks match. (compare_actual_formal): Do not compare storage sizes for class expressions. It is an error if an actual class array, passed to a formal class array is not full. * trans-expr.c (gfc_class_data_get, gfc_class_vptr_get, gfc_vtable_field_get, gfc_vtable_hash_get, gfc_vtable_size_get, gfc_vtable_extends_get, gfc_vtable_def_init_get, gfc_vtable_copy_get): New functions for class API. (gfc_conv_derived_to_class): For an array reference in an elemental procedure call retain the ss to provide the scalarized array reference. Moved in file. (gfc_conv_class_to_class): New function. (gfc_conv_subref_array_arg): Use the type of the class _data component as a basetype. (gfc_conv_procedure_call): Ensure that class array expressions have both the _data reference and an array reference. Use gfc_conv_class_to_class to handle class arrays for elemental functions in scalarized loops, class array elements and full class arrays. Use a call to gfc_conv_subref_array_arg in order that the copy-in/copy-out for passing class arrays to derived type arrays occurs correctly. (gfc_conv_expr): If it is missing, add the _data component between a class object or component and an array reference. (gfc_trans_class_array_init_assign): New function. (gfc_trans_class_init_assign): Call it for array expressions. * trans-array.c (gfc_add_loop_ss_code): Do not use a temp for class scalars since their size will depend on the dynamic type. (build_class_array_ref): New function. (gfc_conv_scalarized_array_ref): Call build_class_array_ref. (gfc_array_init_size): Add extra argument, expr3, that represents the SOURCE argument. If present,use this for the element size. (gfc_array_allocate): Also add argument expr3 and use it when calling gfc_array_init_size. (structure_alloc_comps): Enable class arrays. * class.c (gfc_add_component_ref): Carry over the derived type of the _data component. (gfc_add_class_array_ref): New function. (class_array_ref_detected): New static function. (gfc_is_class_array_ref): New function that calls previous. (gfc_is_class_scalar_expr): New function. (gfc_build_class_symbol): Throw not implemented error for assumed size class arrays. Remove error that prevents CLASS arrays. (gfc_build_class_symbol): Prevent pointer/allocatable conflict. Also unset codimension. (gfc_find_derived_vtab): Make 'copy' elemental and set the intent of the arguments accordingly.: * trans-array.h : Update prototype for gfc_array_allocate. * array.c (gfc_array_dimen_size): Return failure if class expr. (gfc_array_size): Likewise. * gfortran.h : New prototypes for gfc_add_class_array_ref, gfc_is_class_array_ref and gfc_is_class_scalar_expr. * trans-stmt.c (trans_associate_var): Exclude class targets from test. Move the allocation of the _vptr to an earlier time for class objects. (trans_associate_var): Assign the descriptor directly for class arrays. (gfc_trans_allocate): Add expr3 to gfc_array_allocate arguments. Convert array element references into sections. Do not invoke gfc_conv_procedure_call, use gfc_trans_call instead. * expr.c (gfc_get_corank): Fix for BT_CLASS. (gfc_is_simply_contiguous): Exclude class from test. * trans.c (gfc_build_array_ref): Include class array refs. * trans.h : Include prototypes for class API functions that are new in trans-expr. Define GFC_DECL_CLASS(node). * resolve.c (check_typebound_baseobject ): Remove error for non-scalar base object. (resolve_allocate_expr): Ensure that class _data component is present. If array, call gfc_expr_to_intialize. (resolve_select): Remove scalar error for SELECT statement as a temporary measure. (resolve_assoc_var): Update 'target' (aka 'selector') as needed. Ensure that the target expression has the right rank. (resolve_select_type): Ensure that target expressions have a valid locus. (resolve_allocate_expr, resolve_fl_derived0): Fix for BT_CLASS. * trans-decl.c (gfc_get_symbol_decl): Set GFC_DECL_CLASS, where appropriate. (gfc_trans_deferred_vars): Get class arrays right. * match.c(select_type_set_tmp): Add array spec to temporary. (gfc_match_select_type): Allow class arrays. * check.c (array_check): Ensure that class arrays have refs. (dim_corank_check, dim_rank_check): Retrun success if class. * primary.c (gfc_match_varspec): Fix for class arrays and co-arrays. Make sure that class _data is present. (gfc_match_rvalue): Handle class arrays. *trans-intrinsic.c (gfc_conv_intrinsic_size): Add class array reference. (gfc_conv_allocated): Add _data component to class expressions. (gfc_add_intrinsic_ss_code): ditto. * simplify.c (simplify_cobound): Fix for BT_CLASS. (simplify_bound): Return NULL for class arrays. (simplify_cobound): Obtain correct array_spec. Use cotype as appropriate. Use arrayspec for bounds. 2011-12-11 Paul Thomas <pault@gcc.gnu.org> Tobias Burnus <burnus@gcc.gnu.org> PR fortran/41539 PR fortran/43214 PR fortran/43969 PR fortran/44568 PR fortran/46356 PR fortran/46990 PR fortran/49074 * gfortran.dg/class_array_1.f03: New. * gfortran.dg/class_array_2.f03: New. * gfortran.dg/class_array_3.f03: New. * gfortran.dg/class_array_4.f03: New. * gfortran.dg/class_array_5.f03: New. * gfortran.dg/class_array_6.f03: New. * gfortran.dg/class_array_7.f03: New. * gfortran.dg/class_array_8.f03: New. * gfortran.dg/coarray_poly_1.f90: New. * gfortran.dg/coarray_poly_2.f90: New. * gfortran.dg/coarray/poly_run_1.f90: New. * gfortran.dg/coarray/poly_run_2.f90: New. * gfortran.dg/class_to_type_1.f03: New. * gfortran.dg/type_to_class_1.f03: New. * gfortran.dg/typebound_assignment_3.f03: Remove the error. * gfortran.dg/auto_dealloc_2.f90: Occurences of __builtin_free now 2. * gfortran.dg/class_19.f03: Occurences of __builtin_free now 8. Added: trunk/gcc/testsuite/gfortran.dg/class_array_1.f03 trunk/gcc/testsuite/gfortran.dg/class_array_2.f03 trunk/gcc/testsuite/gfortran.dg/class_array_3.f03 trunk/gcc/testsuite/gfortran.dg/class_array_4.f03 trunk/gcc/testsuite/gfortran.dg/class_array_5.f03 trunk/gcc/testsuite/gfortran.dg/class_array_6.f03 trunk/gcc/testsuite/gfortran.dg/class_array_7.f03 trunk/gcc/testsuite/gfortran.dg/class_array_8.f03 trunk/gcc/testsuite/gfortran.dg/class_to_type_1.f03 trunk/gcc/testsuite/gfortran.dg/coarray/poly_run_1.f90 trunk/gcc/testsuite/gfortran.dg/coarray/poly_run_2.f90 trunk/gcc/testsuite/gfortran.dg/coarray_poly_1.f90 trunk/gcc/testsuite/gfortran.dg/coarray_poly_2.f90 trunk/gcc/testsuite/gfortran.dg/type_to_class_1.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/array.c trunk/gcc/fortran/check.c trunk/gcc/fortran/class.c trunk/gcc/fortran/expr.c trunk/gcc/fortran/gfortran.h trunk/gcc/fortran/interface.c trunk/gcc/fortran/match.c trunk/gcc/fortran/primary.c trunk/gcc/fortran/resolve.c trunk/gcc/fortran/simplify.c trunk/gcc/fortran/trans-array.c trunk/gcc/fortran/trans-array.h trunk/gcc/fortran/trans-decl.c trunk/gcc/fortran/trans-expr.c trunk/gcc/fortran/trans-intrinsic.c trunk/gcc/fortran/trans-stmt.c trunk/gcc/fortran/trans.c trunk/gcc/fortran/trans.h trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/auto_dealloc_2.f90 trunk/gcc/testsuite/gfortran.dg/class_19.f03 trunk/gcc/testsuite/gfortran.dg/typebound_assignment_3.f03
REOPEN. While the reduced test case in comment 1 works, I get an ICE with the original test case of comment 0: internal compiler error: in gfc_conv_array_constructor_expr, at fortran/trans-expr.c:4529 It is not a true regression as with GCC 4.6 one had: Error: Non-scalar base object at (1) currently not implemented
The failing assert is: Breakpoint 2, gfc_conv_array_constructor_expr (expr=0x16b8f10, se=0x7fffffffd580) at /home/tob/projects/gcc-git/gcc/gcc/fortran/trans-expr.c:4529 4529 gcc_assert (ss->info->expr == expr && ss->info->type == GFC_SS_CONSTRUCTOR); We have: (gdb) p ss->info->expr $5 = (gfc_expr *) 0x16bdf60 (gdb) p expr $6 = (gfc_expr *) 0x16b8f10 While expr is indeed an array constructor (EXPR_ARRAY), ss->info->expr is an EXPR_VARIABLE; both are of the same BT_DERIVED type. The variable is: (gdb) p ss->info->expr->symtree->n.sym->name $14 = 0x2aaaacf080b8 "foobar" That is the LHS of the assignment: foobar = [bar(1), bar(2)] For completeness, (gdb) p ss->info->type $15 = GFC_SS_SECTION The backtrace is: #0 gfc_conv_array_constructor_expr (expr=0x16b8f10, se=0x7fffffffd580) at gcc/fortran/trans-expr.c:4529 #1 gfc_conv_expr (se=0x7fffffffd580, expr=0x16b8f10) at gcc/fortran/trans-expr.c:5193 #2 0x00000000005d28a6 in gfc_conv_expr_reference (se=0x7fffffffd580, expr=<optimized out>) at gcc/fortran/trans-expr.c:5298 #3 0x00000000005d78d2 in gfc_conv_derived_to_class (class_ts=..., e=0x16b8f10, parmse=0x7fffffffd580) at gcc/fortran/trans-expr.c:185 #4 gfc_conv_procedure_call (se=0x7fffffffd750, sym=0x16bc5d0, args=0x16bfec0, expr=0x16be2b0, append_args=0x0) at gcc/fortran/trans-expr.c:3217
Draft patch: Index: trans-stmt.c =================================================================== --- trans-stmt.c (révision 199585) +++ trans-stmt.c (copie de travail) @@ -267,6 +267,7 @@ gfc_conv_elemental_dependencies (gfc_se * se, gfc_ GFC_SS_SECTION); gfc_mark_ss_chain_used (tmp_ss, 1); tmp_ss->info->expr = ss->info->expr; + tmp_ss->info->data.array.ref = ss->info->data.array.ref; replace_ss (loopse, ss, tmp_ss); /* Obtain the argument descriptor for unpacking. */
Author: mikael Date: Thu Jun 13 14:26:47 2013 New Revision: 200069 URL: http://gcc.gnu.org/viewcvs?rev=200069&root=gcc&view=rev Log: fortran/ PR fortran/49074 * trans-expr.c (gfc_conv_variable): Don't walk the reference chain. Handle NULL array references. (gfc_conv_procedure_call): Remove code handling NULL array references. testsuite/ PR fortran/49074 * gfortran.dg/typebound_assignment_5.f03: New. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-expr.c trunk/gcc/testsuite/ChangeLog Author: mikael Date: Thu Jun 13 14:30:17 2013 New Revision: 200070 URL: http://gcc.gnu.org/viewcvs?rev=200070&root=gcc&view=rev Log: Commit forgotten file Added: trunk/gcc/testsuite/gfortran.dg/typebound_assignment_5.f03
FIXED again.
Author: mikael Date: Sat Jun 15 21:20:29 2013 New Revision: 200128 URL: http://gcc.gnu.org/viewcvs?rev=200128&root=gcc&view=rev Log: fortran/ PR fortran/49074 PR fortran/56136 * dependency.c (gfc_check_argument_var_dependency): Return 0 in the array constructor case. testsuite/ PR fortran/49074 PR fortran/56136 * gfortran.dg/typebound_assignment_5.f03: Check the absence of any packing. * gfortran.dg/typebound_assignment_6.f03: New. Added: trunk/gcc/testsuite/gfortran.dg/typebound_assignment_6.f03 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/dependency.c trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/gfortran.dg/typebound_assignment_5.f03
Comment #14 removes an unnecessary packing/unpacking. The bug remains fixed. :-)
*** Bug 56136 has been marked as a duplicate of this bug. ***