Skip to content

Commit 53304ab

Browse files
committed
parser: Don't disallow mixing RETURN/FUNCTION= in byref functions
1 parent 228ec6f commit 53304ab

File tree

4 files changed

+86
-14
lines changed

4 files changed

+86
-14
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ Version 1.01.0
6363
- 0.90.0 regression: Compiler crash during error recovery for expressions like 'type<UDT>().field' where initializer values are missing
6464
- When passing a constant zero of some integer to an overloaded procedure, overloads with integer parameters will now be preferred over overloads with pointers (literal 0 can still be passed to pointer parameters in this case though, by casting it to the pointer type)
6565
- Literal zeroes with [U]Byte or [U]Short type (or the 16bit Integer in -lang qb) can now be passed to pointer parameters of overloaded procedures (now it's possible to call Bsave() with 0 source buffer in -lang qb again -- it also was affected by this bug since FB 0.90)
66+
- RETURN and FUNCTION= couldn't be used together in byref functions returning an UDT with constructor. This check is now only applied to functions returning byval.
6667

6768

6869
Version 1.00.0 (former 0.91.0):

src/compiler/parser-compound.bas

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,20 +156,20 @@ sub cEndStatement( )
156156
end sub
157157

158158
private function hCheckForCtorResult( ) as integer
159-
function = FB_ERRMSG_OK
160-
if( symbHasCtor( parser.currproc ) ) then
161-
if( symbGetProcStatReturnUsed( parser.currproc ) ) then
159+
if( symbGetProcStatReturnUsed( parser.currproc ) ) then
160+
if( symbHasCtor( parser.currproc ) and _
161+
(not symbProcReturnsByref( parser.currproc )) ) then
162162
'' EXIT FUNCTION cannot be allowed in combination
163-
'' with RETURN and a ctor result, because it would
164-
'' not call the result constructor.
165-
function = FB_ERRMSG_MISSINGRETURNFORCTORRESULT
166-
else
167-
'' EXIT FUNCTION used, and no RETURN yet:
168-
'' make it behave like FUNCTION=, to ensure the result ctor
169-
'' is called at the top.
170-
symbSetProcStatAssignUsed( parser.currproc )
163+
'' with RETURN and a ctor result for byval functions,
164+
'' because it would not call the result constructor.
165+
return FB_ERRMSG_MISSINGRETURNFORCTORRESULT
171166
end if
172167
end if
168+
169+
'' EXIT FUNCTION used; mark the function as if FUNCTION= was used,
170+
'' to ensure the result will be constructed at the top if needed.
171+
symbSetProcStatAssignUsed( parser.currproc )
172+
function = FB_ERRMSG_OK
173173
end function
174174

175175
'':::::

src/compiler/parser-proccall.bas

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,20 @@ function cAssignFunctResult( byval is_return as integer ) as integer
4646

4747
has_ctor = symbHasCtor( parser.currproc )
4848
has_defctor = symbHasDefCtor( parser.currproc )
49+
var returns_byref = symbProcReturnsByref( parser.currproc )
4950

5051
'' RETURN?
5152
if( is_return ) then
5253
if( symbGetProcStatAssignUsed( parser.currproc ) ) then
53-
if( has_defctor ) then
54+
if( has_defctor and (not returns_byref) ) then
5455
errReport( FB_ERRMSG_RETURNMIXEDWITHASSIGN )
5556
end if
5657
end if
5758

5859
symbSetProcStatReturnUsed( parser.currproc )
5960
else
6061
if( symbGetProcStatReturnUsed( parser.currproc ) ) then
61-
if( has_defctor ) then
62+
if( has_defctor and (not returns_byref) ) then
6263
errReport( FB_ERRMSG_ASSIGNMIXEDWITHRETURN )
6364
end if
6465
end if
@@ -80,7 +81,7 @@ function cAssignFunctResult( byval is_return as integer ) as integer
8081
'' is allowed, no implicit ADDROF is done, just like with BYREF params.
8182

8283
'' Returning BYREF and no explicit BYVAL given?
83-
if( symbProcReturnsByref( parser.currproc ) and (not hMatch( FB_TK_BYVAL )) ) then
84+
if( returns_byref and (not hMatch( FB_TK_BYVAL )) ) then
8485
'' BYREF return, must be able to do addrof on the expression
8586
'' (this disallows expressions like constants, BOPs, @ UOP, ...)
8687
rhs = cVarOrDeref( FB_VAREXPROPT_ISEXPR )

tests/functions/return-byref.bas

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,75 @@ namespace cxxMangling
806806
end sub
807807
end namespace
808808

809+
namespace returnVsFunction
810+
'' For functions returning BYREF, both RETURN and FUNCTION= should be
811+
'' allowed to assign results, no matter what result type it is, since
812+
'' it's just a pointer, and the function doesn't actually have to call
813+
'' any constructor.
814+
815+
type CtorUdt
816+
i as integer
817+
declare constructor( )
818+
end type
819+
820+
constructor CtorUdt( )
821+
end constructor
822+
823+
dim shared as integer ireturn, ifunction
824+
dim shared as CtorUdt ctorudtreturn, ctorudtfunction
825+
826+
function getInteger1( ) byref as integer
827+
return ireturn
828+
function = ifunction
829+
end function
830+
831+
function getInteger2( ) byref as integer
832+
function = ifunction
833+
return ireturn
834+
end function
835+
836+
function getInteger3( ) byref as integer
837+
exit function
838+
return ireturn
839+
end function
840+
841+
function getInteger4( ) byref as integer
842+
return ireturn
843+
exit function
844+
end function
845+
846+
function getCtorUdt1( ) byref as CtorUdt
847+
return ctorudtreturn
848+
function = ctorudtfunction
849+
end function
850+
851+
function getCtorUdt2( ) byref as CtorUdt
852+
function = ctorudtfunction
853+
return ctorudtreturn
854+
end function
855+
856+
function getCtorUdt3( ) byref as CtorUdt
857+
exit function
858+
return ctorudtreturn
859+
end function
860+
861+
function getCtorUdt4( ) byref as CtorUdt
862+
return ctorudtreturn
863+
exit function
864+
end function
865+
866+
sub test cdecl( )
867+
CU_ASSERT( @(getInteger1( )) = @ireturn )
868+
CU_ASSERT( @(getInteger2( )) = @ireturn )
869+
CU_ASSERT( @(getInteger3( )) = 0 )
870+
CU_ASSERT( @(getInteger4( )) = @ireturn )
871+
CU_ASSERT( @(getCtorUdt1( )) = @ctorudtreturn )
872+
CU_ASSERT( @(getCtorUdt2( )) = @ctorudtreturn )
873+
CU_ASSERT( @(getCtorUdt3( )) = 0 )
874+
CU_ASSERT( @(getCtorUdt4( )) = @ctorudtreturn )
875+
end sub
876+
end namespace
877+
809878
private sub ctor( ) constructor
810879
fbcu.add_suite( "tests/functions/return-byref" )
811880
fbcu.add_test( "returning globals", @returnGlobal.test )
@@ -830,6 +899,7 @@ private sub ctor( ) constructor
830899
fbcu.add_test( "explicit BYVAL", @explicitByval.test )
831900
fbcu.add_test( "returning a forward ref", @protoReturningFwdref.test )
832901
fbcu.add_test( "C++ mangling", @cxxMangling.test )
902+
fbcu.add_test( "ReturnVsFunction", @returnVsFunction.test )
833903
end sub
834904

835905
end namespace

0 commit comments

Comments
 (0)