Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Something bad happened to my gfortran installation

130 views
Skip to first unread message

James Van Buskirk

unread,
Nov 22, 2010, 2:22:03 AM11/22/10
to
After months of trouble-free use, I installed the most recent
gfortran compilers from http://www.equation.com,
gcc-4.6-20101113-64.exe and gcc-4.6-20101120-32.exe and gfortran
doesn't work right any more. Even deleting all the old gfortran
files and installing an old compiler doesn't seem to help.

C:\gfortran\clf\mxcsr>type test5.f90
program test5
use ISO_C_BINDING
implicit none
type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type
type(CPUID_TYPE) result
character(16) string
real(10) x

result =
transfer(achar(10)//achar(0)//achar(0)//achar(0)//'GenuineIntel',result
)
write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)
write(*,*) len(string)
write(*,'(4(z8.8:1x))') result
result%eax = transfer(achar(10)//achar(0)//achar(0)//achar(0),result%eax)
result%ebx = transfer('Genu',result%ebx)
result%edx = transfer('ineI',result%edx)
result%ecx = transfer('ntel',result%ecx)
write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)
write(*,*) huge(x)
write(*,*) tiny(x)
end program test5

C:\gfortran\clf\mxcsr>gfortran test5.f90 -otest5

C:\gfortran\clf\mxcsr>test5
Max input value for basic CPUID: 10
Brand name:

16
0000000A 0000000A 0000000A 0000000A
Max input value for basic CPUID: 10
Brand name: GenuineIntel
n.inite ?B ? E+0000
0.0000000000000-(00000E-4933

C:\gfortran\clf\mxcsr>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.6.0/l
to-wrapper.exe
Target: x86_64-pc-mingw32
Configured with: ../gcc-4.6-20100626-mingw/configure
CFLAGS=-O0 --host=x86_64-pc
-mingw32 --build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/h
ome/gfortran/gcc-home/binary/mingw32/native/x86_64/gcc/4.6-20100626 --with-gmp=/
home/gfortran/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/
mingw32/cross/x86_64/gcc/4.6-20100626 --with-gcc --with-gnu-ld --with-gnu-as
--d
isable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c,
fortran,c++ --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.6.0 20100626 (experimental) (GCC)

Please let me know if you see something obviously wrong.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


James Van Buskirk

unread,
Nov 22, 2010, 1:17:48 PM11/22/10
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:icd5ms$afs$1...@news.eternal-september.org...

> string = transfer(result,string)

OK, what happened last night was that I was getting a Windows error
regarding data execution prevention. That seemed more or less normal
because I actually was poking machine code into memory and executing
it. The funny thing (after hours of debugging) was that even though
this was the first time I ever got this error from gfortran and it
was almost the first time to poke & call like this, the error had
nothing to do with my dubious coding practices (hear that, Richard?)

The error seems to be another bug in gfortran, and here is a brief
example that triggers it:

C:\gfortran\clf\mxcsr>type bug1b.f90
module utils
use ISO_C_BINDING
implicit none
private
public CPUID_TYPE


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

end module utils

program mxcsr_test
use ISO_C_BINDING
use utils
implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
! character(C_SIZEOF(result)) string
! character(16) string
character(C_SIZEOF(CPUID_type(0,0,0,0))) string

result = CPUID_TYPE(int(Z'0000000A'),int(Z'756E6547'), &
int(Z'49656E69'),int(Z'6C65746E'))


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)

write(*,'(4(z8.8:1x))') result

end program mxcsr_test

C:\gfortran\clf\mxcsr>gfortran -fno-range-check bug1b.f90 -obug1b

C:\gfortran\clf\mxcsr>bug1b


Max input value for basic CPUID: 10

And at this point I get the "Data Execution Prevention-Microsoft
Windows" popup that says "To help protext your computer, Windows
has closed this program."

The error seems to happen on the line:

string = transfer(result,string)

because when I comment it out the program runs to completion:

C:\gfortran\clf\mxcsr>type bug1b.f90
module utils
use ISO_C_BINDING
implicit none
private
public CPUID_TYPE


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

end module utils

program mxcsr_test
use ISO_C_BINDING
use utils
implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
! character(C_SIZEOF(result)) string
! character(16) string
character(C_SIZEOF(CPUID_type(0,0,0,0))) string

result = CPUID_TYPE(int(Z'0000000A'),int(Z'756E6547'), &
int(Z'49656E69'),int(Z'6C65746E'))


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax

! string = transfer(result,string)


write(*,'(a,a)') 'Brand name: ',string(5:16)

write(*,'(4(z8.8:1x))') result

end program mxcsr_test

C:\gfortran\clf\mxcsr>gfortran -fno-range-check bug1b.f90 -obug1b

C:\gfortran\clf\mxcsr>bug1b


Max input value for basic CPUID: 10

Brand name: =瓶+詔
0000000A 756E6547 49656E69 6C65746E

Albeit with nonsense results because variable string has never
been given a value. But it also requires the strined line:

character(C_SIZEOF(CPUID_type(0,0,0,0))) string

because when I switch over to:

character(16) string

It runs again:

C:\gfortran\clf\mxcsr>type bug1b.f90
module utils
use ISO_C_BINDING
implicit none
private
public CPUID_TYPE


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

end module utils

program mxcsr_test
use ISO_C_BINDING
use utils
implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
! character(C_SIZEOF(result)) string
character(16) string
! character(C_SIZEOF(CPUID_type(0,0,0,0))) string

result = CPUID_TYPE(int(Z'0000000A'),int(Z'756E6547'), &
int(Z'49656E69'),int(Z'6C65746E'))


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)

write(*,'(4(z8.8:1x))') result

end program mxcsr_test

C:\gfortran\clf\mxcsr>gfortran -fno-range-check bug1b.f90 -obug1b

C:\gfortran\clf\mxcsr>bug1b


Max input value for basic CPUID: 10
Brand name: GenuineIntel

0000000A 756E6547 49656E69 6C65746E

I had to use the fateful declaration because is I tried the more
normal:

character(C_SIZEOF(result)) string

I found that gfortran doesn't like it:

C:\gfortran\clf\mxcsr>type bug1b.f90
module utils
use ISO_C_BINDING
implicit none
private
public CPUID_TYPE


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

end module utils

program mxcsr_test
use ISO_C_BINDING
use utils
implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
character(C_SIZEOF(result)) string
! character(16) string
! character(C_SIZEOF(CPUID_type(0,0,0,0))) string

result = CPUID_TYPE(int(Z'0000000A'),int(Z'756E6547'), &
int(Z'49656E69'),int(Z'6C65746E'))


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)

write(*,'(4(z8.8:1x))') result

end program mxcsr_test

C:\gfortran\clf\mxcsr>gfortran -fno-range-check bug1b.f90 -obug1b
bug1b.f90:23.22:

character(C_SIZEOF(result)) string
1
Error: Variable 'result' cannot appear in the expression at (1)
bug1b.f90:23.37:

character(C_SIZEOF(result)) string
1
Error: 'string' at (1) must have constant character length in this context

Even though it's OK in F08. See section 7.1.11 about specification
inquiry:

"A specification inquiry is a reference to
...
(4) the function C_SIZEOF from the intrinsic module ISO C BINDING
(15.2.3.7)"

and section 7.1.12 about constant expressions:

"A constant expression is an expression with limitations that make
it suitable for use as a kind type parameter, initializer, or named
constant. It is an expression in which each operation is intrinsic,
and each primary is
...
(4) a specification inquiry where each designator or function argument is
(a) a constant expression or
(b) a variable whose properties inquired about are not
(i) assumed,
(ii) deferred, or
(iii) defined by an expression that is not a constant expression"

Looking at disassemblies I get the impression that gfortran for some
reason best known to itself does some sort of convoluted song and
dance to determine the address of variable string and the address
seems to lie below the stack frame so that it can either get
overwritten on any random function call or can overwrite return
addresses when written to. This problem only seems to be happening
in 32-bit gfortran; I'm not sure whether the 64-bit version is immune
or whether it's just luck that it doesn't get triggered there.

C:\gfortran\clf\mxcsr>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran

COLLECT_LTO_WRAPPER=c:/gcc_equation32/bin/../libexec/gcc/i686-pc-mingw32/4.6.0/l
to-wrapper.exe
Target: i686-pc-mingw32
Thread model: win32
gcc version 4.6.0 20101113 (experimental) (GCC)

Well, that's the best I can do as far as narrowing this issue down.
Do what you will with the information.

James Van Buskirk

unread,
Nov 22, 2010, 9:46:08 PM11/22/10
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:icec4e$34e$1...@news.eternal-september.org...

> OK, what happened last night was that I was getting a Windows error
> regarding data execution prevention. That seemed more or less normal
> because I actually was poking machine code into memory and executing
> it. The funny thing (after hours of debugging) was that even though
> this was the first time I ever got this error from gfortran and it
> was almost the first time to poke & call like this, the error had
> nothing to do with my dubious coding practices (hear that, Richard?)

Another thing that slowed me down was that the installer for the
www.equation.com builds helpfully modifies your PATH environmental
variable without giving you the chance to opt out. Thus while
switching back and forth between versions of the compiler I wasn't
necessarily always invoking the latest version installed. For that
reason it looked like I had really messed things up because as I
switched to a compiler that I thought didn't have the same problems
I was really using the last one I tried...

The fact that gfortran was using all this complicated code at run-
time to compute the address of variable string led me to doubt that
gfortran was using its initialization expression evaluation
mechanism to compute its length. If it did, gfortran should have
just filled in the expression C_SIZEOF(CPUID_type(0,0,0,0)) with
its value of 16 and worked as it did when the hardwired value of
16 was inserted. Accordingly, I made up some tests to determine
whether gfortran thought that these expressions were initialization
expressions or not:

C:\gfortran\clf\mxcsr>type bug2.f90
module M


use ISO_C_BINDING
implicit none
private

