| Some additional information from the customer. I really don't want to
take a 30 block reproducer...
---------------(Issue #4) ---------------
This is to supply some more information about issue #4 -- compiler
sometimes issues diagnostic message about invoking a subroutine as
if it were a function, but not always.
As I mentioned, I have an example that demonstrates it; I've reduced
that example from 80 blocks to 30 blocks, and I believe I see why
the diagnostic is issued in some cases, but not from others.
To get the diagnostic (FORT-I-NORETVAL) at all, seems to require
/opt/warn=info (but warn=arg is NOT needed and /NOOPT kills the
message), and source code in question must be compiled together.
So, this checking apparently has nothing to do with the warn=arg
checking, but has something to do with /opt. My guess is that has
something to do with the INLINEing part of optimization. Perhaps
in those cases where the compiler decides to INLINE the call it
issues the message, but in other similar cases where it decides
NOT to INLINE the call, there is no message.
I can send you the 30 block example, if you wish.
COMMENT: it seems to me this checking should be part of the same
logic (invoked by /warn=arg) that generates FNCMATERR
messages, not something that evokes a comment from the
compiler only in certain very special circumstances.
---------------(Issue #1) ---------------
I have also revisited issue #1, reporting errors about function type
mismatches between the caller's declaration and the actual function.
I formerly said that I thought that the compiler did this properly (when
code is compiled together with /warn=arg specified.) Now, I
find, there are at least some cases that it misses here as well.
The following example shows a test with two such mismatches, one
is reported, the other is not. The one which is not is a function
with no arguments; I don't think this is a coincidence.
$ fort/nolis/noopt/noob/warn=(ar,noali,noin,nounc,nouni,nounr,nous) -
/syntax sys$input:
program main
real*4 func8a, func8b, var4
var4 = func8a (10)
call dummy (var4)
var4 = func8b ()
call dummy (var4)
end
real*8 function func8a (int)
integer*4 int
func8a = int
return
end
real*8 function func8b ()
func8b = 10.d0
return
end
$! end of test file.
When I execute this example, I get
var4 = func8a (10)
...............^
%FORT-W-FNCMATERR, Data type for function call ( RealF*4 ) is not equal to
actual function data type ( RealG*8 ).
at line number 4 in file SYS$INPUT:.;
COMMENT: It looks as if the case of 'no arguments' prevents the
full argument checking (including function type) from
being done. This doesn't make a lot of sense.
|
| First of all, let me state that actual/formal argument
checking is not "perfect". We allow certain "invalid" constructs
because they are so commonly used in dusty deck sources. We are
primarily concerned with the more blatant mismatches.
Having said that, let's consider your examples.
1. This is a bug. When the declaration of the actual function
type occurs AFTER the function statement, we fail to update one
(there are several) of the TYPE fields in the symbol table. This
results in incorrect messages (but correct code). I've fixed this
with edit 4-128.
2. Passing a (typed) function name to a routine which declares its
dummy argument to have a DIFFERENT type results in no warning. This
is a case we do not catch. The reason for not reporting this case
is that the actual argument is being passed "by value", and we do NOT
report any mismatches for such arguments. A similar case is:
call foo(%val(30))
end
subroutine foo(x)
end
In some sense an actual passed "by value" is allowed to match ANY
dummy data type. Part of the reason for this is that this might be a
typeless subroutine name. We agree that this could be improved, but the change
is not simple. We will add this as a possible future enhancement.
There is no way to easily check at compile time the other mismatch,
the (indirect) reference using fdummy and the function ftest. That's
unlikely to ever get detected/reported.
3/4. We do not attempt to catch subroutines used as functions and
vice versa. Sometimes other error messages will be issued when,
for example, a return value is expected, but not set. This is a
fallout of an entirely different piece of code, only available
when optimizing (it relies upon graphing information). Since
there are a LOT of user programs doing this rather terrible thing, we do
not plan to add the code to detect these cases. Another case of the
real world intruding!
Your note .1 raises another issue regarding our not reporting
a mismatched function type when the function has no arguments.
This is also a bug in the code, and I've corrected it with edit
4-128. We were too anxious to get out when there were no arguments,
so failed to detect the mismatch for the function actual/formal
types.
Thank you for pointing out these problems, issues, and suggestions.
I hope that the patch and explanations are what you need.
Cheers!
Dave Eklund
|
| From the customer, we are closing the call at the support center,
but wanted to pass on his final remarks.
-drew
Thanks for the answers to these questions. They clarify the
situation quite well in almost all the situations I inquired about.
The one case which wasn't addressed specifically (although perhaps
it was addressed generally), was the case of a checking that the
user was accessing a subroutine as if it were a function. (This
has been a real issue for us in going from VAX to Alpha, as our
functions generally return T/F (almost always T), and the VAX
tended to leave T in R0 when a subroutine returned, so the broken
code typically 'worked' on the VAX.)
So I made a little test compiling modules together with /OPT, and
found that it detected this problem (with FORT-I-NORETVAL).
Only later did I find that it was being extremely selective about
when it would detect these errors; I _speculate_ it may have been
reporting the error only it decided to INLINE the call. This
is certainly very mysterious behaviour to the user (me), and
violates the fundamental dictum of "create the least astonishment"
that should apply to all software.
So, just in case this situation was overlooked in your review of
the all problems reported, I've attached it below.
If you want to close the call, that's fine.
-------------------------------------------------------------------
From my last previous communication on this case:
| This is to supply some more information about issue #4 -- compiler
| sometimes issues diagnostic message about invoking a subroutine as
| if it were a function, but not always.
|
| As I mentioned, I have an example that demonstrates it; I've reduced
| that example from 80 blocks to 30 blocks, and I believe I see why
| the diagnostic is issued in some cases, but not from others.
|
| To get the diagnostic (FORT-I-NORETVAL) at all, seems to require
|
| /opt/warn=info (but warn=arg is NOT needed and /NOOPT kills the
| message), and source code in question must be compiled together.
|
| So, this checking apparently has nothing to do with the warn=arg
| checking, but has something to do with /opt. My guess is that has
| something to do with the INLINEing part of optimization. Perhaps
| in those cases where the compiler decides to INLINE the call it
| issues the message, but in other similar cases where it decides
| NOT to INLINE the call, there is no message.
|
| I can send you the 30 block example, if you wish.
|
| COMMENT: it seems to me this checking should be part of the same
| logic (invoked by /warn=arg) that generates FNCMATERR
| messages, not something that evokes a comment from the
| compiler only in certain very special circumstances.
|