For the following program, FTN95 V 8.51 generates bad X86 machine code when the options /opt /p6 are used.
program terfdif
print *,erfdif(0.6, 0.4)
end program
function erfdif(x1,x2)
erfdif = erf(x1) - erf(x2)
end
The address of the actual argument X2 is loaded into EBX when the function ERFDIF is entered. Similarly, the address of X1 is loaded into ECX. Then, DERF is called with argument X2. As a result of this call, given the register saving conventions of X86 code, ECX is overwritten. However, the generated code assumes that ECX still contains the address of X1, and passes an invalid address when trying to evaluate DERF(X1). When I ran the program, at this point ECX contained 00000003, and the program crashed with an access violation. The /EXP listing of the function follows.
00000000(49/1/49) push ebp
00000001(50/1/49) mov ebp,esp
00000003(51/1/49) push ebx
00000004(52/1/49) push esi
00000005(53/1/49) push edi
00000006(54/1/49) push eax
00000007(55/1/49) sub esp,=16 ; Adjusted later if temporaries allocated
0000000d(56/1/49) mov ebx,address of X2
; Register ebx contains X2
00000010(58/1/49) mov ecx,address of X1
; Register ecx contains X1
0003 end program AT 13
0004 AT 13
0005 function erfdif(x1,x2) AT 13
0006 erfdif = erf(x1) - erf(x2) AT 13
00000013(60/4/44) fld [ebx]
00000015(61/4/44) dfstp Temp@11
00000018(62/4/44) lea esi,Temp@11
0000001b(63/4/44) push esi
0000001c(64/4/44) call DERF@ ; function call, ECX is destroyed
00000021(65/4/44) add esp,=4
00000024(66/4/44) fstp Temp@10
00000027(67/4/36) fld [ecx] ; BUG HERE, ECX contains rubbish
00000029(68/4/36) dfstp Temp@13
0000002c(69/4/36) lea eax,Temp@13
0000002f(70/4/36) push eax
00000030(71/4/36) call DERF@
00000035(72/4/36) add esp,=4
00000038(73/4/36) fstp Temp@12
0000003b(74/3/48) fld Temp@12
0000003e(75/3/48) fsub Temp@10
00000041(77/1/49) Label __N2
00000041(78/1/49) lea esp,[ebp-12]
00000044(79/1/49) pop edi
00000045(80/1/49) pop esi
00000046(81/1/49) pop ebx
00000047(82/1/49) pop ebp
00000048(83/1/49) ret