Bug 43969 - [OOP] ALLOCATED() with polymorphic arrays
Summary: [OOP] ALLOCATED() with polymorphic arrays
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: ice-on-valid-code
: 44570 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-05-03 10:11 UTC by Salvatore Filippone
Modified: 2011-12-12 08:14 UTC (History)
4 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2010-05-15 10:46:53


Attachments
test case (209 bytes, text/plain)
2010-05-03 10:12 UTC, Salvatore Filippone
Details
Extended text case (257 bytes, text/plain)
2010-05-03 10:37 UTC, Salvatore Filippone
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Salvatore Filippone 2010-05-03 10:11:38 UTC
Hello,
The attached code asserts that an ALLOCATABLE inner component starts its life as ALLOCATED, which is contrary to everything I know about allocatables. 
----------------------------- log -----------------------------------
[sfilippo@donald bug16]$ gfortran -v 
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/gnu46/libexec/gcc/x86_64-unknown-linux-gnu/4.6.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran,lto --no-create --no-recursion : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran,lto --no-create --no-recursion : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran,lto --no-create --no-recursion : (reconfigured) ../gcc/configure --prefix=/usr/local/gnu46 --enable-languages=c,c++,fortran,lto --no-create --no-recursion
Thread model: posix
gcc version 4.6.0 20100430 (experimental) (GCC) 
[sfilippo@donald bug16]$ gfortran -o testd16 testd16.f03
[sfilippo@donald bug16]$ ./testd16 
 Check on allocated:  T
-----------------------------------------------------------------------------
Salvatore
Comment 1 Salvatore Filippone 2010-05-03 10:12:13 UTC
Created attachment 20542 [details]
test case
Comment 2 Salvatore Filippone 2010-05-03 10:37:40 UTC
Created attachment 20544 [details]
Extended text case

With this and a fresh build at r158988 I get the following: 

[sfilippo@donald bug16]$ ./testd16 
 Check on allocated:  T
 Check on allocated 3:  T
At line 18 of file testd16.f03
Fortran runtime error: Attempting to allocate already allocated array 'try2'
Comment 3 janus 2010-05-15 10:25:15 UTC
(In reply to comment #1)
> Created an attachment (id=20542) [edit]

Looking at the dump of this code shows:

The $data component of int is being set to zero (correctly):

  try.int.$data = 0B;

However, the ALLOCATED statement is being evaluated to ".true":

      static logical(kind=4) C.1566 = 1;

      _gfortran_transfer_logical (&dt_parm.0, &C.1566, 4);
Comment 4 janus 2010-05-15 10:46:53 UTC
Turns out that fixing this one is completely trivial, once you actually have a look at it :)

The ALLOCATED intrinsic was just not adjusted to handle CLASS variables yet. The patch is as simple as this:

Index: gcc/fortran/trans-intrinsic.c
===================================================================
--- gcc/fortran/trans-intrinsic.c       (revision 159389)
+++ gcc/fortran/trans-intrinsic.c       (working copy)
@@ -4529,6 +4529,8 @@ gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
     {
       /* Allocatable scalar.  */
       arg1se.want_pointer = 1;
+      if (arg1->expr->ts.type == BT_CLASS)
+       gfc_add_component_ref (arg1->expr, "$data");
       gfc_conv_expr (&arg1se, arg1->expr);
       tmp = arg1se.expr;
     }

Thanks for the bug report, Salvatore.
Comment 5 Salvatore Filippone 2010-05-15 11:33:17 UTC
(In reply to comment #4)
> Turns out that fixing this one is completely trivial, once you actually have a
> look at it :)
> 
> The ALLOCATED intrinsic was just not adjusted to handle CLASS variables yet.
> The patch is as simple as this:
> 
> Index: gcc/fortran/trans-intrinsic.c
> ===================================================================
> --- gcc/fortran/trans-intrinsic.c       (revision 159389)
> +++ gcc/fortran/trans-intrinsic.c       (working copy)
> @@ -4529,6 +4529,8 @@ gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
>      {
>        /* Allocatable scalar.  */
>        arg1se.want_pointer = 1;
> +      if (arg1->expr->ts.type == BT_CLASS)
> +       gfc_add_component_ref (arg1->expr, "$data");
>        gfc_conv_expr (&arg1se, arg1->expr);
>        tmp = arg1se.expr;
>      }
> 
> Thanks for the bug report, Salvatore.
> 
While we are at it, shouldn't the error message on ALLOCATE be  changed to reflect the fact that not only arrays but also scalars might be allocatables? 
(see #2)
Salvatore 
Comment 6 janus 2010-05-15 13:52:52 UTC
Subject: Bug 43969

Author: janus
Date: Sat May 15 13:52:33 2010
New Revision: 159431

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=159431
Log:
2010-05-15  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/43207
	PR fortran/43969
	* gfortran.h (gfc_class_null_initializer): New prototype.
	* expr.c (gfc_class_null_initializer): New function to build a NULL
	initializer for CLASS pointers.
	* symbol.c (gfc_build_class_symbol): Modify internal naming of class
	containers. Remove default NULL initialization of $data component.
	* trans.c (gfc_allocate_array_with_status): Fix wording of an error 
	message.
	* trans-expr.c (gfc_conv_initializer,gfc_trans_subcomponent_assign):
	Use new function 'gfc_class_null_initializer'.
	* trans-intrinsic.c (gfc_conv_allocated): Handle allocatable scalar
	class variables.


2010-05-15  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/43207
	PR fortran/43969
	* gfortran.dg/class_18.f03: New.
	* gfortran.dg/class_19.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/class_18.f03
    trunk/gcc/testsuite/gfortran.dg/class_19.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/expr.c
    trunk/gcc/fortran/gfortran.h
    trunk/gcc/fortran/symbol.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 janus 2010-05-15 14:18:13 UTC
r159431 fixes the problems with allocatable scalar class variables in comment #1 and #2, and also the wording of the error message reported in comment #5.

However, the ALLOCATED intrinsic still gives a gimplification error for allocatable class arrays:

  type foo
  end type
  class(foo), allocatable :: aca(:)
  write(*,*) 'Check on allocated: ', allocated(aca)
end
Comment 8 janus 2010-06-17 22:38:32 UTC
*** Bug 44570 has been marked as a duplicate of this bug. ***
Comment 9 janus 2010-12-29 17:02:24 UTC
Here is another test case from PR46838 comment #8:

  implicit none

  type indx_map
  end type

  type desc_type
    class(indx_map), allocatable :: indxmap(:)
  end type

  type(desc_type)  :: desc
  if (allocated(desc%indxmap)) call abort()

end
Comment 10 Paul Thomas 2011-12-11 20:42:29 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 11 Tobias Burnus 2011-12-12 08:14:04 UTC
FIXED on the 4.7 trunk.

Thanks for the bug report Salvatore!