public T
type, bind(C) :: T
integer(C_INT32_T) a
integer(C_INT32_T) b
integer(C_INT32_T) c
integer(C_INT32_T) d
end type T
end module M

program P
use M
implicit none
type(T) :: R = T(0,0,0,0)

write(*,'(a)') 'First make call with guaranteed constant expression'
call sub1(1)
write(*,'(/a)') 'Next make call with guaranteed non-constant expression'
call sub2(1)
write(*,'(/a)') 'Now test with C_SIZEOF(R)'
call sub3(1,R)
! write(*,'(/a)') 'This test incorrectly fails to compile'
! call sub4(1)
write(*,'(/a)') 'Now test with C_SIZEOF(T(0,0,0,0))'
call sub5(1)
write(*,'(/a)') 'Now test with SIZEOF(R)'
call sub6(1,R)
! write(*,'(/a)') 'This test incorrectly fails to compile'
! call sub7(1)
write(*,'(/a)') 'Now test with SIZEOF(T(0,0,0,0))'
call sub8(1)
end program P

recursive subroutine sub1(depth)
implicit none
integer depth
character(16) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub1(depth+1)
write(*,'(a)') trim(string)
end if
end subroutine sub1

recursive subroutine sub2(depth)
implicit none
integer depth
character(0*depth+16) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub2(depth+1)
write(*,'(a)') trim(string)
end if
end subroutine sub2

recursive subroutine sub3(depth,R)
use M
implicit none
integer depth
type(T) R
character(C_SIZEOF(R)) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub3(depth+1,R)
write(*,'(a)') trim(string)
end if
end subroutine sub3

!recursive subroutine sub4(depth)
! use M
! implicit none
! integer depth
! type(T) R
! character(C_SIZEOF(R)) string
! save
!
! write(string,'(a,i0)') 'Depth is ',depth
! write(*,'(a)') trim(string)
! if(depth < 3) then
! call sub4(depth+1)
! write(*,'(a)') trim(string)
! end if
!end subroutine sub4

recursive subroutine sub5(depth)
use M
implicit none
integer depth
character(C_SIZEOF(T(0,0,0,0))) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub5(depth+1)
write(*,'(a)') trim(string)
end if
end subroutine sub5

recursive subroutine sub6(depth,R)
use M
implicit none
integer depth
type(T) R
character(SIZEOF(R)) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub6(depth+1,R)
write(*,'(a)') trim(string)
end if
end subroutine sub6

!recursive subroutine sub7(depth)
! use M
! implicit none
! integer depth
! type(T) R
! character(SIZEOF(R)) string
! save
!
! write(string,'(a,i0)') 'Depth is ',depth
! write(*,'(a)') trim(string)
! if(depth < 3) then
! call sub7(depth+1)
! write(*,'(a)') trim(string)
! end if
!end subroutine sub7

recursive subroutine sub8(depth)
use M
implicit none
integer depth
character(SIZEOF(T(0,0,0,0))) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub8(depth+1)
write(*,'(a)') trim(string)
end if
end subroutine sub8

C:\gfortran\clf\mxcsr>gfortran bug2.f90 -obug2

C:\gfortran\clf\mxcsr>bug2
First make call with guaranteed constant expression
Depth is 1
Depth is 2
Depth is 3
Depth is 3
Depth is 3

Next make call with guaranteed non-constant expression
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

Now test with C_SIZEOF(R)
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

Now test with C_SIZEOF(T(0,0,0,0))
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

Now test with SIZEOF(R)
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

Now test with SIZEOF(T(0,0,0,0))
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

We can see that for an initialization expression, the depths should
print as 1,2,3,3,3, whereas for a non-initialization expression
depths should read 1,2,3,2,1 from the first two tests. So gfortran
prints out the wrong results for sub3 and sub5 and fails to compile
sub4 when it should. Anything it does for sub6:8 is a bug because
gfortran doesn't document whether its SIZEOF extension qualifies as
a specification inquiry or not. One might hope that it should be
a specification inquiry just like C_SIZEOF. Another issue: C_SIZEOF
is from the ISO_C_BINDING module which wasn't USEd in sub3:5 so its
interface wasn't explicit there and the code should possibly have been
rejected because a specification function must be PURE, requiring an
explicit interface. I don't know whether the compiler is allowed to
also consider procedures from ISO_C_BINDING to be also intrinsics as
an extension, so maybe the interface was explicit, if undocumented.

C:\gfortran\clf\mxcsr>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran

COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.6.0/l
to-wrapper.exe
Target: x86_64-pc-mingw32
Configured with: ../gcc-4.6-20100626-mingw/configure
CFLAGS=-O0 --host=x86_64-pc
-mingw32 --build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/h
ome/gfortran/gcc-home/binary/mingw32/native/x86_64/gcc/4.6-20100626 --with-gmp=/
home/gfortran/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/
mingw32/cross/x86_64/gcc/4.6-20100626 --with-gcc --with-gnu-ld --with-gnu-as
--d
isable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c,
fortran,c++ --enable-threads=win32 --disable-win32-registry

Thread model: win32
gcc version 4.6.0 20100626 (experimental) (GCC)

steve

unread,
Nov 23, 2010, 3:08:32 PM11/23/10
to
On Nov 22, 6:46 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:

> We can see that for an initialization expression, the depths should
> print as 1,2,3,3,3, whereas for a non-initialization expression
> depths should read 1,2,3,2,1 from the first two tests.  So gfortran
> prints out the wrong results for sub3 and sub5 and fails to compile
> sub4 when it should.  Anything it does for sub6:8 is a bug because
> gfortran doesn't document whether its SIZEOF extension qualifies as
> a specification inquiry or not.  One might hope that it should be
> a specification inquiry just like C_SIZEOF.  Another issue: C_SIZEOF
> is from the ISO_C_BINDING module which wasn't USEd in sub3:5 so its
> interface wasn't explicit there and the code should possibly have been
> rejected because a specification function must be PURE, requiring an
> explicit interface.  I don't know whether the compiler is allowed to
> also consider procedures from ISO_C_BINDING to be also intrinsics as
> an extension, so maybe the interface was explicit, if undocumented.

Perhaps, you need to report a bug to equation.com.

laptop:kargl[5] gfc4x -o z j3.f90
j3.f90:70.13:

character(C_SIZEOF(R)) string
1
Error: Function 'c_sizeof' at (1) has no IMPLICIT type
j3.f90:101.13:

character(C_SIZEOF(T(0,0,0,0))) string

Error: Function 'c_sizeof' at (1) has no IMPLICIT type
1

gcc version 4.6.0 20101117 (experimental) (GCC)

--
steve

James Van Buskirk

unread,
Nov 23, 2010, 10:21:05 PM11/23/10
to
"steve" <kar...@comcast.net> wrote in message
news:7e6eb91e-5d71-43bd...@g26g2000vba.googlegroups.com...

> Perhaps, you need to report a bug to equation.com.

> laptop:kargl[5] gfc4x -o z j3.f90
> j3.f90:70.13:

> character(C_SIZEOF(R)) string
1
> Error: Function 'c_sizeof' at (1) has no IMPLICIT type
> j3.f90:101.13:

> character(C_SIZEOF(T(0,0,0,0))) string

> Error: Function 'c_sizeof' at (1) has no IMPLICIT type
> 1

> gcc version 4.6.0 20101117 (experimental) (GCC)

Thanks for taking a look at this, Steve. I rolled back my gfortran
installation because of a regression. Here's what happens with the
version gcc-4.6-20100626-64.exe:

C:\gfortran\clf\mxcsr>type bug1b.f90
module utils


use ISO_C_BINDING
implicit none
private

C:\gfortran\clf\mxcsr>gfortran bug1b.f90 -obug1b

C:\gfortran\clf\mxcsr>bug1b
Max input value for basic CPUID: 10
Brand name: GenuineIntel
0000000A 756E6547 49656E69 6C65746E

C:\gfortran\clf\mxcsr>gfortran -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.6.0/l
to-wrapper.exe
Target: x86_64-pc-mingw32
Configured with: ../gcc-4.6-20100626-mingw/configure
CFLAGS=-O0 --host=x86_64-pc
-mingw32 --build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/h
ome/gfortran/gcc-home/binary/mingw32/native/x86_64/gcc/4.6-20100626 --with-gmp=/
home/gfortran/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/
mingw32/cross/x86_64/gcc/4.6-20100626 --with-gcc --with-gnu-ld --with-gnu-as
--d
isable-shared --disable-nls --disable-tls --enable-libgomp --enable-languages=c,
fortran,c++ --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.6.0 20100626 (experimental) (GCC)

So the program I was working on made it OK. Now with the latest you
can get of 64-bit versions an www.equation.com, gcc-4.6-20101113-64.exe:

C:\gfortran\clf\mxcsr>gfortran bug1b.f90 -obug1b

C:\gfortran\clf\mxcsr>bug1b
Max input value for basic CPUID: 10

Brand name: ??"
0000000A 756E6547 49656E69 6C65746E

C:\gfortran\clf\mxcsr>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran

COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.0/
lto-wrapper.exe
Target: x86_64-w64-mingw32
Thread model: win32
gcc version 4.6.0 20101113 (experimental) (GCC)

So you can see that also the 64-bit version of gfortran has this
regression on at least one specification expression. This time,
instead of overwriting the return address on the stack during
execution of _memmove during that fateful
string = TRANSFER(result,string) statement, we see the other
possibility that a function call overwrites string on the stack.
Since the ABI for 32-bit Windows and 32-bit BSD are pretty similar,
could you try the above program at your end and see if you have the
same regression?

Now let's get back to the test of whether gfortran correctly
identifies initialization expression with this latest version:

C:\gfortran\clf\mxcsr>gfortran bug2.f90 -obug2

bug2.f90:70.13:

character(C_SIZEOF(R)) string
1
Error: Function 'c_sizeof' at (1) has no IMPLICIT type

