Bug 44489 - Transfer with boz constant can confuse - add documentation
Transfer with boz constant can confuse - add documentation
Status: RESOLVED WONTFIX
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
: diagnostic, documentation
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2010-06-10 02:52 UTC by Jerry DeLisle
Modified: 2014-03-17 01:45 UTC (History)
1 user (show)

See Also:
Host:
Target: i686-pc-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-09-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jerry DeLisle 2010-06-10 02:52:36 UTC
This one was posted at gfortran.org

program f90_test
  implicit none
  integer :: ii8,ii4
  ii4=0
  ii8=522405223
  print'(z4)',ii4  
  print'(z12)',ii8
  print *, "z=", z'10000000'
  print *, transfer(ii8,z'10000000')
  print *, transfer(ii8,z'10000000')
  ii4=30292 !=z'7654'
  print'(z4)',ii4
  print'(z12)',ii8
end program f90_test

Repeated execution gives changing results for line 9. I have not investigated further yet.

$ ./a.out 
   0
    1F234567
 z=            268435456
    60197368789943655
            522405223
7654
    1F234567
$ ./a.out 
   0
    1F234567
 z=            268435456
    61446413999097191
            522405223
7654
    1F234567
$ ./a.out 
   0
    1F234567
 z=            268435456
    61358453068875111
            522405223
7654
    1F234567


Jerry
Comment 1 kargl 2010-06-10 04:24:50 UTC
This is probably a bogus PR.
The BOZ literal constants are INTEGER(16) entities
(at least of x86_64).  ii8 is an INTEGER(4) item.
The transfer() in the print statement is returning
a INTEGER(16) entity where only INTEGER(4) worth of
bits are set.

I've removed the 'wrong-code' keyword, because I
think you are getting processor dependent behavior.
In fact, the program might be nonconforming, but I'd
need to read up on transfer().
Comment 2 Jerry DeLisle 2010-06-10 04:37:34 UTC
Interesting!

  print *, "kind=", kind(transfer(ii4,z'10000000'))

On my system this gives kind = 8

Comment 3 Jerry DeLisle 2010-06-10 05:21:56 UTC
The result of transfer is largest kind of decimal.  Can be kind=8 or kind=16 depending on the system.  Maybe we should add some documentation in the manual on this. Thanks Steve for pointing this out.
Comment 4 kargl 2010-06-10 06:31:11 UTC
(In reply to comment #3)
> The result of transfer is largest kind of decimal.  Can be kind=8 or kind=16
> depending on the system.  Maybe we should add some documentation in the manual
> on this. Thanks Steve for pointing this out.
> 

Well, to be more exact,  the result of transfer() has the type
of its 2nd argument.  In transfer(ii8,z'1000'), the BOZ may have
a kind type parameter of 8 or 16 depending on the target; while
the INTEGER(4) ii8 can only supply 32 bits.  Note, the documentation
for transfer() already describes this situation without explicitly
mentioning BOZ literal constants.
Comment 5 Tobias Burnus 2010-06-10 07:25:44 UTC
I think there is another problem. Assuming the following program:

integer(4) :: i4
integer(8) :: i8
i4 = 1
i8 = transfer(i4, mold=i8)
end

The TRANSFER (as the one in comment 0) is partially undefined, but there is no warning. By contrast, NAG f95 warns:

  Warning: test.f90, line 4: Intrinsic TRANSFER has partly undefined result


Expected: A similar warning; we already have a check in simplify.c, but it seemingly does not work for this case:

  if (gfc_option.warn_surprising && source_size < result_size)
    gfc_warning("Intrinsic TRANSFER at %L has partly undefined result: "
                "source size %ld < result size %ld", &source->where,
                (long) source_size, (long) result_size);
Comment 6 Dominique d'Humieres 2013-09-04 07:53:30 UTC
I think the code in comment #0 is invalid (see also pr54072) per:

> C4102 (R463) A boz-literal-constant shall appear only as a 
> data-stmt-constant in a DATA statement, or where explicitly allowed 
> in subclause 13.7 as an actual argument of an intrinsic procedure.
>
> 13.7.168 TRANSFER (SOURCE, MOLD [, SIZE])
> ...
> MOLD shall be a scalar or array of any type. If it is a variable, 
> it need not be defined.

BOZ is not explicitly allowed here.

Note that compiling the code in comment#0 with -Wall gives the following warnings

pr44489.f90:9.20:

  print *, transfer(ii8,z'10000000')
                    1
Warning: Intrinsic TRANSFER at (1) has partly undefined result: source size 4 < result size 16
pr44489.f90:10.20:

  print *, transfer(ii8,z'10000000')
                    1
Warning: Intrinsic TRANSFER at (1) has partly undefined result: source size 4 < result size 16

(size 8 for 32 bit mode).
Comment 7 Jerry DeLisle 2014-03-17 01:45:06 UTC
No need to do anything here.