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: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: ice-on-valid-code
Depends on:
Blocks: 45170
  Show dependency treegraph
Reported: 2011-08-03 07:16 UTC by Tobias Burnus
Modified: 2013-06-12 09:53 UTC (History)
0 users

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


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)

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
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.