bug2.f90:101.13:

character(C_SIZEOF(T(0,0,0,0))) string


1
Error: Function 'c_sizeof' at (1) has no IMPLICIT type

OK, so it detects the problem where I forgot to USE ISO_C_BINDING.
Let's correct our omission and retry:

use ISO_C_BINDING, only: C_SIZEOF


implicit none
integer depth
type(T) R
character(C_SIZEOF(R)) string
save

write(string,'(a,i0)') 'Depth is ',depth
write(*,'(a)') trim(string)
if(depth < 3) then
call sub3(depth+1,R)
write(*,'(a)') trim(string)
end if
end subroutine sub3

!recursive subroutine sub4(depth)
! use M

! use ISO_C_BINDING, only: C_SIZEOF


! implicit none
! integer depth
! type(T) R
! character(C_SIZEOF(R)) string
! save
!
! write(string,'(a,i0)') 'Depth is ',depth
! write(*,'(a)') trim(string)
! if(depth < 3) then
! call sub4(depth+1)
! write(*,'(a)') trim(string)
! end if
!end subroutine sub4

recursive subroutine sub5(depth)
use M

use ISO_C_BINDING, only: C_SIZEOF

Now test with C_SIZEOF(T(0,0,0,0))
??" ?"
¼?" á?"
L?" @?"
ÿ?" É?"
°?" ??"

Now test with SIZEOF(R)
Depth is 1
Depth is 2
Depth is 3
Depth is 2
Depth is 1

Now test with SIZEOF(T(0,0,0,0))
??" ?"
¼?" á?"
L?" @?"
ÿ?" É?"
°?" ??"

So gfortran still is doing the wrong thing with C_SIZEOF(R) and
SIZEOF(R): not taking into account that these (at least the first)
are specification inquiries. It's kind of hard to know directly
whether it's getting C_SIZEOF(T(0,0,0,0)) and SIZEOF(T(0,0,0,0))
right because they trigger the regression, but if gfortran really
thought they were initialization expressions it should have had the
same result as if these were replaced by 16, but that was subroutine
sub1 which worked OK. Oh yes, there is another issue in that the
original code way back up at the top of this post also has
C_SIZEOF(CPUID_TYPE(0,0,0,0)) as a specification expression in the
main program, but since gfortran thinks that isn't an initialization
expression, it should error out because automatic data objects aren't
allowed in the main program.

The original program, the one that started all this trouble, was one
that checked the x87 FCW. I wanted to see if you could try running
it because of the singular results you posted for REAL(KIND=10)
variables. I was thinking that maybe your Fortran processor set
precision to 53 bits and wanted to see if that was true. Here is
the program, now with the workaround that the length of string
is given directly as 16 instead of by the specification expression
C_SIZEOF(CPUID_type(0,0,0,0)), this time with the 32-bit build
gcc-4.6-20101113-32.exe:

C:\gfortran\clf\mxcsr>type utils.f90
module utils


use ISO_C_BINDING
implicit none
private

public utils_init, ldmxcsr, stmxcsr, fstsw, fstcw, fldcw, &
fclex, rdtsc, CPUID_type, cpuid
integer(C_INT8_T) BAD_STUFF(224)
data BAD_STUFF / &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'89', Z'4C', Z'24', &
Z'08', Z'0F', Z'AE', Z'54', Z'24', Z'08', Z'C3', Z'0F', &
Z'AE', Z'54', Z'24', Z'04', Z'C3', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'0F', Z'AE', Z'5C', &
Z'24', Z'08', Z'8B', Z'44', Z'24', Z'08', Z'C3', Z'50', &
Z'0F', Z'AE', Z'1C', Z'24', Z'58', Z'C3', Z'90', Z'90', &
Z'31', Z'C0', Z'DF', Z'E0', Z'C3', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'D9', Z'7C', Z'24', &
Z'08', Z'66', Z'8B', Z'44', Z'24', Z'08', Z'C3', Z'50', &
Z'D9', Z'3C', Z'24', Z'58', Z'C3', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'66', Z'89', Z'4C', &
Z'24', Z'08', Z'D9', Z'6C', Z'24', Z'08', Z'C3', Z'D9', &
Z'6C', Z'24', Z'04', Z'C3', Z'90', Z'90', Z'90', Z'90', &
Z'DB', Z'E2', Z'C3', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'0F', Z'31', Z'48', &
Z'C1', Z'E2', Z'20', Z'48', Z'09', Z'D0', Z'C3', Z'0F', &
Z'31', Z'C3', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'18', Z'53', Z'89', Z'D0', &
Z'49', Z'87', Z'C8', Z'0F', Z'A2', Z'49', Z'90', Z'44', &
Z'89', Z'00', Z'89', Z'58', Z'04', Z'89', Z'50', Z'08', &
Z'89', Z'48', Z'0C', Z'5B', Z'C3', Z'53', Z'56', Z'8B', &
Z'44', Z'24', Z'10', Z'8B', Z'4C', Z'24', Z'14', Z'0F', &
Z'A2', Z'8B', Z'74', Z'24', Z'0C', Z'89', Z'06', Z'89', &
Z'5E', Z'04', Z'89', Z'56', Z'08', Z'89', Z'4E', Z'0C', &
Z'5E', Z'5B', Z'C3', Z'90', Z'90', Z'90', Z'90', Z'90' /


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

abstract interface
subroutine ldmxcsr_template(source) bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT32_T), value :: source
end subroutine ldmxcsr_template
function stmxcsr_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT32_T) :: stmxcsr_template
end function stmxcsr_template
function fstsw_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T) :: fstsw_template
end function fstsw_template
function fstcw_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T) :: fstcw_template
end function fstcw_template
subroutine fldcw_template(source) bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T), value :: source
end subroutine fldcw_template
subroutine fclex_template() bind(C)
use ISO_C_BINDING
implicit none
end subroutine fclex_template
function rdtsc_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT64_T) :: rdtsc_template
end function rdtsc_template
subroutine cpuid_template(result,eax,ecx) bind(C)
use ISO_C_BINDING
import CPUID_type
implicit none
type(CPUID_type) :: result
integer(C_INT32_T), value :: eax
integer(C_INT32_T), value :: ecx
end subroutine cpuid_template
end interface
procedure(ldmxcsr_template), pointer :: ldmxcsr => NULL()
procedure(stmxcsr_template), pointer :: stmxcsr => NULL()
procedure(fstsw_template), pointer :: fstsw => NULL()
procedure(fstcw_template), pointer :: fstcw => NULL()
procedure(fldcw_template), pointer :: fldcw => NULL()
procedure(fclex_template), pointer :: fclex => NULL()
procedure(rdtsc_template), pointer :: rdtsc => NULL()
procedure(cpuid_template), pointer :: cpuid => NULL()
interface
function VirtualAlloc(lpAddress, dwSize, flAllocationType, &
flProtect) bind(C, name = 'VirtualAlloc')
use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: VirtualAlloc
type(C_PTR) VirtualAlloc
type(C_PTR), value :: lpAddress
integer(C_SIZE_T), value :: dwSize
integer(C_LONG), value :: flAllocationType
integer(C_LONG), value :: flProtect
end function VirtualAlloc
function GetLastError() bind(C,name='GetLastError')
use ISO_C_BINDING
implicit none
!GCC$ ATTRIBUTES STDCALL :: GetLastError
integer(C_LONG) GetLastError
end function GetLastError
end interface
contains
subroutine utils_init()
type(C_PTR) address
integer(C_INTPTR_T) temp
integer(C_LONG) error
integer(C_INT8_T), pointer :: temp_ptr(:)
type(C_FUNPTR) fun_address
logical :: first = .TRUE.

if(.NOT.first) return
first = .FALSE.
address = VirtualAlloc(C_NULL_PTR, &
size(BAD_STUFF,kind=C_SIZE_T),int(Z'1000',C_LONG), &
int(Z'40',C_LONG))
if(.NOT.C_ASSOCIATED(address)) then
error = GetLastError()
write(*,'(a,z0,a)') "Error Z'",error,"' allocating memory"
stop
end if
call C_F_POINTER(address, temp_ptr, shape(BAD_STUFF))
temp_ptr = BAD_STUFF
temp = transfer(address, temp)
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, ldmxcsr)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, stmxcsr)
temp = temp+24
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fstsw)
temp = temp+8
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fstcw)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fldcw)
temp = temp+24
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fclex)
temp = temp+8
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, rdtsc)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, cpuid)
end subroutine utils_init
end module utils

module nudge_FSW
implicit none
integer, parameter :: dp = kind(1.0d0)
integer, parameter :: ep_preferred = selected_real_kind(18,4931)
integer, parameter :: ep = &
(1+sign(1,ep_preferred))/2*ep_preferred+ &
(1-sign(1,ep_preferred))/2*dp
private
public ep, set_inexact
contains
subroutine set_inexact(x,y,z)
real(ep) x, y, z
x = y*z
end subroutine set_inexact
end module nudge_FSW

program mxcsr_test
use ISO_C_BINDING
use utils

use nudge_FSW


implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
! character(C_SIZEOF(result)) string

! character(C_SIZEOF(CPUID_type(0,0,0,0))) string
character(16) string
real(ep) alpha
real(ep) :: beta = 4*atan(1.0_ep)
real(ep) :: gamma = sqrt(2.0_ep)

