Bug 72832 - [6/7 Regression] [OOP] ALLOCATE with SOURCE fails to allocate requested dimensions
Summary: [6/7 Regression] [OOP] ALLOCATE with SOURCE fails to allocate requested dimen...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 6.1.1
: P4 normal
Target Milestone: 6.3
Assignee: vehre
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-08 08:18 UTC by Daan van Vugt
Modified: 2016-10-31 16:24 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 5.4.0
Known to fail: 6.1.0, 7.0
Last reconfirmed: 2016-08-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daan van Vugt 2016-08-08 08:18:41 UTC
If I try to allocate a polymorphic variable with a specific dimension I do not get the expected result. See this example:

program allocate_source
  type :: t
  end type t
  type, extends(t) :: tt
  end type tt

  class(t), allocatable, dimension(:) :: a, b
  allocate(tt::a(1:2))
  write(*,*) size(a,1)

  allocate(b(1:4), source=a)
  write(*,*) size(b,1)
end program allocate_source

Which produces as output
2
2

While I expect the second line to be 4.
Comment 1 Dominique d'Humieres 2016-08-08 08:34:43 UTC
> While I expect the second line to be 4.

From the standard

"If SOURCE= appears, source-expr shall be conformable with allocation."

I think the code is invalid.
Comment 2 vehre 2016-08-10 08:28:01 UTC
There are two bugs in one here: 

- the shape is selected from source= and not from the b(1:4), and
- the shape of a and new b is not conformable, which can only be deduced at runtime (and is already when the class(t) is replaced by type(t) and -fcheck=all is used).
Comment 3 vehre 2016-08-10 08:51:58 UTC
This patch fragment fixes the first issue:

diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 5884e7a..8e5428a 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -5485,7 +5485,8 @@ gfc_trans_allocate (gfc_code * code)
                  desc = tmp;
                  tmp = gfc_class_data_get (tmp);
                }
-             e3_is = E3_DESC;
+             if (code->ext.alloc.arr_spec_from_expr3)
+               e3_is = E3_DESC;
            }
          else
            desc = !is_coarray ? se.expr
Comment 4 Dominique d'Humieres 2016-08-10 11:23:56 UTC
For the record, the following test

program allocate_source
  type :: t
  end type t
  type, extends(t) :: tt
  end type tt

  type(t), allocatable, dimension(:) :: a, b
  allocate(a(1:2))
  write(*,*) size(a,1)

  allocate(b(1:4), source=a)
  write(*,*) size(b,1)
end program allocate_source

gives the "expected" output and at runtime the error

           2
At line 11 of file pr72832_db_1.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'b' (4/2)

when compiled with -fcheck=bounds.
Comment 5 Daan van Vugt 2016-08-10 11:39:25 UTC
Thanks for the quick responses.
Just out of interest: what is the recommended way to allocate a class(t) variable of the same type as a but different size?
Do I need to select type and list all of the types? that would be inconvenient.
Comment 6 Dominique d'Humieres 2016-08-10 13:22:31 UTC
BTW this is a regression. Compiling the code with 5.4.0 gives at runtime the output

           2
           4

if compiled without -fcheck=bounds and

           2
At line 11 of file pr72832.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'b' (4/2)

with it.

> Just out of interest: what is the recommended way to allocate a class(t)
> variable of the same type as a but different size?

Not 100% sure, but may be you can use a scalar (it does seem to work for me).
Comment 7 Dominique d'Humieres 2016-08-10 13:51:47 UTC
Likely caused by r229294 (PRs 67044 and 66927).
Comment 8 vehre 2016-09-02 08:48:32 UTC
Patch available at:

https://gcc.gnu.org/ml/fortran/2016-09/msg00007.html

Awaiting comments/review.
Comment 9 vehre 2016-10-13 08:51:53 UTC
Author: vehre
Date: Thu Oct 13 08:51:21 2016
New Revision: 241088

URL: https://gcc.gnu.org/viewcvs?rev=241088&root=gcc&view=rev
Log:
gcc/fortran/ChangeLog:

2016-09-01  Andre Vehreschild  <vehre@gcc.gnu.org>

	PR fortran/72832
	* trans-expr.c (gfc_copy_class_to_class): Add generation of
	runtime array bounds check.
	* trans-intrinsic.c (gfc_conv_intrinsic_size): Add a crutch to
	get the descriptor of a function returning a class object.
	* trans-stmt.c (gfc_trans_allocate): Use the array spec on the
	array to allocate instead of the array spec from source=.

gcc/testsuite/ChangeLog:

2016-09-01  Andre Vehreschild  <vehre@gcc.gnu.org>

	PR fortran/72832
	* gfortran.dg/allocate_with_source_22.f03: New test.
	* gfortran.dg/allocate_with_source_23.f03: New test.  Expected to
	fail.



Added:
    trunk/gcc/testsuite/gfortran.dg/allocate_with_source_22.f03
    trunk/gcc/testsuite/gfortran.dg/allocate_with_source_23.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-intrinsic.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 vehre 2016-10-13 08:53:40 UTC
Waiting one week before backporting to gcc-6.
Comment 11 vehre 2016-10-23 10:54:29 UTC
Closed due to no further complains.
Comment 12 vehre 2016-10-23 10:56:47 UTC
Whoops, that was wrong. Backporting to gcc-6 still pending.
Comment 13 vehre 2016-10-23 11:56:17 UTC
Author: vehre
Date: Sun Oct 23 11:55:44 2016
New Revision: 241448

URL: https://gcc.gnu.org/viewcvs?rev=241448&root=gcc&view=rev
Log:
gcc/fortran/ChangeLog:

2016-10-23  Andre Vehreschild  <vehre@gcc.gnu.org>

	Backport from trunk
	PR fortran/72832
	* trans-expr.c (gfc_copy_class_to_class): Add generation of
	runtime array bounds check.
	* trans-intrinsic.c (gfc_conv_intrinsic_size): Add a crutch to
	get the descriptor of a function returning a class object.
	* trans-stmt.c (gfc_trans_allocate): Use the array spec on the
	array to allocate instead of the array spec from source=.

gcc/testsuite/ChangeLog:

2016-10-23  Andre Vehreschild  <vehre@gcc.gnu.org>

	Backport from trunk
	PR fortran/72832
	* gfortran.dg/allocate_with_source_22.f03: New test.
	* gfortran.dg/allocate_with_source_23.f03: New test.  Expected to
	fail.



Added:
    branches/gcc-6-branch/gcc/testsuite/gfortran.dg/allocate_with_source_22.f03
    branches/gcc-6-branch/gcc/testsuite/gfortran.dg/allocate_with_source_23.f03
Modified:
    branches/gcc-6-branch/gcc/fortran/ChangeLog
    branches/gcc-6-branch/gcc/fortran/trans-expr.c
    branches/gcc-6-branch/gcc/fortran/trans-intrinsic.c
    branches/gcc-6-branch/gcc/fortran/trans-stmt.c
    branches/gcc-6-branch/gcc/testsuite/ChangeLog
Comment 14 vehre 2016-10-31 16:24:20 UTC
Now closing.