Bug 49074 - [OOP] Defined assignment w/ CLASS arrays: Incomplete error message
Summary: [OOP] Defined assignment w/ CLASS arrays: Incomplete error message
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 4.9.0
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, patch
: 56136 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-05-20 01:29 UTC by Jerry DeLisle
Modified: 2016-11-16 14:18 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-06-16 17:51:22


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jerry DeLisle 2011-05-20 01:29:26 UTC
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
Comment 1 Tobias Burnus 2011-05-20 06:56:01 UTC
(Program compiles with ifort 12, but segfaults at run time.)
Comment 2 janus 2011-06-16 17:51:22 UTC
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
Comment 3 janus 2011-06-16 18:24:15 UTC
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.
Comment 4 janus 2011-06-16 21:45:29 UTC
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
Comment 5 janus 2011-06-16 21:49:28 UTC
r175113 fixes the problem on trunk. Is it worth backporting this to 4.6?
Comment 6 janus 2011-06-19 21:05:22 UTC
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
Comment 7 janus 2011-06-19 21:31:25 UTC
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.
Comment 8 Paul Thomas 2011-12-11 20:42:31 UTC
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
Comment 9 Tobias Burnus 2011-12-12 12:21:51 UTC
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
Comment 10 Tobias Burnus 2011-12-12 12:31:55 UTC
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
Comment 11 Mikael Morin 2013-06-11 16:13:54 UTC
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.  */
Comment 12 Tobias Burnus 2013-06-13 16:08:41 UTC
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
Comment 13 Mikael Morin 2013-06-14 11:40:45 UTC
FIXED again.
Comment 14 Mikael Morin 2013-06-15 21:23:43 UTC
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 15 Mikael Morin 2013-06-15 21:25:02 UTC
Comment #14 removes an unnecessary packing/unpacking.
The bug remains fixed. :-)
Comment 16 Mikael Morin 2013-06-15 21:28:13 UTC
*** Bug 56136 has been marked as a duplicate of this bug. ***