write(*,'(a,i0,a)') 'This is a ', &
bit_size(1_C_INTPTR_T),'-bit processor'
call utils_init
ts1 = rdtsc()
reg = stmxcsr()
ts2 = rdtsc()
write(*,'(a,i0)') 'Time read from TSC: ',ts2-ts1
write(*,'(a,z0.8)') 'Initial value of MXCSR: ',reg
reg = ibclr(reg,9)
write(*,'(a,z0.8)') 'Value to be stored in MXCSR: ',reg
call ldmxcsr(reg)
reg = stmxcsr()
write(*,'(a,z0.8)') 'Value read from MXCSR: ',reg
cw = fstcw()
write(*,'(a,z0.4)') 'Initial value of FCW: ',cw
cw = ibclr(cw, 2)
write(*,'(a,z0.4)') 'Value to be stored in FCW: ',cw
call fldcw(cw)
cw = fstcw()
write(*,'(a,z0.4)') 'Value read from FCW: ',cw
sw = fstsw()
write(*,'(a,z0.4)') 'Initial value of FSW: ',sw
call set_inexact(alpha, beta, gamma)
sw = fstsw()
write(*,'(a,z0.4)') 'Value of FSW after inexact: ',sw
call fclex
sw = fstsw()
write(*,'(a,z0.4)') 'Value of FSW after FCLEX: ',sw
eax = 0
ecx = 0
call cpuid(result, eax, ecx)


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)

!write(*,*) len(string)


write(*,'(4(z8.8:1x))') result

! Get ep parameters
write(*,'(a,g14.6)') 'epsilon = ', epsilon(alpha)
! write(*,'(a,g14.6)') 'huge = ', huge(alpha)
write(*,*) 'huge = ', huge(alpha)
write(*,'(a,i0)') 'precision = ', precision(alpha)
write(*,'(a,i0)') 'range = ', range(alpha)
write(*,'(a,i0)') 'sizeof = ', sizeof(alpha)
! write(*,'(a,e15.6)') 'tiny = ', tiny(alpha)
write(*,*) 'tiny = ', tiny(alpha)
end program mxcsr_test

C:\gfortran\clf\mxcsr>gfortran -fno-range-check utils.f90 -outils

C:\gfortran\clf\mxcsr>utils
This is a 32-bit processor
Time read from TSC: 430
Initial value of MXCSR: 00001F80
Value to be stored in MXCSR: 00001D80
Value read from MXCSR: 00001D80
Initial value of FCW: 037F
Value to be stored in FCW: 037B
Value read from FCW: 037B
Initial value of FSW: 0000
Value of FSW after inexact: 0020
Value of FSW after FCLEX: 0000


Max input value for basic CPUID: 10
Brand name: GenuineIntel
0000000A 756E6547 49656E69 6C65746E

epsilon = 0.108420E-18
huge = n.inite ??wX²j ° ? E+0000
precision = 18
range = 4931
sizeof = 12
tiny = 0.0000000000000-(00000E-4933

You can see that the FCW is initialized to Z'037F' on my system.
The above won't work on your end of the wire because of the Win32
API calls. My best guess is that:

C:\gfortran\clf\mxcsr>type utils_linux.f90
module utils


use ISO_C_BINDING
implicit none
private

public utils_init, ldmxcsr, stmxcsr, fstsw, fstcw, fldcw, &
fclex, rdtsc, CPUID_type, cpuid
integer(C_INT8_T) BAD_STUFF(216)
data BAD_STUFF / &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'89', Z'7C', Z'24', &
Z'F8', Z'0F', Z'AE', Z'54', Z'24', Z'F8', Z'C3', Z'0F', &
Z'AE', Z'54', Z'24', Z'04', Z'C3', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'0F', Z'AE', Z'5C', &
Z'24', Z'F8', Z'8B', Z'44', Z'24', Z'F8', Z'C3', Z'50', &
Z'0F', Z'AE', Z'1C', Z'24', Z'58', Z'C3', Z'90', Z'90', &
Z'31', Z'C0', Z'DF', Z'E0', Z'C3', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'D9', Z'7C', Z'24', &
Z'F8', Z'66', Z'8B', Z'44', Z'24', Z'F8', Z'C3', Z'50', &
Z'D9', Z'3C', Z'24', Z'58', Z'C3', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'66', Z'89', Z'7C', &
Z'24', Z'F8', Z'D9', Z'6C', Z'24', Z'F8', Z'C3', Z'D9', &
Z'6C', Z'24', Z'04', Z'C3', Z'90', Z'90', Z'90', Z'90', &
Z'DB', Z'E2', Z'C3', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'0A', Z'0F', Z'31', Z'48', &
Z'C1', Z'E2', Z'20', Z'48', Z'09', Z'D0', Z'C3', Z'0F', &
Z'31', Z'C3', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', Z'90', &
Z'31', Z'C0', Z'40', Z'75', Z'14', Z'53', Z'89', Z'F0', &
Z'89', Z'D1', Z'0F', Z'A2', Z'89', Z'07', Z'89', Z'5F', &
Z'04', Z'89', Z'57', Z'08', Z'89', Z'4F', Z'0C', Z'5B', &
Z'C3', Z'53', Z'56', Z'8B', Z'44', Z'24', Z'10', Z'8B', &
Z'4C', Z'24', Z'14', Z'0F', Z'A2', Z'8B', Z'74', Z'24', &
Z'0C', Z'89', Z'06', Z'89', Z'5E', Z'04', Z'89', Z'56', &
Z'08', Z'89', Z'4E', Z'0C', Z'5E', Z'5B', Z'C3', Z'90' /


type, bind(C) :: CPUID_type
integer(C_INT32_T) eax
integer(C_INT32_T) ebx
integer(C_INT32_T) edx
integer(C_INT32_T) ecx
end type CPUID_type

abstract interface
subroutine ldmxcsr_template(source) bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT32_T), value :: source
end subroutine ldmxcsr_template
function stmxcsr_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT32_T) :: stmxcsr_template
end function stmxcsr_template
function fstsw_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T) :: fstsw_template
end function fstsw_template
function fstcw_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T) :: fstcw_template
end function fstcw_template
subroutine fldcw_template(source) bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT16_T), value :: source
end subroutine fldcw_template
subroutine fclex_template() bind(C)
use ISO_C_BINDING
implicit none
end subroutine fclex_template
function rdtsc_template() bind(C)
use ISO_C_BINDING
implicit none
integer(C_INT64_T) :: rdtsc_template
end function rdtsc_template
subroutine cpuid_template(result,eax,ecx) bind(C)
use ISO_C_BINDING
import CPUID_type
implicit none
type(CPUID_type) :: result
integer(C_INT32_T), value :: eax
integer(C_INT32_T), value :: ecx
end subroutine cpuid_template
end interface
procedure(ldmxcsr_template), pointer :: ldmxcsr => NULL()
procedure(stmxcsr_template), pointer :: stmxcsr => NULL()
procedure(fstsw_template), pointer :: fstsw => NULL()
procedure(fstcw_template), pointer :: fstcw => NULL()
procedure(fldcw_template), pointer :: fldcw => NULL()
procedure(fclex_template), pointer :: fclex => NULL()
procedure(rdtsc_template), pointer :: rdtsc => NULL()
procedure(cpuid_template), pointer :: cpuid => NULL()
interface
function mmap(start, length, prot, flags, fd, offset) &
bind(C,name='mmap')
use ISO_C_BINDING
implicit none
type(C_PTR) mmap
type(C_PTR), value :: start
integer(C_SIZE_T), value :: length
integer(C_INT), value :: prot
integer(C_INT), value :: flags
integer(C_INT), value :: fd
integer(C_INT64_T), value :: offset
end function mmap
end interface
contains
subroutine utils_init()
type(C_PTR) address
integer(C_INTPTR_T) temp
integer(C_LONG) error
integer(C_INT8_T), pointer :: temp_ptr(:)
type(C_FUNPTR) fun_address
logical :: first = .TRUE.

if(.NOT.first) return
first = .FALSE.
address = mmap(C_NULL_PTR,size(BAD_STUFF,kind=C_SIZE_T), &
7_C_INT,int(Z'1002',C_INT),-1_C_INT,0_C_INT64_T)
if(.NOT.C_ASSOCIATED(address)) then
! How does Fortran get errno?
write(*,'(a)') "Error allocating memory"
stop
end if
call C_F_POINTER(address, temp_ptr, shape(BAD_STUFF))
temp_ptr = BAD_STUFF
temp = transfer(address, temp)
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, ldmxcsr)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, stmxcsr)
temp = temp+24
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fstsw)
temp = temp+8
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fstcw)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fldcw)
temp = temp+24
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, fclex)
temp = temp+8
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, rdtsc)
temp = temp+32
fun_address = transfer(temp, fun_address)
call C_F_PROCPOINTER(fun_address, cpuid)
end subroutine utils_init
end module utils

module nudge_FSW
implicit none
integer, parameter :: dp = kind(1.0d0)
! integer, parameter :: ep_preferred = selected_real_kind(18,4931)
! integer, parameter :: ep = &
! (1+sign(1,ep_preferred))/2*ep_preferred+ &
! (1-sign(1,ep_preferred))/2*dp
integer, parameter :: ep = 10
private
public ep, set_inexact
contains
subroutine set_inexact(x,y,z)
real(ep) x, y, z
x = y*z
end subroutine set_inexact
end module nudge_FSW

program mxcsr_test
use ISO_C_BINDING
use utils

use nudge_FSW


implicit none
integer(C_INT32_T) reg
integer(C_INT64_T) ts1, ts2
integer(C_INT16_T) sw, cw
integer(C_INT32_T) eax, ecx
type(CPUID_type) result
! character(C_SIZEOF(result)) string

! character(C_SIZEOF(CPUID_type(0,0,0,0))) string
character(16) string
real(ep) alpha
real(ep) :: beta = 4*atan(1.0_ep)
real(ep) :: gamma = sqrt(2.0_ep)

