Skip to content

Commit

Permalink
Show error for override with different parameter modes than the virtual
Browse files Browse the repository at this point in the history
  • Loading branch information
dkl committed Apr 3, 2013
1 parent 2e0f8f2 commit 47a2067
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/compiler/error.bas
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ declare function hMakeParamDesc _
@"Override has different calling convention than overridden method", _ @"Override has different calling convention than overridden method", _
@"Implicit destructor override would have different calling convention", _ @"Implicit destructor override would have different calling convention", _
@"Implicit LET operator override would have different calling convention", _ @"Implicit LET operator override would have different calling convention", _
@"Override has different parameters than overridden method", _
@"This operator cannot be STATIC", _ @"This operator cannot be STATIC", _
@"Parameter must be an integer", _ @"Parameter must be an integer", _
@"Parameter must be a pointer", _ @"Parameter must be a pointer", _
Expand Down
1 change: 1 addition & 0 deletions src/compiler/error.bi
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ enum FB_ERRMSG
FB_ERRMSG_OVERRIDECALLCONVDIFFERS FB_ERRMSG_OVERRIDECALLCONVDIFFERS
FB_ERRMSG_IMPLICITDTOROVERRIDECALLCONVDIFFERS FB_ERRMSG_IMPLICITDTOROVERRIDECALLCONVDIFFERS
FB_ERRMSG_IMPLICITLETOVERRIDECALLCONVDIFFERS FB_ERRMSG_IMPLICITLETOVERRIDECALLCONVDIFFERS
FB_ERRMSG_OVERRIDEPARAMSDIFFER
FB_ERRMSG_OPERATORCANTBESTATIC FB_ERRMSG_OPERATORCANTBESTATIC
FB_ERRMSG_PARAMMUSTBEANINTEGER FB_ERRMSG_PARAMMUSTBEANINTEGER
FB_ERRMSG_PARAMMUSTBEAPOINTER FB_ERRMSG_PARAMMUSTBEAPOINTER
Expand Down
85 changes: 66 additions & 19 deletions src/compiler/symb-proc.bas
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2460,6 +2460,64 @@ end function
'' misc '' misc
'':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ''::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


private function hAreMethodsCompatible _
( _
byval v as FBSYMBOL ptr, _ '' The virtual that's overridden
byval o as FBSYMBOL ptr _ '' The override
) as integer

dim as FBSYMBOL ptr vparam = any, oparam = any

assert( symbIsProc( v ) and symbIsMethod( v ) )
assert( symbIsProc( o ) and symbIsMethod( o ) )

'' Different result type? (Note: SUBs have VOID result type)
if( (symbGetType ( v ) <> symbGetType ( o )) or _
(symbGetSubtype( v ) <> symbGetSubtype( o )) ) then
return FB_ERRMSG_OVERRIDERETTYPEDIFFERS
end if

'' Does one have a BYREF result, but not the other?
if( symbProcReturnsByref( v ) <> symbProcReturnsByref( o ) ) then
return FB_ERRMSG_OVERRIDERETTYPEDIFFERS
end if

'' Different calling convention?
if( symbAreProcModesEqual( v, o ) = FALSE ) then
return FB_ERRMSG_OVERRIDECALLCONVDIFFERS
end if

'' Different parameter count?
if( symbGetProcParams( v ) <> symbGetProcParams( o ) ) then
return FB_ERRMSG_OVERRIDEPARAMSDIFFER
end if

'' Check each parameter's mode and type
vparam = symbGetProcLastParam( v )
oparam = symbGetProcLastParam( o )

'' But skip THIS ptr; virtual/override will have a different types here,
'' their parent classes respectively. Since this virtual was found to
'' be overridden by this override, we know that the override's THIS
'' type is derived from the virtual's THIS type.
assert( symbIsParamInstance( vparam ) )
assert( symbIsParamInstance( oparam ) )
vparam = vparam->next
oparam = oparam->next

while( vparam )
if( (symbGetParamMode( vparam ) <> symbGetParamMode( oparam )) or _
(symbGetFullType ( vparam ) <> symbGetFullType ( oparam )) or _
(symbGetSubtype ( vparam ) <> symbGetSubtype ( oparam )) ) then
return FB_ERRMSG_OVERRIDEPARAMSDIFFER
end if
vparam = vparam->next
oparam = oparam->next
wend

function = FB_ERRMSG_OK
end function

sub symbProcCheckOverridden _ sub symbProcCheckOverridden _
( _ ( _
byval proc as FBSYMBOL ptr, _ byval proc as FBSYMBOL ptr, _
Expand All @@ -2473,25 +2531,16 @@ sub symbProcCheckOverridden _


'' Overriding anything? '' Overriding anything?
if( overridden ) then if( overridden ) then
'' Check whether override and overridden have different '' Check whether override and overridden have different return
'' return type or calling convention, this must be disallowed '' type or calling convention etc., this must be disallowed
'' (unlike with overloading) because the function signatures '' (unlike with overloading) because the function signatures
'' aren't really compatible (e.g. return on stack vs. return '' aren't really compatible (e.g. return on stack vs. return
'' in registers). '' in registers).
if( ( symbGetType( proc ) <> symbGetType( overridden )) or _
(symbGetSubtype( proc ) <> symbGetSubtype( overridden )) ) then
'' This won't happen with destructors/LET overloads
assert( is_implicit = FALSE )
errReport( FB_ERRMSG_OVERRIDERETTYPEDIFFERS )
end if

'' Check for return BYREF
if( symbProcReturnsByref( proc ) <> symbProcReturnsByref( overridden ) ) then
errReport( FB_ERRMSG_OVERRIDERETTYPEDIFFERS )
end if


if( symbAreProcModesEqual( proc, overridden ) = FALSE ) then errmsg = hAreMethodsCompatible( overridden, proc )
if( is_implicit ) then if( errmsg <> FB_ERRMSG_OK ) then
if( is_implicit and _
(errmsg = FB_ERRMSG_OVERRIDECALLCONVDIFFERS) ) then
'' symbUdtAddDefaultMembers() uses this to check '' symbUdtAddDefaultMembers() uses this to check
'' implicit dtors and LET overloads. Since they '' implicit dtors and LET overloads. Since they
'' are not visible in the original code, '' are not visible in the original code,
Expand All @@ -2501,13 +2550,11 @@ sub symbProcCheckOverridden _
else else
errmsg = FB_ERRMSG_IMPLICITLETOVERRIDECALLCONVDIFFERS errmsg = FB_ERRMSG_IMPLICITLETOVERRIDECALLCONVDIFFERS
end if end if
else
'' Normal error message that will be shown on
'' the problematic method declaration.
errmsg = FB_ERRMSG_OVERRIDECALLCONVDIFFERS
end if end if

errReport( errmsg ) errReport( errmsg )
end if end if

end if end if


end sub end sub
Expand Down
9 changes: 9 additions & 0 deletions tests/virtual/incompatible-override-10.bas
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
' TEST_MODE : COMPILE_ONLY_FAIL

type A extends object
declare virtual sub f( byval i as integer )
end type

type B extends A
declare sub f( byref i as integer )
end type
9 changes: 9 additions & 0 deletions tests/virtual/incompatible-override-11.bas
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,9 @@
' TEST_MODE : COMPILE_ONLY_FAIL

type A extends object
declare virtual sub f( byref i as integer )
end type

type B extends A
declare sub f( byval i as integer )
end type

0 comments on commit 47a2067

Please sign in to comment.