[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-03 Thread strasbur at chkw386 dot ch.pwr.wroc.pl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

--- Comment #18 from Krzysztof Strasburger  ---
I have found that tree-fre, tree-pre and tree-dse have to be disabled in order
to generate correctly working code at all optimization levels (both C and
FORTRAN).
I'm happy with this workaround, so thank you for all suggestions.


[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-02 Thread dominiq at lps dot ens.fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

--- Comment #17 from Dominique d'Humieres  ---
> I cannot agree with you. You are interpreting the code that may access the
> array beyond declared bounds as invalid, which is simply not true.

6.5 Use of data objects

... The value of a subscript in an array element shall be within the bounds for
its dimension.

where the "shall" means (as elsewhere in the standard) that it is the coder
responsibility to honor the constraint at run time.

> As you pointed it out before, unnamed common block may be declared larger
> elsewhere, so writing the dmem array beyond its first element may be a design
> decision and therefore may be perfectly legal. 

As above this is a wrong assumption: the design decision must be standard
conforming. When you write "common dmem(1)" you tell the compiler that 'dmem'
has only one element.

> The compiler has no clue about real size of unnamed common while compiling 
> buggy.f and bounds checking is optional.

When you write "common dmem(1)" you tell the compiler that 'dmem' has only one
element.

> I would also like to point it out that interpreting things this way 
> you do, 

This is not my interpretation, it is what the Fortran standard says.

> you exclude some older FORTRAN77 software (for example: quantum chemistry
> GAMESS), in which the lack of dynamic memory allocation was overcome using 
> the trick we are discussing here (mixing with C was needed). 

Well, I have used safer tricks to overcome the limitation.

> BTW, change the size of dmem to 2 in buggy.f and things start to work 
> correctly, although "out of bounds" memory accesses still do happen. 
> The problem occurs only if dmem is of size 1.

Because only for size 1 the optimizer can infer that valid uses will provide
the (1,1,1) triplet.

> Of course you (developers) may decide to ignore this problem anyway, 
> so if you do so, feel free to close this bug. I'm not going to reopen 
> it again, because I'm out of arguments. I'm also not competent enough 
> to tamper with the compiler.

What you can do is to look at the GCC manual and try to find the optimization
pass than enable the optimization you don't like and disable it. Note that most
optimizations are not part of the gfortran front-end.


[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-02 Thread strasbur at chkw386 dot ch.pwr.wroc.pl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

--- Comment #16 from Krzysztof Strasburger  ---
Dear Dominique,
I cannot agree with you. You are interpreting the code that may access the
array beyond declared bounds as invalid, which is simply not true.
As you pointed it out before, unnamed common block may be declared larger
elsewhere, so writing the dmem array beyond its first element may be a design
decision and therefore may be perfectly legal. The compiler has no clue about
real size of unnamed common while compiling buggy.f and bounds checking is
optional.
I would also like to point it out that interpreting things this way you do, you
exclude some older FORTRAN77 software (for example: quantum chemistry GAMESS),
in which the lack of dynamic memory allocation was overcome using the trick we
are discussing here (mixing with C was needed). BTW, change the size of dmem to
2 in buggy.f and things start to work correctly, although "out of bounds"
memory accesses still do happen. The problem occurs only if dmem is of size 1.
Of course you (developers) may decide to ignore this problem anyway, so if you
do so, feel free to close this bug. I'm not going to reopen it again, because
I'm out of arguments. I'm also not competent enough to tamper with the
compiler.


[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-02 Thread dominiq at lps dot ens.fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

Dominique d'Humieres  changed:

   What|Removed |Added

 Status|UNCONFIRMED |WAITING
   Last reconfirmed||2013-09-02
 Ever confirmed|0   |1

--- Comment #15 from Dominique d'Humieres  ---
It is invalid to use

  subroutine buggy(i1, i2, i3)
  integer*4 i1, i2, i3
  real*8 dmem
  common dmem(1)
  dmem(i1)=1.
  dmem(i2)=2.
  dmem(i3)=2.
  return
  end

with any i* different from 1. If you compile the code with -fbounds-check (or
for recent gfortran, -fcheck=bounds) you get for 'echo 1 2 3'

Fortran runtime error: Index '2' of dimension 1 of array 'dmem' above upper
bound of 1

As the code is invalid if one of the i* is not one, the compiler can do
whatever it finds appropriate, e.g., set i1=i2=i3=1 (only valid case) and
discard the other assignments.

AFAICT, the following works as I expect (4.0, 2.0, 3.0):

[macbook] dominiq/Downloads% cat buggy.f90
  subroutine buggy(i1, i2, i3)
  integer*4 i1, i2, i3
  real*8 dmem
  common dmem(1)
  dmem(i1)=4.
!  dmem(i2)=2.
!  dmem(i3)=2.
  return
  end
[macbook] dominiq/Downloads% cat main.f90
! Compile and link this file with buggy.f, using gfortran 4.6 (and probably
! any newer version), with optimization enabled (at least -O1).
! Run with: echo 1 2 3 | ./a.out
! expected (correct) result: 1. 2. 2.
  program main
  implicit none
  integer*4 i1,i2,i3
  real*8 dmem
  common dmem(3)
  read (*,*) i1,i2,i3
  dmem(i1) = 1.0
  dmem(i2) = 2.0
  dmem(i3) = 3.0
  print *, dmem
  call buggy(i1,i2,i3)
  write (*,*) dmem(1),dmem(2),dmem(3)
  end

I let you close the PR as INVALID.


[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-02 Thread strasbur at chkw386 dot ch.pwr.wroc.pl
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

Krzysztof Strasburger  changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #14 from Krzysztof Strasburger  ---
Marking the report as invalid doesn't solve the real problem.
I changed the common to unnamed and the situation is still the same.
main.f:
C Compile and link this file with buggy.f, using gfortran 4.6 (and probably
C any newer version), with optimization enabled (at least -O1).
C Run with: echo 1 2 3 | ./a.out
C expected (correct) result: 1. 2. 2.
  program main
  integer*4 i1,i2,i3
  real*8 dmem
  common dmem(3)
  read (*,*) i1,i2,i3
  call buggy(i1,i2,i3)
  write (*,*) dmem(1),dmem(2),dmem(3)
  end 
buggy.f:
  subroutine buggy(i1, i2, i3)
  integer*4 i1, i2, i3
  real*8 dmem
  common dmem(1)
  dmem(i1)=1.
  dmem(i2)=2.
  dmem(i3)=2.
  return
  end
Better?


[Bug fortran/58270] Wrong code while accessing array elements in a global structure

2013-09-02 Thread dominiq at lps dot ens.fr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270

Dominique d'Humieres  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #13 from Dominique d'Humieres  ---
> Example of failing FORTRAN code, with assembler output from gfortran 4.6.4

This code is invalid:

5.7.2.5 Differences between named common and blank common

A blank common block has the same properties as a named common block, except
for the following.

...
 Named common blocks of the same name shall be of the same size in all scoping
units of a program in which they appear, but blank common blocks may be of
dierent sizes.
...

If you put the two *.f files in the same one and compile the result, you get
the following waring:

Warning: Named COMMON block 'mem' at (1) shall be of the same size as elsewhere
(24 vs 8 bytes)

and the executable gives the result you expect.