write(*,'(a,i0,a)') 'This is a ', &
bit_size(1_C_INTPTR_T),'-bit processor'
call utils_init
ts1 = rdtsc()
reg = stmxcsr()
ts2 = rdtsc()
write(*,'(a,i0)') 'Time read from TSC: ',ts2-ts1
write(*,'(a,z0.8)') 'Initial value of MXCSR: ',reg
reg = ibclr(reg,9)
write(*,'(a,z0.8)') 'Value to be stored in MXCSR: ',reg
call ldmxcsr(reg)
reg = stmxcsr()
write(*,'(a,z0.8)') 'Value read from MXCSR: ',reg
cw = fstcw()
write(*,'(a,z0.4)') 'Initial value of FCW: ',cw
cw = ibclr(cw, 2)
write(*,'(a,z0.4)') 'Value to be stored in FCW: ',cw
call fldcw(cw)
cw = fstcw()
write(*,'(a,z0.4)') 'Value read from FCW: ',cw
sw = fstsw()
write(*,'(a,z0.4)') 'Initial value of FSW: ',sw
call set_inexact(alpha, beta, gamma)
sw = fstsw()
write(*,'(a,z0.4)') 'Value of FSW after inexact: ',sw
call fclex
sw = fstsw()
write(*,'(a,z0.4)') 'Value of FSW after FCLEX: ',sw
eax = 0
ecx = 0
call cpuid(result, eax, ecx)


write(*,'(a,i0)') 'Max input value for basic CPUID: ', result%eax
string = transfer(result,string)
write(*,'(a,a)') 'Brand name: ',string(5:16)

! Get ep parameters
write(*,'(a,g14.6)') 'epsilon = ', epsilon(alpha)
write(*,*) 'huge = ', huge(alpha)
write(*,'(a,i0)') 'precision = ', precision(alpha)
write(*,'(a,i0)') 'range = ', range(alpha)
write(*,'(a,i0)') 'sizeof = ', sizeof(alpha)
write(*,*) 'tiny = ', tiny(alpha)
end program mxcsr_test

is what might work over there. If you are brave enough to run
code from someone out on the internet whose image you have never
seen that pokes machine code into memory and then jumps to it...
I would be very curious as to the output you get from the above
code.

steve

unread,
Nov 23, 2010, 11:25:43 PM11/23/10
to
> So the program I was working on made it OK.  Now with the latest you
> can get of 64-bit versions an www.equation.com, gcc-4.6-20101113-64.exe:
>
> C:\gfortran\clf\mxcsr>gfortran bug1b.f90 -obug1b
>
> C:\gfortran\clf\mxcsr>bug1b
> Max input value for basic CPUID: 10
> Brand name:     ??"
> 0000000A 756E6547 49656E69 6C65746E
>
> So you can see that also the 64-bit version of gfortran has this
> regression on at least one specification expression.  This time,
> instead of overwriting the return address on the stack during
> execution of _memmove during that fateful
> string = TRANSFER(result,string) statement, we see the other
> possibility that a function call overwrites string on the stack.
> Since the ABI for 32-bit Windows and 32-bit BSD are pretty similar,
> could you try the above program at your end and see if you have the
> same regression?

I only have fairly recent trunk on my laptop along with 4.4
and 4.5. I've removed the writes from your code to simply
the -fdump-tree-original output. I see

laptop:kargl[72] gfortran44 -o z j5.f90 && ./z
laptop:kargl[73] gfortran45 -o z j5.f90 && ./z
laptop:kargl[74] gfc4x -o z j5.f90 && ./z
Segmentation fault (core dumped)

Looks like someone may have broken TRANSFER. I haven't
looked for the cause, yet.

> Now test with SIZEOF(T(0,0,0,0))
> ??"      ?"
> ¼?"     á?"
> L?"     @?"
> ÿ?"     É?"
> °?"     ??"
>
> So gfortran still is doing the wrong thing with C_SIZEOF(R) and
> SIZEOF(R): not taking into account that these (at least the first)
> are specification inquiries.  It's kind of hard to know directly
> whether it's getting C_SIZEOF(T(0,0,0,0)) and SIZEOF(T(0,0,0,0))
> right because they trigger the regression, but if gfortran really
> thought they were initialization expressions it should have had the
> same result as if these were replaced by 16, but that was subroutine
> sub1 which worked OK.  Oh yes, there is another issue in that the
> original code way back up at the top of this post also has
> C_SIZEOF(CPUID_TYPE(0,0,0,0)) as a specification expression in the
> main program, but since gfortran thinks that isn't an initialization
> expression, it should error out because automatic data objects aren't
> allowed in the main program.

This may related to the absences of simplification routines. I need
to check, but I think the frontend may not be replacing the [C_]SIZEOF
until it is too late.

> The original program, the one that started all this trouble, was one
> that checked the x87 FCW.  I wanted to see if you could try running
> it because of the singular results you posted for REAL(KIND=10)
> variables.  I was thinking that maybe your Fortran processor set
> precision to 53 bits and wanted to see if that was true.  Here is
> the program, now with the workaround that the length of string

> is given...

The results aren't singular to the extent that this is the
expected behavior on FreeBSD. REAL(10) maps to long double
on IA32 FreeBSD, and the FPU is explicitly set to have 53-bit
of precision. The comment from /sys/src/sys/i386/include/npx.h
(ie FreeBSD source code) is

/*
* The hardware default control word for i387's and later coprocessors
is
* 0x37F, giving:
*
* round to nearest
* 64-bit precision
* all exceptions masked.
*
* We modify the affine mode bit and precision bits in this to give:
*
* affine mode for 287's (if they work at all) (1 in bitfield
1<<12)
* 53-bit precision (2 in bitfield 3<<8)
*
* 64-bit precision often gives bad results with high level languages
* because it makes the results of calculations depend on whether
* intermediate values are stored in memory or in FPU registers.
*/

--
steve

steve

unread,
Nov 23, 2010, 11:31:51 PM11/23/10
to
On Nov 23, 7:21 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:


> You can see that the FCW is initialized to Z'037F' on my system.
> The above won't work on your end of the wire because of the Win32
> API calls.  My best guess is that:
>

(code clipped)

> is what might work over there.  If you are brave enough to run
> code from someone out on the internet whose image you have never
> seen that pokes machine code into memory and then jumps to it...
> I would be very curious as to the output you get from the above
> code.

Yeah, sure.

laptop:kargl[91] gfc4x -o z -fno-range-check j9.f90
laptop:kargl[92] ./z


This is a 32-bit processor

Time read from TSC: 1810


Initial value of MXCSR: 00001F80
Value to be stored in MXCSR: 00001D80
Value read from MXCSR: 00001D80

Initial value of FCW: 127F
Value to be stored in FCW: 127B
Value read from FCW: 127B


Initial value of FSW: 0000
Value of FSW after inexact: 0020
Value of FSW after FCLEX: 0000
Max input value for basic CPUID: 10
Brand name: GenuineIntel

epsilon = 0.222045E-15
huge = 1.18973149535723163300E+4932
precision = 15


range = 4931
sizeof = 12

tiny = 3.36210314311209350626E-4932

James Van Buskirk

unread,
Nov 24, 2010, 12:33:27 AM11/24/10
to
"steve" <kar...@comcast.net> wrote in message
news:f30bd27c-3878-4e51...@m20g2000prc.googlegroups.com...

> I only have fairly recent trunk on my laptop along with 4.4
> and 4.5. I've removed the writes from your code to simply
> the -fdump-tree-original output. I see

> laptop:kargl[72] gfortran44 -o z j5.f90 && ./z
> laptop:kargl[73] gfortran45 -o z j5.f90 && ./z
> laptop:kargl[74] gfc4x -o z j5.f90 && ./z
> Segmentation fault (core dumped)

> Looks like someone may have broken TRANSFER. I haven't
> looked for the cause, yet.

Actually I don't think TRANSFER itself is at fault. Here's a
really small example that crashes on 32-bit Windows:

C:\gfortran\clf\mxcsr>type bug2a.f90
program P
call sub
end program P

subroutine sub
use ISO_C_BINDING, only: C_SIZEOF, C_INT
implicit none
type, bind(C) :: T
integer(C_INT) a
integer(C_INT) b
integer(C_INT) c
integer(C_INT) d
end type T
character(C_SIZEOF(T(0,0,0,0))) string
type(T) R

string = transfer(R,string)
end subroutine sub

C:\gfortran\clf\mxcsr>gfortran bug2a.f90 -obug2a

C:\gfortran\clf\mxcsr>bug2a

And crash! I don't have the tools to do this myself, but if
you ran the above under a debugger and set a breakpoint at
the line:

string = transfer(R,string)

my prediction is that the address of R should lie above esp and
the address of string should lie below it. It's the placement
of string below esp that is a mistake. I don't know whether
the address of string is calculated incorrectly on subroutine
entry or if esp is corrupted as a consequence of the calculation
(for example esp is restored from ecx after a call to ___chkstk_ms
amd the ABI specifies ecx as caller-save...)

If you want to find problems with TRANSFER itself, look at the
program in the originating post of this thread. Completely
unrelated to this bug, though.

> > Now test with SIZEOF(T(0,0,0,0))
> > ??" ?"
> > ¼?" á?"
> > L?" @?"
> > ÿ?" É?"
> > °?" ??"

> > So gfortran still is doing the wrong thing with C_SIZEOF(R) and
> > SIZEOF(R): not taking into account that these (at least the first)
> > are specification inquiries. It's kind of hard to know directly
> > whether it's getting C_SIZEOF(T(0,0,0,0)) and SIZEOF(T(0,0,0,0))
> > right because they trigger the regression, but if gfortran really
> > thought they were initialization expressions it should have had the
> > same result as if these were replaced by 16, but that was subroutine
> > sub1 which worked OK. Oh yes, there is another issue in that the
> > original code way back up at the top of this post also has
> > C_SIZEOF(CPUID_TYPE(0,0,0,0)) as a specification expression in the
> > main program, but since gfortran thinks that isn't an initialization
> > expression, it should error out because automatic data objects aren't
> > allowed in the main program.

> This may related to the absences of simplification routines. I need
> to check, but I think the frontend may not be replacing the [C_]SIZEOF
> until it is too late.

Actually I think it's the same bug that causes the crash. Both are
possible outcomes of string lying below esp in memory, and I agree
that it's the result of copmuting [C_]SIZEOF as a specification
expression at runtime.

