Bug 91544 - When initializing allocatable character array get "Error: size of variable 'A.0' is too large"
Summary: When initializing allocatable character array get "Error: size of variable 'A...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 7.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: 68241
  Show dependency treegraph
 
Reported: 2019-08-25 23:03 UTC by urbanjost
Modified: 2022-05-09 17:43 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-09-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description urbanjost 2019-08-25 23:03:47 UTC
If use a non-constant integer as the length for an allocatable character variable array get a confusing error message.

If the integer LINE_LENGTH is a PARAMETER it works.

A work-around where the array is first allocated as a zero-size array
and then included in the assignment works.

Otherwise get an odd compile-time error about "A.0" being too large.

program testit
implicit none
integer                      :: line_length=50
character(len=:),allocatable :: test_in(:)

#ifdef BAD
   test_in=[ character(len=line_length) ::  'aaa','bb' ]
#else
   allocate(character(len=line_length) :: test_in(0))
   test_in=[character(len=line_length) :: test_in,'aaa','bb']
#endif
   write(*,*)test_in
end program testit

gfortran -UBAD xx.F90
 aaa                                               bb                                                
gfortran -DBAD xx.F90
xx.f90:4:0:

    test_in=[ character(len=line_length) ::  'this is a test' ]

Error: size of variable 'A.0' is too large
Comment 1 Dominique d'Humieres 2019-09-07 13:30:49 UTC
Compiling the test with gcc4.8 or 4.9 gives an ICE

pr91544.f90:6:0: internal compiler error: in gimplify_var_or_parm_decl, at gimplify.c:1741
    test_in=[ character(len=line_length) ::  'aaa','bb' ]

I get the error starting at gcc5.
Comment 2 Tobias Burnus 2022-05-09 17:38:16 UTC
Reconfirmed with GCC 13. Internally, the following code is generated (for my example, -fdump-tree-original):

          static character(kind=1) A.0[3][1:D.4246] = {"abcde", "fhji", "klmno"};

The problem is that D.4246 is a variable and not a constant. I think the proper solution is to create an array for max length, i.e. 5 in this example with right padding if too short:

          static character(kind=1) A.0[3][1:5] = {"abcde", "fhji ", "klmno"};

And then in the array use, there is already some code like the following. However, here, not only the .x (= desired length) but also the actual length (here: 5) has to be taken into account for the memmove/memset bit, i.e. min(.x, 5). (In the example below, .x, D.4251 and D.4252 are all the same - and match either the LHS after allocation or RHS of the assignment.)

  .x = i >= -2 ? (integer(kind=8)) (i + 2) : 0;
...
  D.4252 = .x;
  D.4253 = (void *) D.4242 + (sizetype) (((S.1 + D.4249) + D.4243) * x.span);
  D.4254 = (void *) &A.0[S.1];
  if (D.4252 > 0)
    {
      if (NON_LVALUE_EXPR <D.4251> < NON_LVALUE_EXPR <D.4252>)
        {
          __builtin_memmove (D.4253, D.4254, (unsigned long) NON_LVALUE_EXPR <D.4251>);
          __builtin_memset (D.4253 + (sizetype) NON_LVALUE_EXPR <D.4251>, 32,
(unsigned long) (NON_LVALUE_EXPR <D.4252> - NON_LVALUE_EXPR <D.4251>));