Bug 34945 - LBOUND fails for array with KIND(complex) used in zero-sized dimension
Summary: LBOUND fails for array with KIND(complex) used in zero-sized dimension
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: rejects-valid
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2008-01-23 17:49 UTC by Dick Hendrickson
Modified: 2008-02-05 13:37 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-01-28 18:09:22


Attachments
Patch and testcase for this PR (935 bytes, patch)
2008-02-03 14:05 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dick Hendrickson 2008-01-23 17:49:26 UTC
With compiler
gcc version 4.3.0 20080109 (experimental) [trunk revision 131426] (GCC)

I get the following error message


>gfortran vf0009.f
vf0009.f: In function 'vf0009':
vf0009.f:11: error: size of variable 'test_array' is too large

If I replace the second line in the declaration of test_array with
any of
     $   KIND(IDA1):5,
     $   KIND(YDA):9,
     $   8:5,
the program compiles without an error message.
The LBOUND function is needed to trigger the error message

Dick Hendrickson

      SUBROUTINE VF0009(IDA1,IDA2,YDA,HDA)
      INTEGER(4) IDA1(4)
      INTEGER(4) IDA2(4)
      COMPLEX(8) YDA(2)
      INTEGER(4) HDA(3)
!  I N I T I A L I Z A T I O N  S E C T I O N
      COMPLEX(KIND=4) :: TEST_ARRAY
     $(  4:5,
     $   KIND(YDA):5,
     $   4:5,
     $   4:5  )
!  T E S T  S T A T E M E N T S
       IDA1(1:4) = LBOUND(TEST_ARRAY)
      END SUBROUTINE
Comment 1 Tobias Burnus 2008-01-28 18:09:22 UTC
I think the size is simply calculated as:
   ubound[n] + 1 - lbound[n];
which means:
   5+1-8 = -2
At some point the variable is regarded as unsigned which means (for 8 byte variables): 18446744073709551614, which is not unexpected to be too large. (I'm ignoring here the byte-size of complex(4) and the other dimensions).

The actual size is of cause "0" as the shape is 2 0 2 2.

I think we have several places where a zero-sized array makes problems (cf. e.g. PR34980 for SHAPE). For this PR one probably needs to fix gfc_trans_create_temp_array, where "size" is calculated as follows:
     size = 1;
     for (n = 0; n < rank; n++)
       {
         stride[n] = size
         delta = ubound[n] + 1 - lbound[n];
         size = size * delta;
       }
     size = size * sizeof(element);

But maybe also something else.
Comment 2 Paul Thomas 2008-01-29 11:24:11 UTC
(In reply to comment #1)

Note the comment in trans-expr.c(gfc_map_intrinsic_function) :

    case GFC_ISYM_LBOUND:
    case GFC_ISYM_UBOUND:
	/* TODO These implementations of lbound and ubound do not limit if
	   the size < 0, according to F95's 13.14.53 and 13.14.113.  */

We need an intrinsic function that translates to cond ? a : b to do the right thing here.  I could not see how to do it with existing front-endery.

Paul
Comment 3 Tobias Burnus 2008-01-29 13:22:33 UTC
> Note the comment in trans-expr.c(gfc_map_intrinsic_function) :
>     case GFC_ISYM_LBOUND:
>     case GFC_ISYM_UBOUND:
>         /* TODO These implementations of lbound and ubound do not limit if
>            the size < 0, according to F95's 13.14.53 and 13.14.113.  */

I had the impression that the problem is the array itself and not only ubound/lbound.

You can replace LBOUND(TEST_ARRAY) by "print *, TEST_ARRAY", "SIZE(TEST_ARRAY)" etc. You will always get the middle end error:
   a.f:11: error: size of variable ‘test_array’ is too large
(gcc/varasm.c:2095).

What I find puzzling is the following:

implicit none
integer :: i(kind(4):1)
integer :: j(4:1)
print *, i(4:3)
print *, j(4:3)
end

"j" works but "i" gives the same error message. If the size is not known at compile time (e.g. an automatic array) it seems to work.

Actually, replacing "j(4:1)" by "j((4):1)" is enough to make it fail. I think "4:1" is replaced by "1:0" while "(4):1" is replaced by "4:1".
Comment 4 Jerry DeLisle 2008-01-30 05:18:17 UTC
Reply to comment two:

There is front-endery code to do "cond ? a : b" in the handling of missing optional dummy arguments. You can borrow from that.
Comment 5 Paul Thomas 2008-01-31 08:30:09 UTC
(In reply to comment #4)
> Reply to comment two:
> 
> There is front-endery code to do "cond ? a : b" in the handling of missing
> optional dummy arguments. You can borrow from that.
> 

I know about the TREE_SSA expressions - what I need is a frontend, ie. a gfc_expr  that delivers this functionality.  The bit of code that needs sorting is manipulating gfc_expressions.  The reason that this is necessary, is that the conditional operators carry over the magnitude of the conditional expression:

i = 4   => (i > 0) * f  => 4*f  when implemented with gfc binops.

In writing this, I realise that I never tried to convert the (i > 0) to logical but I do not think that it would make any difference.

Paul
Comment 6 Paul Thomas 2008-02-03 12:55:23 UTC
(In reply to comment #3)

> I had the impression that the problem is the array itself and not only
> ubound/lbound.

Quite right, Tobias!

Paul
Comment 7 Paul Thomas 2008-02-03 14:05:31 UTC
Created attachment 15085 [details]
Patch and testcase for this PR

This one is regtesting right now.

Cheers

Paul
Comment 8 Dominique d'Humieres 2008-02-03 22:46:28 UTC
Test suite run without new regression on ppc/intel-darwin9, 32 and 64 bit modes, with the patch in http://gcc.gnu.org/ml/fortran/2008-02/msg00008.html.

Thanks for the fix.

Comment 9 Paul Thomas 2008-02-05 13:34:23 UTC
Subject: Bug 34945

Author: pault
Date: Tue Feb  5 13:33:35 2008
New Revision: 132121

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132121
Log:
2008-02-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34945
	* array.c (match_array_element_spec): Remove check for negative
	array size.
	(gfc_resolve_array_spec): Add check for negative size.

2008-02-05  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/34945
	* gfortran.dg/bounds_check_13.f: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/bounds_check_13.f
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/array.c
    trunk/gcc/testsuite/ChangeLog

Comment 10 Paul Thomas 2008-02-05 13:37:21 UTC
Fixed on trunk - thanks, Dick!

Paul