Skip to content

Commit a5b7fad

Browse files
committed
overload: Allow passing constant 0 Byte/Short to pointer params
This makes the behaviour of normal and overloaded calls match. ast-node-conv allows assigning a literal zero integer to a pointer even if the integer type's size didn't match the pointer size. hCalcTypesDiff() on the other hand had a check only allowing this if the type size matched. To fix this, the non-ptr-to-ptr checking code from ast-node-conv.bas is extracted into a helper function which is now called by hCalcTypesDiff(), replacing the bogus size check. This should ensure that both overload resolution and normal cast/conv checks will behave the same (as far as passing literal zeroes to pointers is concerned). This also fixes the issue where it was no longer possible to call Bsave in -lang qb with 0 as the 2nd parameter (which is a pointer), since commit 07d6977 in FB 0.90 which turned Bsave() into an overloaded function.
1 parent 04f033c commit a5b7fad

File tree

7 files changed

+60
-40
lines changed

7 files changed

+60
-40
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Version 1.01.0
5959
- PRINT now disallows commas/newlines after SPC/TAB, instead of silently ignoring them
6060
- 0.90.0 regression: Compiler crash during error recovery for expressions like 'type<UDT>().field' where initializer values are missing
6161
- 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)
62+
- 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)
6263

6364

6465
Version 1.00.0 (former 0.91.0):

src/compiler/ast-node-conv.bas

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,41 @@ private function hGetTypeMismatchErrMsg( byval options as AST_CONVOPT ) as integ
104104
end if
105105
end function
106106

107+
function astCheckConvNonPtrToPtr _
108+
( _
109+
byval to_dtype as integer, _
110+
byval expr_dtype as integer, _
111+
byval expr as ASTNODE ptr, _
112+
byval options as AST_CONVOPT _
113+
) as integer
114+
115+
assert( typeIsPtr( to_dtype ) )
116+
assert( typeIsPtr( expr_dtype ) = FALSE )
117+
118+
select case as const typeGet( expr_dtype )
119+
case FB_DATATYPE_INTEGER, FB_DATATYPE_UINT, FB_DATATYPE_ENUM, _
120+
FB_DATATYPE_LONG, FB_DATATYPE_ULONG, _
121+
FB_DATATYPE_LONGINT, FB_DATATYPE_ULONGINT
122+
'' Allow integer-to-pointer casts if same size
123+
if( typeGetSize( expr_dtype ) = env.pointersize ) then
124+
return FB_ERRMSG_OK
125+
end if
126+
127+
'' only allow other int dtypes if it's 0 (due QB's INTEGER = short)
128+
case FB_DATATYPE_BYTE, FB_DATATYPE_UBYTE, _
129+
FB_DATATYPE_SHORT, FB_DATATYPE_USHORT
130+
if( astIsCONST( expr ) ) then
131+
if( astConstEqZero( expr ) ) then
132+
'' Allow 0-to-pointer casts
133+
return FB_ERRMSG_OK
134+
end if
135+
end if
136+
137+
end select
138+
139+
function = hGetTypeMismatchErrMsg( options )
140+
end function
141+
107142
private function hCheckPtr _
108143
( _
109144
byval to_dtype as integer, _
@@ -117,35 +152,11 @@ private function hCheckPtr _
117152

118153
'' to pointer? only allow integers of same size, and pointers
119154
if( typeIsPtr( to_dtype ) ) then
120-
select case as const typeGet( expr_dtype )
121-
case FB_DATATYPE_INTEGER, FB_DATATYPE_UINT, FB_DATATYPE_ENUM, _
122-
FB_DATATYPE_LONG, FB_DATATYPE_ULONG, _
123-
FB_DATATYPE_LONGINT, FB_DATATYPE_ULONGINT
124-
'' Allow integer-to-pointer casts if same size
125-
if( typeGetSize( expr_dtype ) = env.pointersize ) then
126-
exit function
127-
end if
128-
return hGetTypeMismatchErrMsg( options )
129-
130-
'' only allow other int dtypes if it's 0 (due QB's INTEGER = short)
131-
case FB_DATATYPE_BYTE, FB_DATATYPE_UBYTE, _
132-
FB_DATATYPE_SHORT, FB_DATATYPE_USHORT
133-
if( astIsCONST( expr ) ) then
134-
if( astConstEqZero( expr ) ) then
135-
'' Allow 0-to-pointer casts
136-
exit function
137-
end if
138-
end if
139-
140-
return hGetTypeMismatchErrMsg( options )
141-
142-
case FB_DATATYPE_POINTER
143-
'' Both are pointers, fall through to checks below
155+
if( typeIsPtr( expr_dtype ) = FALSE ) then
156+
return astCheckConvNonPtrToPtr( to_dtype, expr_dtype, expr, options )
157+
end if
144158