James Van Buskirk

unread,
Nov 24, 2010, 1:07:56 AM11/24/10
to
"steve" <kar...@comcast.net> wrote in message
news:120409db-ff2c-46fb...@22g2000prx.googlegroups.com...

> On Nov 23, 7:21 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:

> > You can see that the FCW is initialized to Z'037F' on my system.
> > The above won't work on your end of the wire because of the Win32
> > API calls. My best guess is that:

> (code clipped)

> > is what might work over there. If you are brave enough to run
> > code from someone out on the internet whose image you have never
> > seen that pokes machine code into memory and then jumps to it...
> > I would be very curious as to the output you get from the above
> > code.

> Yeah, sure.

> laptop:kargl[91] gfc4x -o z -fno-range-check j9.f90
> laptop:kargl[92] ./z
> This is a 32-bit processor

So you are running the 32-bit version of the compiler for
this test.

> Time read from TSC: 1810
> Initial value of MXCSR: 00001F80

Flush-to-zero disabled, round to nearest, mask precision,
underflow, overflow, divide-by-zero, denormal operation,
and invalid operation exceptions, denormals-are-zeros
disabled, no precision, underflow, overflow, divide-by-zero,
denormal operation, or invalid operation detected.

> Value to be stored in MXCSR: 00001D80
> Value read from MXCSR: 00001D80
> Initial value of FCW: 127F

Infinity control set to affine (too bad my old 80287 no longer
works) round to nearest, precision control set to 53 bits,
mysterious reserved bit 6 set, mask precision, underflow,
overflow, zero divide, denormal operation, and invalid
operation exceptions. As you said in your previous post.

> Value to be stored in FCW: 127B
> Value read from FCW: 127B
> Initial value of FSW: 0000
> Value of FSW after inexact: 0020

This is why I had to use REAL(KIND=10) arithmetic in module
nudge_FSW. Had I used single or double precision, the program
wouldn't have worked in 64-bit mode because gfortran uses xmm
registers for those kinds of variable by default, but of course
REAL(KIND=10) is carried out on the x87 floating point stack
in both modes. It's easy to set that precision bit, of course.

> Value of FSW after FCLEX: 0000
> Max input value for basic CPUID: 10
> Brand name: GenuineIntel
> epsilon = 0.222045E-15
> huge = 1.18973149535723163300E+4932
> precision = 15
> range = 4931
> sizeof = 12
> tiny = 3.36210314311209350626E-4932

Woo-hoo! All running to completion sight-unseen. I'd rather be
lucky than good. You are indeed very brave.

steve

unread,
Nov 24, 2010, 1:18:23 PM11/24/10
to

Tobias fixed this problem last night while I slept.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46638

>
> > > Now test with SIZEOF(T(0,0,0,0))
> > > ??" ?"

> > > ?" ?"
> > > L?" @?"
> > > ?" ?"


> > > ?" ??"
> > > So gfortran still is doing the wrong thing with C_SIZEOF(R) and
> > > SIZEOF(R): not taking into account that these (at least the first)
> > > are specification inquiries. It's kind of hard to know directly
> > > whether it's getting C_SIZEOF(T(0,0,0,0)) and SIZEOF(T(0,0,0,0))
> > > right because they trigger the regression, but if gfortran really
> > > thought they were initialization expressions it should have had the
> > > same result as if these were replaced by 16, but that was subroutine
> > > sub1 which worked OK. Oh yes, there is another issue in that the
> > > original code way back up at the top of this post also has
> > > C_SIZEOF(CPUID_TYPE(0,0,0,0)) as a specification expression in the
> > > main program, but since gfortran thinks that isn't an initialization
> > > expression, it should error out because automatic data objects aren't
> > > allowed in the main program.
> > This may related to the absences of simplification routines.  I need
> > to check, but I think the frontend may not be replacing the [C_]SIZEOF
> > until it is too late.
>
> Actually I think it's the same bug that causes the crash.  Both are
> possible outcomes of string lying below esp in memory, and I agree
> that it's the result of copmuting [C_]SIZEOF as a specification
> expression at runtime.

Tobias and I agree this is a simplification issue. See

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46641

--
steve

James Van Buskirk

unread,
Nov 24, 2010, 2:48:30 PM11/24/10
to
"steve" <kar...@comcast.net> wrote in message
news:38e44163-5933-4f0a...@i32g2000pri.googlegroups.com...

> On Nov 23, 9:33 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:

I'm pretty sure that you intended to leave in at this point:

> > If you want to find problems with TRANSFER itself, look at the
> > program in the originating post of this thread. Completely
> > unrelated to this bug, though.

> Tobias fixed this problem last night while I slept.

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46638

So I pasted that bit of context back in for you. Thanks to Tobias
for the instantaneous fix!

> > Actually I think it's the same bug that causes the crash. Both are
> > possible outcomes of string lying below esp in memory, and I agree
> > that it's the result of copmuting [C_]SIZEOF as a specification
> > expression at runtime.

> Tobias and I agree this is a simplification issue. See

> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46641

There is a problem with the bug reproducer that I posted in that
if gfortran first fixes the issue about applying its initialization
expression mechanism to the expression C_SIZEOF(T(0,0,0,0)) then
the problem will appear to go away, but there are actually something
like three problems here:

1) gfortran isn't recognizing C_SIZEOF(T(0,0,0,0)) as an initialization
expression -- that is probed in bug2.f90 in
http://groups.google.com/group/comp.lang.fortran/msg/b52ababb4a60ec0f?hl=en

2) Even though it doesn't consider it to be an initialization
expression it is accepted as a specification expression in the
specification-part of a main program:

program main
...
character(C_SIZEOF(T(0,0,0,0))) string
...
end program main

But this is an isolated incident and I can't find any generalization
of this that gfortran doesn't catch, so hopefully this issue will go
away by itself when issue 1 above is fixed.

3) Something going wrong with specification expressions, at least
those involving C_SIZEOF. The previous error reproducer I posted
for this is problematic in that if gfortran's initialization
expression evaluation mechanism gets brought to bear as hoped for
under issue 1 above, the error will still be there, just not detected
by the test suite. Thus we need a program that shows the error with
a specification expression that is not an initialization expression:

C:\gfortran\clf\mxcsr>type bug2b.f90
program P
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) x(4)
x = int(Z'41414141',C_INT)
call sub(x,size(x))
end program P

subroutine sub(A,N)


use ISO_C_BINDING, only: C_SIZEOF, C_INT
implicit none

integer N
integer(C_INT) A(N)
character(C_SIZEOF(A)) string

string = transfer(A,string)
end subroutine sub

C:\gfortran\clf\mxcsr>gfortran bug2b.f90 -obug2b

C:\gfortran\clf\mxcsr>bug2b

And once again I get a crash here. gfortran version:

C:\gfortran\clf\mxcsr>gfortran -v
Driving: gfortran -v -specs=libgfortran.spec
Using built-in specs.
Reading specs from
c:/gcc_equation32/bin/../lib/gcc/i686-pc-mingw32/4.6.0/../../
../libgfortran.spec
rename spec lib to liborig


COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation32/bin/../libexec/gcc/i686-pc-mingw32/4.6.0/l
to-wrapper.exe
Target: i686-pc-mingw32

Configured with:
../gcc-4.6-20101120-mingw/configure --host=i686-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i686-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.6-20101120 --with-gcc --with-gnu-ld
--
with-gnu-as --disable-shared --disable-nls --disable-tls --disable-lto --with-gm
p=/home/gfortran/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfo
rtran/gcc-home/binary/mingw32/native/x86_32/mpfr --with-mpc=/home/gfortran/gcc-h
ome/binary/mingw32/native/x86_32/mpc --enable-languages=c,c++,fortran --with-sys
root=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.6-20101120 --enab
le-libgomp --enable-threads=win32 --disable-win32-registry : (reconfigured)
../g
cc-4.6-20101120-mingw/configure --host=i686-pc-mingw32 --build=x86_64-unknown-li
nux-gnu --target=i686-pc-mingw32 --prefix=/home/gfortran/gcc-home/binary/mingw32
/native/x86_32/gcc/4.6-20101120 --with-gcc --with-gnu-ld --with-gnu-as --disable
-shared --disable-nls --disable-tls --disable-lto --with-gmp=/home/gfortran/gcc-
home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home/binary
/mingw32/native/x86_32/mpfr --with-mpc=/home/gfortran/gcc-home/binary/mingw32/na
tive/x86_32/mpc --enable-languages=c,c++,fortran --with-sysroot=/home/gfortran/g
cc-home/binary/mingw32/cross/x86_32/gcc/4.6-20101120 --enable-libgomp --enable-t


hreads=win32 --disable-win32-registry
Thread model: win32

gcc version 4.6.0 20101120 (experimental) (GCC)

I found a message that lies in the right time frame:

http://patchwork.ozlabs.org/patch/65771/

but it's all greek to me and possibly a red herring. www.equation.com
used to have all of its old builds available on its ftp site, but
doesn't any more so I couldn't test whether the regression happened
on or near 2010-09-25.

Again thanks to you and Tobias for your attention to these issues.

James Van Buskirk

unread,
Nov 25, 2010, 2:45:00 AM11/25/10
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:icjq6i$nkb$1...@news.eternal-september.org...

> I found a message that lies in the right time frame:

> http://patchwork.ozlabs.org/patch/65771/

> but it's all greek to me and possibly a red herring. www.equation.com
> used to have all of its old builds available on its ftp site, but
> doesn't any more so I couldn't test whether the regression happened
> on or near 2010-09-25.

