|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
acw
Joined: 04 Nov 2005 Posts: 165 Location: Darkest Devon
|
Posted: Mon Jul 16, 2007 5:35 pm Post subject: Possible bugs when using 2d arrays and interfaces in modules |
|
|
I have a possible bug/bugs that occur with a module containing a 2D array, type conversion, interfaces and the /check compiler option. There is an example at the end of the email showing the various problems (there is more info in the code comments):
1. If the realVals declaration occurs after the ADT spec the compiler crashes with an access violation in make_new_variable. Actually this occurs even if /check is omitted.
2. In SetTestType() the use of an int function with a kind parameter on an int-cast 2D array index where an index is a variable(!) causes the compiler to issue "operand incompatible with opcode" error - if an intermediate integer is used then the problem goes away, or if /check is omitted, or if the array has constant indices
3. In SetTestType2(), nint produces incorrect values with or without /check (although it's a different incorrect value).
Problems 2 & 3 disappear if their interfaces are removed.
Compiler version is 5.10 and I'm doing a Win32 build.
Alan
! Demonstrate comiler bug with 2D arrays in modules whit /check option and interface
module TestMod
! Some values - if this goes after type def compiler crashes, even here the initialisation fails
real:: realVals(10,10) = 42.55
type TestType
integer*1:: intKind1
end TestType
!real:: realVals(10,10) = 42.55 ! causes a compiler crash if placed here (with or without init)
interface
subroutine SetTestType(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
end subroutine SetTestType
subroutine SetTestType2(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
end subroutine SetTestType2
end interface
contains
subroutine SetTestType(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
tt%intKind1 = int(nint(realVals(idx,4)), 1) ! generates "operand incompatible with opcode" when realVals is 2D array
! creating an intermediate integer*4 solves the problem
end subroutine SetTestType
subroutine SetTestType2(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
tt%intKind1 = nint(realVals(idx,4), 1) ! this is 52 with /check, 0 without, should be 43 (okay if interface removed)
end subroutine SetTestType2
end module TestMod
winapp
use TestMod
type(TestType):: newtt
realVals = 42.59 ! init in module doesn't work
call SetTestType(newtt, 3)
call SetTestType2(newtt, 4)
end |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7929 Location: Salford, UK
|
Posted: Tue Jul 17, 2007 1:06 pm Post subject: |
|
|
These are compiler bugs irrespective of whether the code is valid Fortran.
I will add this to the list of issues to be investigated. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7929 Location: Salford, UK
|
Posted: Fri Jul 20, 2007 3:11 pm Post subject: |
|
|
There is an error in your code. You need
type TestType
integer*1:: intKind1
end type TestType
(on the last line, add the keyword "type").
We have fixed this in the compiler so that it now reports this error in the program code. |
|
Back to top |
|
|
acw
Joined: 04 Nov 2005 Posts: 165 Location: Darkest Devon
|
Posted: Mon Jul 30, 2007 9:43 am Post subject: |
|
|
Okay that's fine, but this has no effect on the compilation errors which still occur whether or not there is an "end type" Does the missing "type" have any effect on the generated code ? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7929 Location: Salford, UK
|
Posted: Tue Jul 31, 2007 6:37 am Post subject: |
|
|
I will try to have another look at this later this week.
With the current release, if you miss out the word "type" after "end" then FTN95 produces incorrect assembly code - i.e. it fails or gives incorrect results at runtime.
What it should do is report the omission as a compilation error. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7929 Location: Salford, UK
|
Posted: Thu Aug 02, 2007 4:20 pm Post subject: |
|
|
I have now rechecked your sample program.
The omission of the keyword "type" from "end type" causes a number of errors, all of which appear to be solved by inserting "type" except for one...
The kind value 1 used in nint (within SetTestType2) does not appear to work in this context (it is omitted in SetTestType where it is applied to int instead).
This kind value is conveniently redundant because you are assigning to an integer*1 anyway. If you leave it out you get the right answer.
Note also that the interface statements are redundant. |
|
Back to top |
|
|
acw
Joined: 04 Nov 2005 Posts: 165 Location: Darkest Devon
|
Posted: Fri Aug 03, 2007 10:47 am Post subject: |
|
|
Paul,
I'm afraid I have no such luck - the only problem fixed by the "end type" is the crash when initialising the "realVals" array after the type decl. The "operand incompatible with opcode" errors are all exactly the same - both in SetTestType and SetTestType2, even when I remove the kind parameter and just use nint, ie:
tt%intKind1 = nint(realVals(idx,4))
The only way I can get it to work is to introduce an intermediate 32-bit integer, if I introduce an 8-bit integer it compiles but does not assign any value to the 8-bit int when run, so this works fine:
subroutine SetTestType(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
integer:: i ! 32-bit intermediate is okay
i = nint(realVals(idx,4))
tt%intKind1 = i
end subroutine SetTestType
but this compiles but doesn't doesn't actually assign a value to i:
subroutine SetTestType(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
integer*1:: i ! 8-bit int, the line below results in i being "undefined"
i = nint(realVals(idx,4),1)
tt%intKind1 = i
end subroutine SetTestType
and if I omit the ,1 in nint the "incompatible with opcode" compiler error appears again.
Maybe our compiler options are different ? I only get the error when I have "checking code" (/check) on, and all other checking options off (if I enable any others my main code doesn't run properly due to the presence of binary data, or other problems with bounds checking of allocatable arrays). Incidentally, with /check off the nint(...,1) above does sets i (incorrectly) to 0 rather than undefined.
I can supply you with my full Visual Studio 2005 project if it helps
Thanks for the info on interfaces - I must admit to being a bit paranoid about them having had lots of problems in the past with optional parameters and things going wrong when, for example, I pass an 8-bit integer in to a 32-bit parameter. However it all seems okay in the test program so I will relax it a bit.
Alan |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Fri Aug 03, 2007 2:49 pm Post subject: |
|
|
Alan,
I once had a perplexing "illegal instruction" error problem that manifested on some machines and not others - I can't remember whether it was "operand incompatible with opcode" or not (though it rings a bell). Anyway, it turns out that there is a compiler switch /P6 (uses some instructions only available on a Pentium 6 or higher) which I was inadvertently using for the app in question - and some of the machines were insufficiently speccy.
So check your project properties carefully for compiler options - this switch can cause problems if your machine is not up to scratch.
Funnily enough, I noticed just the other day that one of my projects had this switch activated for all of the checkmate, debug and release build properties (I use Plato not Visual Studio), and wondered how it got there. I've certainly never applied it myself intentionally. I just created a new project to see if /P6 is used by default, but no. I haven't checked any other projects, but at the moment, of the two I have checked, one does and one doesn't. I'm wondering if it has been on by default in a previous release of Plato, and is now off by default?
I'm off to check a few more now. I've been having a variety of odd problems with a new version of an app of mine recently, which has to run on some quite old machines, and I'm wondering if this switch is ) on and b) implicated.
Andy |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Fri Aug 03, 2007 3:46 pm Post subject: More on /P6 |
|
|
Sorry for following up to self, but I've checked quite a few projects now, and it's all rather curious.
1) I checked 13 "projects" that I created between March 2005 and July 2007. I say "projects" because the amount of code in each is tiny - each one has been created when I have needed to produce code to illustrate a bug report or a technical query. These are good because they tend to get completed quickly and then ignored, so the project file timestamp is probably an accurate indication of when they were created. I can find no evidence for the /P6 switch being on before a certain date, and off afterwards. In every case, the switch is either on or off in all of the three builds (checkmate, debug and release). Of the 13 projects, 5 have the switch on (Mar 05, Oct 05, Aug 06 and 2 x Jan 07), and 8 off (Jul 06 - Jul 07).
2) Of three real projects that are ongoing, one does not have the switch on, one does - and curiously, one is "mixed" (it's on in the checkmate build, and off in the other two builds).
As I said, I have never knowingly used this switch. No idea how to interpret these findings, I'm just passing them on in hope a Silverfrostian may be able to.
Andy |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7929 Location: Salford, UK
|
Posted: Fri Aug 03, 2007 6:37 pm Post subject: |
|
|
There is a command log in Visual Studio and also in the latest version of Plato so you can see what the default options are.
My guess is that P6 is on by default in Visual Studio.
I think Plato had it as the default for a while but not any longer because there are still some old processors around.
I cannot help any further with the basic problem for a while.
If you want to post a new sample with the version number of FTN95 and the exact command line then I will look at it when I can. |
|
Back to top |
|
|
acw
Joined: 04 Nov 2005 Posts: 165 Location: Darkest Devon
|
Posted: Mon Aug 06, 2007 8:18 pm Post subject: |
|
|
Paul,
Here's the build log and code that fails on compile - code is pretty much as it was but with correct end type and no interface. Remove /CHECK and it compiles but the value assigned in SetTestType2 is wrong (0 in XP, 120 in Vista).
Cheers,
Alan
Build log:
======
Compiling...
Compiling file: FreeFormat1.f95
FTN95.EXE "D:\Alan\Documents\Source\IntCompileBug\IntCompileBug\FreeFormat1.f95" /NO_BANNER /DEBUG /CHECK /P6 /FPP/VS8 /DELETE_OBJ_ON_ERROR /ERROR_NUMBERS /UNLIMITED_ERRORS /BINARY "Debug\Win32\FreeFormat1.obj"
Compiler output:
D:\Alan\Documents\Source\IntCompileBug\IntCompileBug\FreeFormat1.F95(16) : error 137: Operand incompatible with opcode
D:\Alan\Documents\Source\IntCompileBug\IntCompileBug\FreeFormat1.F95(12) : error 52: Compilation abandoned
There were compile errors, no link performed
Code log:
======
! Demonstrate comiler bug with 2D arrays in modules whth /check option
module TestMod
type TestType
integer*1:: intKind1
end type TestType
real:: realVals(10,10) = 42.55
contains
subroutine SetTestType(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
tt%intKind1 = nint(realVals(idx,4)) ! generates "operand incompatible with opcode" when realVals is 2D array
! creating an intermediate integer*4 solves the problem
end subroutine SetTestType
subroutine SetTestType2(tt, idx)
type(TestType), intent(in out):: tt
integer, intent(in):: idx
tt%intKind1 = nint(realVals(idx,4), 1) ! this is 52 with /check, 0 without
end subroutine SetTestType2
end module TestMod
winapp
use TestMod
type(TestType):: newtt
integer*1:: i1
call SetTestType(newtt, 3)
call SetTestType2(newtt, 4)
end |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|