Menu

#892 Bug when default calling via a pointer to a 'Sub' defined with the only 'Any Ptr' optional parameter

closed
nobody
None
compiler
2022-04-29
2018-11-05
No

Since fbc 0.90.0, default calling via a pointer does not support a 'Sub' defined with the only 'Any Ptr' optional parameter:

Sub test (Byval p As Any Ptr = 0)
  Print "text"
End Sub

test(0)
test()

Dim As Sub (Byval As Any Ptr = 0) ptest = @test
ptest(0)
ptest()  '' error 1: Argument count mismatch

Sleep

The program compiles:

  • with any other optional pointer type,
  • if there is any other parameter,
  • with 'Function' pointer.
    Example:
Sub test (Byval p As Any Ptr = 0)
  Print "text"
End Sub

test(0)
test()

Dim As Function (Byval As Any Ptr = 0) As Integer ptest = Cast(Any Ptr, @test)
ptest(0)
ptest()

Sleep

See also forum topic at https://www.freebasic.net/forum/viewtopic.php?f=3&t=27139

Discussion

  • Jeff Marshall

    Jeff Marshall - 2021-12-05

    Cause of this bug is due to internal mangling of function pointer types. Function pointers are given a unique name internally so that they can be re-used and checked for compatibility. However, this internal encoding does not include the optional parameters, so only the first usage of the function pointer is stored. When a second use of a function pointer is used that differs only by optional parameters, the first one is returned.

    Example:

    declare sub proc1( byval x as integer )
    declare sub proc2( byval x as integer = 123 )
    
    var p1 = @proc1  '' typeof(@proc1) is stored internally
    var p2 = @proc2  '' internal lookup matches typeof(@proc1)
                     '' and typeof(@proc2) is discarded even though
                     '' the optional arguments are different
    
    p2()  '' error: argument count mismatch
    

    For the bug reported here, the following function pointer:
    Dim As Sub (Byval As Any Ptr = 0) ptest = @test
    Is already defined internally by the ThreadCreate prototype and takes no optional parameter:

    Declare Function Threadcreate _
    ( _
    ByVal procptr As Sub ( ByVal userdata As Any Ptr ), _
    ByVal param As Any Ptr = 0, _
    ByVal stack_size As Integer = 0 _
    ) As Any Ptr
    

    A reasonable fix to try would be to encode the optional parameters as part of the internally mangled name. (immediately after or as part of the {fbfp} prefix in the internal name)

     
  • Jeff Marshall

    Jeff Marshall - 2021-12-05

    It is reasonable to encode which parameters are optional in the internal name. It is not reasonable to encode the default in to the name. I think it's possible to at least fix the reported bug but a full solution will be more complicated, as can see here with some unanswered questions:

    sub proc1( byval x as integer = 123 )
        print x
    end sub
    
    sub proc2( byval x as integer )
        print x
    end sub
    
    dim p1 as sub( byval x as integer = 123 ) = @proc1  '' OK
    dim p2 as sub( byval x as integer = 456 ) = @proc1  '' OK (or should be error/warning?)
    dim p3 as sub( byval x as integer       ) = @proc1  '' OK (or should be error/warning?)
    
    dim p4 as sub( byval x as integer = 789 ) = @proc2  '' OK (or should be error/warning?)
    
    p1() '' 123
    p2() '' 123 (or should be 456?    )
    p3() '' 123 (or should be error? )
    p4() '' 123 (or should be 789?   )
    

    I think, if the internal function pointer typedef has capability to record optional parameters (which it almost does) then, the function pointer should be followed for optional parameters and default values. If function matching is a serious concern then can deal with it as a warning in variable assignment, parameter passing, etc.

     
  • Jeff Marshall

    Jeff Marshall - 2021-12-18

    A reasonable fix in fbc 1.09.0.

    • fbc now differentiates between function pointers that have different numbers and positions of optional parameters
    • It's not perfect. The first use of a procedure pointer with optional parameters (unique by number and position) determines which default values will be used when the function pointer is used. A lot more work would be needed to differentiate function pointers based on the value of the defaults.
      -the commit message should be for this ticket 892 but on the commit incorrectly reads 982 (will get fixed in a future commit)

    commit: [1707d741dce612b4e2d7a08ba081e88489e8f90c]

     

    Related

    Commit: [1707d7]

  • Jeff Marshall

    Jeff Marshall - 2021-12-18
    • status: open --> closed
     
  • TeeEmCee

    TeeEmCee - 2022-01-19

    I found what looks like essentially the same bug has been introduced in FB 1.09 (seen in an official Windows build, and one from git on Linux). It was not there (in git) a few months ago or with previous FB versions. I think it's better to reopen this bug report for all the relevant discussion here than file a new one.

    extern func1 as function (min_height as integer = 0) as integer
    extern func2 as function (byval y as integer) as integer
    dim func1 as function (min_height as integer = 0) as integer
    

    produces "error 20: Type mismatch, func1 in 'dim func1 as function (min_height as integer = 0) as integer'".
    Not specific to functions with one integer arg: error remains on adding more args to the function pointers.

     
  • Jeff Marshall

    Jeff Marshall - 2022-04-15
    • status: closed --> open
     
  • Jeff Marshall

    Jeff Marshall - 2022-04-23

    Bug appears to be a typo in symbLookupInternallyMangledSubtype() causing only the first function pointer (in each list of function pointers of a chain) to be checked. Typo is a chain_->sym that should be sym.

     
  • Jeff Marshall

    Jeff Marshall - 2022-04-29
    • status: open --> closed
     

Log in to post a comment.

MongoDB Logo MongoDB