Skip to content

Commit 064acc9

Browse files
committed
Fix #767: Show proper error for illegal byref result assignments
(and not just a warning) (cherry picked from commit ae86415)
1 parent 8b8c0a9 commit 064acc9

12 files changed

+73
-11
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Version 1.02.1
1414
- bindings: Various previously untranslated (or wrongly translated) #defines in SDL2, X11, crt/pthread, Windows API
1515
- Windows API binding: DirectX headers missed some declarations and some didn't compile
1616
- crt/string.bi, crt/mem.bi: Added CONSTs to function declarations
17+
- #767: Illegal byref result assignments will now cause a proper error message, not just a warning
1718

1819

1920
Version 1.02.0

src/compiler/ast-node-assign.bas

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,18 @@ function astCheckASSIGNToType _
370370
astDelTree( l )
371371
end function
372372

373+
'' Check whether it's ok to assign
374+
'' l = r
375+
'' where l is a reference.
376+
function astCheckByrefAssign _
377+
( _
378+
byval ldtype as integer, _
379+
byval lsubtype as FBSYMBOL ptr, _
380+
byval r as ASTNODE ptr _
381+
) as integer
382+
function = (typeCalcMatch( ldtype, lsubtype, FB_PARAMMODE_BYREF, r->dtype, r->subtype ) > 0)
383+
end function
384+
373385
private function hShallowCopy _
374386
( _
375387
byval l as ASTNODE ptr, _

src/compiler/ast.bi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,13 @@ declare function astCheckASSIGNToType _
904904
byval r as ASTNODE ptr _
905905
) as integer
906906

907+
declare function astCheckByrefAssign _
908+
( _
909+
byval ldtype as integer, _
910+
byval lsubtype as FBSYMBOL ptr, _
911+
byval r as ASTNODE ptr _
912+
) as integer
913+
907914
declare function astCheckConvNonPtrToPtr _
908915
( _
909916
byval to_dtype as integer, _

src/compiler/error.bas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ declare function hMakeParamDesc _
398398
@"CONST used on constructor (not needed)", _
399399
@"CONST used on destructor (not needed)", _
400400
@"Byref function result not set", _
401-
@"Function result assignment outside of the function" _
401+
@"Function result assignment outside of the function", _
402+
@"Type mismatch in byref function result assignment" _
402403
}
403404

404405

src/compiler/error.bi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ enum FB_ERRMSG
320320
FB_ERRMSG_CONSTDTOR
321321
FB_ERRMSG_NOBYREFFUNCTIONRESULT
322322
FB_ERRMSG_RESULTASSIGNOUTSIDEFUNCTION
323+
FB_ERRMSG_TYPEMISMATCHINBYREFRESULTASSIGN
323324

324325
FB_ERRMSGS
325326
end enum

src/compiler/parser-proccall.bas

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,20 @@ function cAssignFunctResult( byval is_return as integer ) as integer
9191
errReport( FB_ERRMSG_INVALIDREFERENCETOLOCAL )
9292
end if
9393

94-
'' BYREF AS STRING and expression is a string literal?
95-
if( (symbGetType( parser.currproc ) = FB_DATATYPE_STRING) and _
96-
(astGetStrLitSymbol( rhs ) <> NULL) ) then
97-
'' Cannot be allowed, since a string literal is not
98-
'' an FBSTRING descriptor...
99-
errReport( FB_ERRMSG_INVALIDDATATYPES )
94+
'' Even though we'll only assign a pointer (it's byref afterall),
95+
'' check the types as if it was a direct assignment. Advantages:
96+
'' * errors instead of warnings
97+
'' * nicer error messages such as "type mismatch" instead of
98+
'' "suspicious pointer assignment" warnings (which don't make sense
99+
'' since the pointer basically is an implementation detail)
100+
if( astCheckByrefAssign( parser.currproc->typ, parser.currproc->subtype, rhs ) = FALSE ) then
101+
errReport( FB_ERRMSG_TYPEMISMATCHINBYREFRESULTASSIGN )
100102
astDelTree( rhs )
101-
rhs = NULL
102-
else
103-
'' Implicit addrof due to BYREF
104-
rhs = astNewADDROF( rhs )
103+
rhs = astNewCONSTz( parser.currproc->typ, parser.currproc->subtype )
105104
end if
105+
106+
'' Implicit addrof due to BYREF
107+
rhs = astNewADDROF( rhs )
106108
end if
107109
else
108110
rhs = cExpression( )

src/compiler/symb-data.bas

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,13 @@ function closestType _
491491

492492
end function
493493

494+
'' Determine whether two types are compatible, for an assignment like this:
495+
'' l = r
496+
'' where l could be a reference or a variable (parameters, function results,
497+
'' variables...) and r is the source (e.g. the argument in case of parameters).
498+
'' result = 0 => incompatible
499+
'' otherwise => compatible, and the result is a matching score
500+
'' (FB_OVLPROC_FULLMATCH etc.)
494501
function typeCalcMatch _
495502
( _
496503
byval ldtype as integer, _
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
' TEST_MODE : COMPILE_ONLY_OK
2+
3+
function f() byref as const integer
4+
static i as const integer = 0
5+
function = i
6+
end function
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
' TEST_MODE : COMPILE_ONLY_OK
2+
3+
function f() byref as const integer
4+
static i as integer = 0
5+
function = i
6+
end function
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
' TEST_MODE : COMPILE_ONLY_FAIL
2+
3+
function f() byref as integer
4+
static i as double
5+
function = i
6+
end function

0 commit comments

Comments
 (0)