I think the above link is really a red herring. Examining disassembly
more thoroughly, it seems that after a fixed-size stack frame is
established, %esp gets saved, then room is made on the stack for
character(C_SIZEOF(A)) string while keeping the stack aligned 0 mod
16, then the address of string is established above the current value
of %esp, also aligned 0 mod 16. But the next thing that happens is
that %esp is restored from the value saved above and now lies above
the address of string. Restoring %esp is the fatal step because now
the executable statements of the subroutine get executed, and when
string gets written by a function, like _memmove, _memcopy, or _memset,
it overwrites the return address and the function can only return into
the unknown.

All it takes to set off the crash is a sufficiently complicated
specification expression for the length of variable string and a
statement that writes string. Example:

C:\gfortran\clf\mxcsr>type bug2d.f90


program P
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) x(4)
x = int(Z'41414141',C_INT)
call sub(x,size(x))
end program P

subroutine sub(A,N)
use ISO_C_BINDING, only: C_SIZEOF, C_INT
implicit none
integer N
integer(C_INT) A(N)
character(C_SIZEOF(A)) string

! character(16) string
! integer L

! L = C_SIZEOF(A)
string = repeat('A',16)
! string = repeat('A',L)
end subroutine sub

C:\gfortran\clf\mxcsr>gfortran bug2d.f90 -obug2d

C:\gfortran\clf\mxcsr>bug2d

Crash! Or:

C:\gfortran\clf\mxcsr>type bug2e.f90


program P
use ISO_C_BINDING, only: C_INT
implicit none
integer(C_INT) x(4)
x = int(Z'41414141',C_INT)
call sub(x,size(x))
end program P

subroutine sub(A,N)
use ISO_C_BINDING, only: C_INT


implicit none
integer N
integer(C_INT) A(N)

character(4*SIZE(A)) string

string = repeat('A',16)
end subroutine sub

C:\gfortran\clf\mxcsr>gfortran bug2e.f90 -obug2e

C:\gfortran\clf\mxcsr>bug2e

Crash again. Or even:

C:\gfortran\clf\mxcsr>type bug2f.f90
program P
implicit none
integer x(4)
x = [2,3,4,7]


call sub(x,size(x))
end program P

subroutine sub(A,N)
implicit none
integer N
integer A(N)
character(SUM(A)) string

string = '0123456789ABCDEF'
end subroutine sub

C:\gfortran\clf\mxcsr>gfortran bug2f.f90 -obug2f

C:\gfortran\clf\mxcsr>bug2f

Again, crash.

So it's not TRANSFER or C_SIZEOF but more something general about the
way gfortran handles local character variables with LEN given by a
sufficiently complicated specification expression.

jfh

unread,
Nov 25, 2010, 3:41:52 PM11/25/10
to
On Nov 25, 8:45 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "James Van Buskirk" <not_va...@comcast.net> wrote in messagenews:icjq6i$nkb$1...@news.eternal-september.org...

No crash for me with gfortran using either of:
gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
And if I insert just before end subroutine sub the line
print *,string
the program prints
0123456789ABCDEF

-- John Harper

Tobias Burnus

unread,
Nov 25, 2010, 3:55:54 PM11/25/10
to
Am 25.11.2010 21:41, schrieb jfh:
>> All it takes to set off the crash is a sufficiently complicated
>> specification expression for the length of variable string and a
>> statement that writes string. Example:
>
> No crash for me with gfortran using either of:
> gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)
> gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

Nor for me with all the examples - and no errors when running the
examples in valgrind.

That's with the (almost) latest 4.6.0 version of today.

I do see the crash with "character(len=c_sizeof(structure_constructor())
:: string" when using "string = transfer(...)" (in an earlier news
posting) - but that's the only failure I see.

Tobias

James Van Buskirk

unread,
Nov 25, 2010, 6:23:51 PM11/25/10
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:4CEECD5A...@net-b.de...

I think that's because you are running 64-bit Linux, which sets up
the stack differently with the Red Zone and all. Given that
assumption, could you please try two simple experiements:

1) Post the output, if any, you get from utils_linux.f90 from my
post of
http://groups.google.com/group/comp.lang.fortran/msg/b52ababb4a60ec0f?hl=en
because I don't yet know if it works on your platform.

2) Post the bug2d.s file you get from running
gfortran -S bug2d.f90
on the bug2d.f90 file from my post of
http://groups.google.com/group/comp.lang.fortran/msg/1814c598c5d9548d?hl=en
by looking at the assembly code I should be able to tell whether
gfortran is messing up the stack even though it doesn't cause an
obvious fault.

James Van Buskirk

unread,
Nov 26, 2010, 2:19:16 PM11/26/10
to
"James Van Buskirk" <not_...@comcast.net> wrote in message
news:icmr6b$smk$1...@news.eternal-september.org...

> "Tobias Burnus" <bur...@net-b.de> wrote in message
> news:4CEECD5A...@net-b.de...

>> Nor for me with all the examples - and no errors when running the
>> examples in valgrind.

>> That's with the (almost) latest 4.6.0 version of today.

>> I do see the crash with "character(len=c_sizeof(structure_constructor())
>> :: string" when using "string = transfer(...)" (in an earlier news
>> posting) - but that's the only failure I see.

> 2) Post the bug2d.s file you get from running


> gfortran -S bug2d.f90
> on the bug2d.f90 file from my post of
> http://groups.google.com/group/comp.lang.fortran/msg/1814c598c5d9548d?hl=en
> by looking at the assembly code I should be able to tell whether
> gfortran is messing up the stack even though it doesn't cause an
> obvious fault.

Here is an f95 example where you can see that depending on luck the
result is expected output, corrupted output, or a crash:

C:\gfortran\clf\probe_rsp>type error1.f90
module mykinds
implicit none
integer, parameter :: ik1 = selected_int_kind(2)
end module mykinds

program test
use mykinds
implicit none
integer, parameter :: N = 128
integer(ik1) A(N)
type T
integer, pointer :: dud
end type T
integer L

write(*,'(a,i0,a)') 'This is a ', &

bit_size(A)*size(transfer(T(NULL()),A)),'-bit processor'
do L = 1, size(A)
write(*,'(a,i0)') 'Calling sub with N = ', L
call sub(A,L)
end do
end program test

subroutine sub(A,N)
use mykinds
implicit none
integer N
integer(ik1) A(N)
character(SIZE(A)) string

string = repeat('1234567890',16)
write(*,'(a)') string
end subroutine sub

C:\gfortran\clf\probe_rsp>gfortran error1.f90 -oerror1

C:\gfortran\clf\probe_rsp>error1


This is a 32-bit processor

Calling sub with N = 1
h
Calling sub with N = 2
hv
Calling sub with N = 3
hvm
Calling sub with N = 4
hvm
Calling sub with N = 5
12345
Calling sub with N = 6
123456
Calling sub with N = 7
1234567
Calling sub with N = 8
12345678
Calling sub with N = 9

C:\gfortran\clf\probe_rsp>gfortran -v

C:\gfortran\clf\probe_rsp>gfortran error1.f90 -oerror1

C:\gfortran\clf\probe_rsp>error1
This is a 64-bit processor
Calling sub with N = 1
?
Calling sub with N = 2
ɷ
Calling sub with N = 3
ɷ"
Calling sub with N = 4
ɷ"
Calling sub with N = 5
ɷ"
Calling sub with N = 6
ɷ"
Calling sub with N = 7
ɷ"
Calling sub with N = 8
ɷ"
Calling sub with N = 9
ɷ" p
Calling sub with N = 10
ɷ" p·
Calling sub with N = 11
ɷ" p·"
Calling sub with N = 12
ɷ" p·"
Calling sub with N = 13
ɷ" p·"
Calling sub with N = 14
ɷ" p·"
Calling sub with N = 15
ɷ" p·"
Calling sub with N = 16
ɷ" p·"
Calling sub with N = 17
ɷ" p·" ?
Calling sub with N = 18

C:\gfortran\clf\probe_rsp>gfortran -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.0/
lto-wrapper.exe
Target: x86_64-w64-mingw32

Thread model: win32
gcc version 4.6.0 20101113 (experimental) (GCC)

We can see that for 32-bit gfortran for Windows of 2010-11-20, we
got corrupted output for N = 1:4, normal-looking output for N = 5:8,
and a crash at N = 9. For 64-bit gfortran for Windows of
2010-11-13, we got corrupted output for N = 1:17 and a crash at
N = 18.

That's why I wanted to see a disassembly: bad pointers (here a bad
stack pointer) don't always cause problems you can see, but they
may be problems waiting to happen. Examining the disassembly can
allow you to see these latent problems before something bad really
happens.

Tobias Burnus

unread,
Nov 27, 2010, 4:52:49 PM11/27/10
to
James Van Buskirk wrote:
> "steve"<kar...@comcast.net> wrote in message
>> Tobias and I agree this is a simplification issue. See
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46641

Actually, there are two issues: There is a simplification issue which
causes the (c_)sizeof not be converted into a constant early during the
compilation. That's tracked by the PR above. It probably takes a while
until this is fixed.


But there is another issue, independent of that one which affected all
local character variables, whose string length is not known at compile
time. (For arrays one would call it automatic array):

> 3) Something going wrong with specification expressions

That's http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46678; a bug fix is
available, but not yet committed (but should be soon).

Even if it were committed, build issues currently prevent the building
of GCC on MinGW/MinGW64, which means that it will take a while until you
get a fixed build.

Thanks for the bug report and the test cases!

Tobias

Richard Maine

unread,
Nov 27, 2010, 5:09:32 PM11/27/10
to
Tobias Burnus <bur...@net-b.de> wrote:

> local character variables, whose string length is not known at compile
> time. (For arrays one would call it automatic array):

"Automatic" is still the right word. As of f2003 there are other
properties that can be automatic, so the term has become a bit more
general, much like "allocatable". I recall an effort to scour the
standard for the term "allocatable array" and replace it with
"allocatable variable." You'd think that might be trivial, but the first
iteration missed some cases.

