[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::fortran

Title:Digital Fortran
Notice:Read notes 1.* for important information
Moderator:QUARK::LIONEL
Created:Thu Jun 01 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:1333
Total number of notes:6734

1229.0. "DFAV looking for better compiler checking" by CSC32::D_SANFORD () Tue Mar 18 1997 23:07

    Digital Fortran 77 V7.1-107, OpenVMS Alpha V6.2

    Below I've included four problem statments with three examples to
    demonstrate these.

    1) bogus FNCMATERR error

       Possible problem, using REAL*8 FUNCTION causes no error, but 
       without this the listing shows it as the same data type.

    2) no mismatch errors for function dummy arguments

       I believe this to be expected behavior when you start playing
       games with the way you pass arguments or routine addresses, 
       don't see how the compiler can catch these.

    3) CALLing a function is not reported as an error

       Don't see how the customer sees this as a problem, if you don't
       want the FUNCTION return value you CALL it, but maybe he is 
       really looking to get a informational or warning flagged.

    4) invoking a SUBROUTINE as if it were a function is sometimes NOT flagged

       He cannot duplicate this behavior, I believe he is using some
       level of indirection like passing the address of a FUNCTION or
       something.

    Hope this doesn't seem too silly!  

    Regards, Drew Sanford
    Customer Support Center
    C970304-6848

$! This is file TEST.COM
$ set noon
$ create sys$output

 ------------------------------------------------------------------
 Demonstration 1:

    Following example generates bogus FNCMATERR errors:

$ fort/nolis/noopt/noob/warn=(ar,noali,noin,nounc,nouni,nounr,nous)-
  /syntax_only sys$input:
        IMPLICIT REAL*8 (A-H,O-Z), INTEGER (I-N)

        a8 = gauss (ix)
        end

C     If you use REAL*8 FUNCTION GAUSS it works
      FUNCTION GAUSS(IX)
      IMPLICIT REAL*8 (A-H,O-Z), INTEGER (I-N)
      G=0
      DO 1 I=1,12
    1 G = G+URAND(IX)
      GAUSS = G - 6
      RETURN
      END

$
$ create sys$output

 ------------------------------------------------------------------
 Demonstration 2:

  Following example shows no mismatch errors for function dummy arguments:

$ fort/nolis/noopt/noob/warn=(ar,noali,noin,nounc,nouni,nounr,nous) -
  /syntax_only sys$input:
C ** compiler doesn't give mismatch errors for dummy args which
C ** are functions

        implicit        none
        external        ftest
        integer*4       ftest

        call    b (ftest)
        end

        subroutine b (fdummy)
        implicit        none

        real*4  fdummy, x

        x = fdummy ()
        return
        end

        real*8  function ftest ()
        implicit        none

        ftest = 1.d0
        return
        end
$
$
$ create sys$output


 ------------------------------------------------------------------
 Demonstration 3:

   Following example shows that CALLing a function is not reported as an
error:

$ fort/nolis/noopt/noob/warn=(ar,noali,noin,nounc,nouni,nounr,nous) -
  /syntax_only sys$input:
c
c ** functions that are 'called' are not reported.
c
        implicit        none

        call funca ()
        end

        integer*4 function      funca ()
        funca = 1
        return
        end
$
T.RTitleUserPersonal
Name
DateLines
1229.1CSC32::D_SANFORDWed Mar 19 1997 16:3580
  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.
1229.2Fixed, explained, noted!TLE::EKLUNDAlways smiling on the inside!Thu Mar 20 1997 11:1652
    	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
    
1229.3CSC32::D_SANFORDTue Mar 25 1997 11:245
    Thank you for the update, I will inform the customer that some of
    these problems will be corrected in a future release.  Didn't
    realize he found soo many problems, this was from Stanford...
    
    -drew
1229.4one final update - just in case we missed somethingCSC32::D_SANFORDTue Mar 25 1997 19:5759
  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.