There's a difference between the assembly emitted for the following two Fortran tests: PRINT *, .TRUE., .TRUE_8 ; END and PRINT *, .TRUE._8, .TRUE ; END Where for the former we get .align 4 .LC1: .long 1 the latter gives: .align 8 .LC1: .long 1 .long 0 .text and in both cases the constants are referenced by pointing to .LC1, i.e. the code for the PRINT-statements looks like: pushl $8 ;; or $4 for the 4-byte true pushl $.LC1 call _gfortran_transfer_logical In other words, the code is correct for the former program, but not for the latter, as here both alignment may be wrong and memory beyond the correctly initialized space will be read. Andrew Pinski confirmed that the same difference also exists on powerpc, I assume that this will make 4-byte .TRUE. to always be evaluated to .FALSE. on that platform. On ix86 on the other hand an .FALSE._8 will be evaluating to true if subsequent memory is non-zero. NB I mark this as blocking PR19543, I don't know if this is the only issue remaining with that PR. Also, I made the component rtl-optimization, as the tree dumps look correct.
Confirmed, middle-end is closer to the reality as this happens without optimization on.
(In reply to comment #0) > In other words, the code is correct for the former program, but not for the > latter, as here both alignment may be wrong and memory beyond the correctly > initialized space will be read. ... the code is correct for the latter program, but not for the first ...
I should also add amphasis to the point that this only happens for LOGICAL constants. To see how they're defined, look at gfc_build_logical_type in fortran/trans-types.c.
One more data point: depending on the order of the functions test1 and test8 the following testcase will print different results on ix86: character*2 :: t(2), f(2), test1, test8 t(1) = test1(1) f(1) = test1(0) t(2) = test8(1) f(2) = test8(0) print *, t print *, f end function test8(i) result(r) integer :: i character*2 :: r if (i==1) then write (r, *) .TRUE._8 else write (r, *) .FALSE._8 end if end function test8 function test1(i) result(r) integer :: i character*2 :: r if (i==1) then write (r, *) .TRUE._1 else write (r, *) .FALSE._1 end if end function test1 if test8 comes in front of test1 we get the correct: T T F F if test1 comes first (that is, if the order of the functions, not the calls, is interchanged): T T F T which is wrong in the logical(8) case. The assembly shows the same anomaly as I pointed out in the initial bug report.
This is indeed a dup of 19543 (at least, it's fixed by the same patch). *** This bug has been marked as a duplicate of 19543 ***