145-
case else
146-
'' Nothing else allowed (strings, structs)
147-
return hGetTypeMismatchErrMsg( options )
148-
end select
159+
'' Both are pointers, fall through to checks below
149160

150161
'' from pointer? only allow integers of same size and pointers
151162
elseif( typeIsPtr( expr_dtype ) ) then

src/compiler/ast.bi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,14 @@ declare function astCheckASSIGNToType _
900900
byval r as ASTNODE ptr _
901901
) as integer
902902

903+
declare function astCheckConvNonPtrToPtr _
904+
( _
905+
byval to_dtype as integer, _
906+
byval expr_dtype as integer, _
907+
byval expr as ASTNODE ptr, _
908+
byval options as AST_CONVOPT _
909+
) as integer
910+
903911
declare function astCheckCONV _
904912
( _
905913
byval to_dtype as integer, _

src/compiler/symb-proc.bas

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,18 +1703,8 @@ private function hCalcTypesDiff _
17031703
return 0
17041704
end if
17051705

1706-
'' not a numeric constant?
1707-
if( astIsCONST( arg_expr ) = FALSE ) then
1708-
return 0
1709-
end if
1710-
1711-
'' not 0 (NULL)?
1712-
if( astConstEqZero( arg_expr ) = FALSE ) then
1713-
return 0
1714-
end if
1715-
1716-
'' not native pointer width?
1717-
if( typeGetSize( arg_dtype ) <> env.pointersize ) then
1706+
'' Allow passing literal 0 (with some non-ptr integer type) to the ptr
1707+
if( astCheckConvNonPtrToPtr( param_dtype, arg_dtype, arg_expr, 0 ) <> FB_ERRMSG_OK ) then
17181708
return 0
17191709
end if
17201710

tests/gfx/bsave-nullptr-fb.bas

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
' TEST_MODE : COMPILE_ONLY_OK
2+
bsave("foo.bmp", 0)

tests/gfx/bsave-nullptr-qb.bas

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
' TEST_MODE : COMPILE_ONLY_OK
2+
#lang "qb"
3+
bsave("foo.bmp", 0)

tests/overload/pointers.bas

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@ namespace const0
816816
private sub test cdecl( )
817817
a( cptr( any ptr, 0 ) )
818818
a( 0 )
819+
a( 0u )
819820
a( cint( 0 ) )
820821
a( cuint( 0 ) )
821822
#ifdef __FB_64BIT__
@@ -829,6 +830,10 @@ namespace const0
829830
a( clng( 0 ) )
830831
a( culng( 0 ) )
831832
#endif
833+
a( cbyte( 0 ) )
834+
a( cubyte( 0 ) )
835+
a( cshort( 0 ) )
836+
a( cushort( 0 ) )
832837

833838
#macro makeTest1( suffix, result )
834839
CU_ASSERT( f1_##suffix( cptr( any ptr, 0 ) ) = "any ptr" )

0 commit comments

Comments
 (0)