Bug 49954 - ICE assigning concat expression to an array deferred-length string (realloc on assignment)
Summary: ICE assigning concat expression to an array deferred-length string (realloc o...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 68241 45170
  Show dependency treegraph
 
Reported: 2011-08-03 07:16 UTC by Tobias Burnus
Modified: 2016-01-10 18:11 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-12 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tobias Burnus 2011-08-03 07:16:52 UTC
Follow up to PR 47674.

The following ICEs in trans-arrays.c's gfc_alloc_allocatable_for_assignment

      tmp = expr2->ts.u.cl->backend_decl;
      gcc_assert (expr1->ts.u.cl->backend_decl);
      tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);

My guess is that the first "tmp" is a NULL_TREE.


character(len=:), allocatable :: array_string(:)
array_string = ["ABCDEFGH"]
array_string = array_string // "A"
print '(*(g0))','>',array_string,'<', len(array_string)
end

Also for the following variants:

  array_string // ["A"]
  array_string(1:2) // "A"
  array_string(1:2) // ["A"]

Expected: No ICE, the use of a temporary and the correct result ;-)
Comment 1 Tobias Burnus 2011-08-03 09:26:09 UTC
I thought about something like:

--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -7322,8 +7322,8 @@ gfc_alloc_allocatable_for_assignment (gfc_loopinfo *loop,
   /* Get the new lhs size in bytes.  */
   if (expr1->ts.type == BT_CHARACTER && expr1->ts.deferred)
     {
-      tmp = expr2->ts.u.cl->backend_decl;
-      gcc_assert (expr1->ts.u.cl->backend_decl);
+      tmp = rss->string_length;
+      gcc_assert (expr1->ts.u.cl->backend_decl && tmp);
       tmp = fold_convert (TREE_TYPE (expr1->ts.u.cl->backend_decl), tmp);
       gfc_add_modify (&fblock, expr1->ts.u.cl->backend_decl, tmp);
     }

However, that yields ".array_length" (i.e. the LHS) even for
  array_string(:)(1:1)
which has the length 1. However, at a glance, gfc_conv_concat_op seems to properly set "se->string_length = len". Maybe it is not properly called for rse->string_length?
Comment 2 Tobias Burnus 2012-05-24 13:05:56 UTC
(In reply to comment #1)
> I thought about something like:
> +      tmp = rss->string_length;

That's nonsense as "rss" should be "rse" and "rse" is not available in that function - just expr2.

> However, that yields ".array_length" (i.e. the LHS) even for
>   array_string(:)(1:1)

I think that problem is closely related to PR 51976: For deferred-length components, using ts.u.cl->backend_decl directly is not possible; one needs to have "var->component" and not "component".

Here, the issue is rather similar. I believe that one needs some conversion function which makes string_length available by walking an expr. (It should also work for the "length" part of parameterized DT.)
Comment 3 Dominique d'Humieres 2013-06-12 09:53:13 UTC
Confirmed at revision 199988.
Comment 4 Paul Thomas 2015-11-15 14:08:25 UTC
Author: pault
Date: Sun Nov 15 14:07:52 2015
New Revision: 230396

URL: https://gcc.gnu.org/viewcvs?rev=230396&root=gcc&view=rev
Log:
2015-11-15  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/50221
	PR fortran/68216
	PR fortran/63932
	PR fortran/66408
	* trans_array.c (gfc_conv_scalarized_array_ref): Pass the
	symbol decl for deferred character length array references.
	* trans-stmt.c (gfc_trans_allocate): Keep the string lengths
	to update deferred length character string lengths.
	* trans-types.c (gfc_get_dtype_rank_type); Use the string
	length of deferred character types for the dtype size.
	* trans.c (gfc_build_array_ref): For references to deferred
	character arrays, use the domain max value, if it is a variable
	to set the 'span' and use pointer arithmetic for acces to the
	element.
	(trans_code): Set gfc_current_locus for diagnostic purposes.

	PR fortran/67674
	* trans-expr.c (gfc_conv_procedure_call): Do not fix deferred
	string lengths of components.

	PR fortran/49954
	* resolve.c (deferred_op_assign): New function.
	(gfc_resolve_code): Call it.
	* trans-array.c (concat_str_length): New function.
	(gfc_alloc_allocatable_for_assignment): Jump directly to alloc/
	realloc blocks for deferred character length arrays because the
	string length might change, even if the shape is the same. Call
	concat_str_length to obtain the string length for concatenation
	since it is needed to compute the lhs string length.
	Set the descriptor dtype appropriately for the new string
	length.
	* trans-expr.c (gfc_trans_assignment_1): Use the rse string
	length for all characters, other than deferred types. For
	concatenation operators, push the rse.pre block to the inner
	most loop so that the temporary pointer and the assignments
	are properly placed.

2015-11-15  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/50221
	* gfortran.dg/deferred_character_1.f90: New test.
	* gfortran.dg/deferred_character_4.f90: New test for comment
	#4 of the PR.

	PR fortran/68216
	* gfortran.dg/deferred_character_2.f90: New test.

	PR fortran/67674
	* gfortran.dg/deferred_character_3.f90: New test.

	PR fortran/63932
	* gfortran.dg/deferred_character_5.f90: New test.

	PR fortran/66408
	* gfortran.dg/deferred_character_6.f90: New test.

	PR fortran/49954
	* gfortran.dg/deferred_character_7.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/deferred_character_1.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_2.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_3.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_4.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_5.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_6.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Paul Thomas 2016-01-07 11:20:01 UTC
Since I already fixed it on trunk, I should take it!

Paul
Comment 6 Paul Thomas 2016-01-10 18:07:16 UTC
Author: pault
Date: Sun Jan 10 18:06:43 2016
New Revision: 232203

URL: https://gcc.gnu.org/viewcvs?rev=232203&root=gcc&view=rev
Log:
2016-01-10  Paul Thomas  <pault@gcc.gnu.org>

	Backport from mainline.
	PR fortran/50221
	PR fortran/68216
	PR fortran/63932
	PR fortran/66408
	* trans_array.c (gfc_conv_scalarized_array_ref): Pass the
	symbol decl for deferred character length array references.
	* trans-stmt.c (gfc_trans_allocate): Keep the string lengths
	to update deferred length character string lengths.
	* trans-types.c (gfc_get_dtype_rank_type); Use the string
	length of deferred character types for the dtype size.
	* trans.c (gfc_build_array_ref): For references to deferred
	character arrays, use the domain max value, if it is a variable
	to set the 'span' and use pointer arithmetic for acces to the
	element.
	(trans_code): Set gfc_current_locus for diagnostic purposes.

	Backport from mainline.
	PR fortran/67674
	* trans-expr.c (gfc_conv_procedure_call): Do not fix deferred
	string lengths of components.

	Backport from mainline.
	PR fortran/49954
	* resolve.c (deferred_op_assign): New function.
	(gfc_resolve_code): Call it.
	* trans-array.c (concat_str_length): New function.
	(gfc_alloc_allocatable_for_assignment): Jump directly to alloc/
	realloc blocks for deferred character length arrays because the
	string length might change, even if the shape is the same. Call
	concat_str_length to obtain the string length for concatenation
	since it is needed to compute the lhs string length.
	Set the descriptor dtype appropriately for the new string
	length.
	* trans-expr.c (gfc_trans_assignment_1): Fix the rse string
	length for all characters, other than deferred types. For
	concatenation operators, push the rse.pre block to the inner
	most loop so that the temporary pointer and the assignments
	are properly placed.

	Backport from mainline.
	PR fortran/67779
	* trans_array.c (gfc_conv_scalarized_array_ref): Add missing
	se->use_offset from condition for calculation of 'base'.

2015-01-10  Paul Thomas  <pault@gcc.gnu.org>

	Backport from mainline.
	PR fortran/50221
	* gfortran.dg/deferred_character_1.f90: New test.
	* gfortran.dg/deferred_character_4.f90: New test for comment
	#4 of the PR.

	Backport from mainline.
	PR fortran/68216
	* gfortran.dg/deferred_character_2.f90: New test.

	Backport from mainline.
	PR fortran/67674
	* gfortran.dg/deferred_character_3.f90: New test.

	Backport from mainline.
	PR fortran/63932
	* gfortran.dg/deferred_character_5.f90: New test.

	Backport from mainline.
	PR fortran/66408
	* gfortran.dg/deferred_character_6.f90: New test.

	Backport from mainline.
	PR fortran/49954
	* gfortran.dg/deferred_character_7.f90: New test.

	Backport from mainline.
	PR fortran/67779
	* gfortran.dg/actual_array_offset_1: New test.

Added:
    branches/gcc-5-branch/gcc/fortran/ChangeLog-2015
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/actual_array_offset_1.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_1.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_2.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_3.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_4.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_5.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_6.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_7.f90
Modified:
    branches/gcc-5-branch/gcc/fortran/ChangeLog
    branches/gcc-5-branch/gcc/fortran/resolve.c
    branches/gcc-5-branch/gcc/fortran/trans-array.c
    branches/gcc-5-branch/gcc/fortran/trans-expr.c
    branches/gcc-5-branch/gcc/fortran/trans-stmt.c
    branches/gcc-5-branch/gcc/fortran/trans-types.c
    branches/gcc-5-branch/gcc/fortran/trans.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 7 Paul Thomas 2016-01-10 18:11:22 UTC
Fixed on trunk and 5-branch.

Thanks for the report.

Paul