I see that "automatic array" is still defined as a separate term in the
standard, although it seems like a largely redundant definition as there
is also the more general "automatic data object." I suppose that
acording to the definitions, one could have an array that was an
automatic data object, but not an automatic array (for example, an array
with constant bounds, but whose elements were characters with automatic
length), but why anyone would care about the distinction is harder for
me to guess.

Don't ask me why the standard uses the long-winded "automatic data
object" instead of just "automatic variable". As far as I can see an
automatic data object is always a variable, so I'd have used the simpler
term.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

James Van Buskirk

unread,
Nov 27, 2010, 11:58:53 PM11/27/10
to
"Tobias Burnus" <bur...@net-b.de> wrote in message
news:4CF17DB1...@net-b.de...

> James Van Buskirk wrote:

> Actually, there are two issues: There is a simplification issue which
> causes the (c_)sizeof not be converted into a constant early during the
> compilation. That's tracked by the PR above. It probably takes a while
> until this is fixed.

> But there is another issue, independent of that one which affected all
> local character variables, whose string length is not known at compile
> time. (For arrays one would call it automatic array):

>> 3) Something going wrong with specification expressions

> That's http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46678; a bug fix is
> available, but not yet committed (but should be soon).

> Even if it were committed, build issues currently prevent the building of
> GCC on MinGW/MinGW64, which means that it will take a while until you get
> a fixed build.

> Thanks for the bug report and the test cases!

Thanks to you and Jerry for the fixing. You've got everything except
perhaps for one problem with I/O for REAL(KIND=10) variables that was
shown on the first post of this thread. I tried to reproduce that
issue on 4 tracks of gfortran: MinGW or www.equation.com and 32- or
64-bit target. Took me a while to figure out how to strip the prefixes
off the executable names provided by MinGW in Fortran, but you can do
anything in Fortran, so here are the results I observed:

C:\gfortran\james\bugs>type bugs2.f90
program bugs2
implicit none


integer, parameter :: ep = 10

real(ep) x
integer i

x = tiny(x)
write(*,*) x
do i = 1, 10
x = 100*x
write(*,*) x
end do
x = huge(x)
write(*,*) x
do i = 1, 10
x = x/1.0e100_ep
write(*,*) x
end do
end program bugs2

C:\gfortran\james\bugs>gfortran bugs2.f90 -obugs2

C:\gfortran\james\bugs>bugs2
0.0000000000000-(00000E-4933
0.0000000000000-(00000E-4931
0.0000000000000-(00000E-4929
0.0000000000000-(00000E-4927
0.0000000000000-(00000E-4925
0.0000000000000-(00000E-4923
0.0000000000000-(00000E-4921
0.0000000000000-(00000E-4919
3.36210314311209349648E-4916
3.36210314311209349648E-4914
3.36210314311209349688E-4912
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000
n.inite m tl?w�&?w E+0000

C:\gfortran\james\bugs>gfortran -v

--------------------------------------------------------------------

C:\gfortran\james\bugs>gfortran bugs2.f90 -obugs2

C:\gfortran\james\bugs>bugs2
0.0000000000000-(00000E-4933
0.0000000000000-(00000E-4931
0.0000000000000-(00000E-4929
0.0000000000000-(00000E-4927
0.0000000000000-(00000E-4925
0.0000000000000-(00000E-4923
0.0000000000000-(00000E-4921
0.0000000000000-(00000E-4919
3.36210314311209349648E-4916
3.36210314311209349648E-4914
3.36210314311209349688E-4912
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000
n.inite ?C ? E+0000

C:\gfortran\james\bugs>gfortran -v


Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-w64-mingw32/4.6.0/
lto-wrapper.exe
Target: x86_64-w64-mingw32

Thread model: win32
gcc version 4.6.0 20101113 (experimental) (GCC)

-------------------------------------------------------------------

C:\gfortran\james\bugs>gfortran bugs2.f90 -obugs2

C:\gfortran\james\bugs>bugs2
3.36210314311209350626E-4932
3.36210314311209350626E-4930
3.36210314311209350626E-4928
3.36210314311209350626E-4926
3.36210314311209350626E-4924
3.36210314311209350626E-4922
3.36210314311209350626E-4920
3.36210314311209350626E-4918
3.36210314311209350626E-4916
3.36210314311209350626E-4914
3.36210314311209350626E-4912
1.18973149535723176502E+4932
1.18973149535723176506E+4832
1.18973149535723176511E+4732
1.18973149535723176514E+4632
1.18973149535723176517E+4532
1.18973149535723176527E+4432
1.18973149535723176530E+4332
1.18973149535723176532E+4232
1.18973149535723176538E+4132
1.18973149535723176537E+4032
1.18973149535723176545E+3932

C:\gfortran\james\bugs>gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_mingw32/bin/../libexec/gcc/i686-w64-mingw32/4.5.2/lto
-wrapper.exe
Target: i686-w64-mingw32
Configured with:
../../../build/gcc/src/configure --target=i686-w64-mingw32 --pr
efix=/c/bb/vista64-mingw32/mingw-x86-x86/build/build/root --with-sysroot=/c/bb/v
ista64-mingw32/mingw-x86-x86/build/build/root --enable-languages=all,obj-c++
--e
nable-fully-dynamic-string --disable-multilib
Thread model: win32
gcc version 4.5.2 20101015 (prerelease) (GCC)

-----------------------------------------------------------------------

C:\gfortran\james\bugs>gfortran bugs2.f90 -obugs2

C:\gfortran\james\bugs>bugs2
3.36210314311209350626E-4932
3.36210314311209350626E-4930
3.36210314311209350626E-4928
3.36210314311209350626E-4926
3.36210314311209350626E-4924
3.36210314311209350626E-4922
3.36210314311209350626E-4920
3.36210314311209350626E-4918
3.36210314311209350626E-4916
3.36210314311209350626E-4914
3.36210314311209350626E-4912
1.18973149535723176502E+4932
1.18973149535723176506E+4832
1.18973149535723176511E+4732
1.18973149535723176514E+4632
1.18973149535723176517E+4532
1.18973149535723176527E+4432
1.18973149535723176530E+4332
1.18973149535723176532E+4232
1.18973149535723176538E+4132
1.18973149535723176537E+4032
1.18973149535723176545E+3932

C:\gfortran\james\bugs>gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_mingw64a/bin/../libexec/gcc/x86_64-w64-mingw32/4.5.2/
lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with:
../../../build/gcc/src/configure --target=x86_64-w64-mingw32 --
prefix=/c/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --with-sysroot=/c
/bb/vista64-mingw32/mingw-x86-x86_64/build/build/root --enable-languages=all,obj
-c++ --enable-fully-dynamic-string --disable-multilib
Thread model: win32
gcc version 4.5.2 20101119 (prerelease) (GCC)

Oog, so the www.equation.com versions are bad and the MinGW ones
are good, so it appears that you guys won't be able to help with
this...

Ken Fairfield

unread,
Nov 29, 2010, 3:41:59 PM11/29/10
to
On Nov 27, 8:58 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
[...]

> Thanks to you and Jerry for the fixing.  You've got everything except
> perhaps for one problem with I/O for REAL(KIND=10) variables that was
> shown on the first post of this thread.  I tried to reproduce that
> issue on 4 tracks of gfortran: MinGW orwww.equation.comand 32- or

> 64-bit target.  Took me a while to figure out how to strip the prefixes
> off the executable names provided by MinGW in Fortran, but you can do
> anything in Fortran, so here are the results I observed:
>
> C:\gfortran\james\bugs>type bugs2.f90
> program bugs2
>    implicit none
>    integer, parameter :: ep = 10
>    real(ep) x
>    integer i
>
>    x = tiny(x)
>    write(*,*) x
>    do i = 1, 10
>       x = 100*x
>       write(*,*) x
>    end do
>    x = huge(x)
>    write(*,*) x
>    do i = 1, 10
>       x = x/1.0e100_ep
>       write(*,*) x
>    end do
> end program bugs2

[...]

> Oog, so thewww.equation.comversions are bad and the MinGW ones


> are good, so it appears that you guys won't be able to help with
> this...

If I read the output for the "tiny" loop correctly, you're
multiplying by 100, but the exponents in the output
increase only by 2, even in the MinGW runs. What
am I missing?

-Ken

James Van Buskirk

unread,
Nov 29, 2010, 4:43:40 PM11/29/10
to
"Ken Fairfield" <ken.fa...@gmail.com> wrote in message
news:64b94053-4bfa-49fd...@35g2000prt.googlegroups.com...

> On Nov 27, 8:58 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> [...]

> > C:\gfortran\james\bugs>type bugs2.f90
> > program bugs2
> > implicit none
> > integer, parameter :: ep = 10
> > real(ep) x
> > integer i

> > x = tiny(x)
> > write(*,*) x
> > do i = 1, 10
> > x = 100*x
> > write(*,*) x
> > end do
> > x = huge(x)
> > write(*,*) x
> > do i = 1, 10
> > x = x/1.0e100_ep
> > write(*,*) x
> > end do
> > end program bugs2

> If I read the output for the "tiny" loop correctly, you're


> multiplying by 100, but the exponents in the output
> increase only by 2, even in the MinGW runs. What
> am I missing?

If I want to increase the number by 100, I add 100. If I want to
increase the number by 2, I add 2. If I want to increase the
exponent by 100, I multiply by 10**100. If I want to increase
the exponent by 2, I multiply by 10**2 = 100 :)

Ken Fairfield

unread,
Nov 29, 2010, 5:18:01 PM11/29/10
to
On Nov 29, 1:43 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "Ken Fairfield" <ken.fairfi...@gmail.com> wrote in message

Duh! Time to reboot by brain. :-( -Ken

Richard Maine

unread,
Nov 29, 2010, 5:35:25 PM11/29/10
to
Ken Fairfield <ken.fa...@gmail.com> wrote:

> Duh! Time to reboot by brain. :-( -Ken

Nah. I'd advise against booting your brain even once, much less
rebooting it. Concussions can be nasty. :-)

0 new messages