Skip to content

Commit 7c4eeec

Browse files
committed
Fix #823: Function overload resolution for [const] array() and passing non-const array argument to const array parameter
1 parent 54c59c9 commit 7c4eeec

File tree

3 files changed

+141
-9
lines changed

3 files changed

+141
-9
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Version 1.06.0
8282
- #866: fbc was throwing lexer errors in comments stating with $. Comments are lexed for directives; allow suffixes in comments
8383
- #858: C backend: fix internal structure size mismatch due to wrong padding when nesting packed structures
8484
- C backend: fix array descriptor mangling to avoid naming conflicts where array data types differ only by const
85+
- #823: Function overload resolution for [const] array() and passing non-const array argument to const array parameter
8586

8687

8788
Version 1.05.0

src/compiler/symb-proc.bas

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,19 +1883,18 @@ private function hCheckOvlParam _
18831883
return FB_OVLPROC_NO_MATCH
18841884
end if
18851885

1886-
'' not a full match?
1887-
if( param_dtype <> arg_dtype ) then
1888-
return FB_OVLPROC_NO_MATCH
1889-
end if
1890-
1891-
if( param_subtype <> arg_subtype ) then
1892-
return FB_OVLPROC_NO_MATCH
1893-
end if
1886+
var match = typeCalcMatch( param_dtype, param_subtype, symbGetParamMode( param ), arg_dtype, arg_subtype )
18941887

1888+
'' not same type?
1889+
if( match < FB_OVLPROC_TYPEMATCH ) then
1890+
return FB_OVLPROC_NO_MATCH
1891+
end if
1892+
18951893
assert( astIsVAR( arg_expr ) or astIsFIELD( arg_expr ) )
18961894
array = arg_expr->sym
18971895
assert( symbIsArray( array ) )
18981896

1897+
18991898
'' If the BYDESC parameter has unknown dimensions, any array can be passed.
19001899
'' Otherwise, only arrays with unknown or matching dimensions can be passed.
19011900
if( param->param.bydescdimensions > 0 ) then
@@ -1905,7 +1904,7 @@ private function hCheckOvlParam _
19051904
end if
19061905
end if
19071906

1908-
return FB_OVLPROC_FULLMATCH
1907+
return match
19091908

19101909
'' byref param?
19111910
case FB_PARAMMODE_BYREF

tests/overload/const.bas

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,136 @@ SUITE( fbc_tests.overload_.const_ )
5050
END_TEST
5151
END_TEST_GROUP
5252

53+
dim shared axlong(1 to ...) as long = {1, 2}
54+
dim shared axlongint(1 to ...) as longint = {1, 2}
55+
dim shared axinteger(1 to ...) as integer = {1, 2}
56+
dim shared axsingle(1 to ...) as single = {1.0f, 2.0f}
57+
dim shared axdouble(1 to ...) as double = {1.0, 2.0}
58+
59+
dim shared axconstlong(1 to ...) as const long = {1, 2}
60+
dim shared axconstlongint(1 to ...) as const longint = {1, 2}
61+
dim shared axconstinteger(1 to ...) as const integer = {1, 2}
62+
dim shared axconstsingle(1 to ...) as const single = {1.0f, 2.0f}
63+
dim shared axconstdouble(1 to ...) as const double = {1.0, 2.0}
64+
65+
dim shared axconstbyte(1 to ...) as const byte = {1, 2}
66+
67+
TEST_GROUP( array )
68+
69+
function f overload( x() as integer ) as string : function = "integer" : end function
70+
function f overload( x() as longint ) as string : function = "longint" : end function
71+
function f overload( x() as single ) as string : function = "single" : end function
72+
function f overload( x() as double ) as string : function = "double" : end function
73+
function f overload( x() as long ) as string : function = "long" : end function
74+
75+
TEST( non_const_array )
76+
CU_ASSERT( f( axlong() ) = "long" )
77+
CU_ASSERT( f( axlongint() ) = "longint" )
78+
CU_ASSERT( f( axinteger() ) = "integer" )
79+
CU_ASSERT( f( axsingle() ) = "single" )
80+
CU_ASSERT( f( axdouble() ) = "double" )
81+
END_TEST
82+
83+
function fc overload( x() as const integer ) as string : function = "integer" : end function
84+
function fc overload( x() as const longint ) as string : function = "longint" : end function
85+
function fc overload( x() as const single ) as string : function = "single" : end function
86+
function fc overload( x() as const double ) as string : function = "double" : end function
87+
function fc overload( x() as const long ) as string : function = "long" : end function
88+
89+
TEST( const_array )
90+
CU_ASSERT( fc( axlong() ) = "long" )
91+
CU_ASSERT( fc( axlongint() ) = "longint" )
92+
CU_ASSERT( fc( axinteger() ) = "integer" )
93+
CU_ASSERT( fc( axsingle() ) = "single" )
94+
CU_ASSERT( fc( axdouble() ) = "double" )
95+
CU_ASSERT( fc( axconstlong() ) = "long" )
96+
CU_ASSERT( fc( axconstlongint() ) = "longint" )
97+
CU_ASSERT( fc( axconstinteger() ) = "integer" )
98+
CU_ASSERT( fc( axconstsingle() ) = "single" )
99+
CU_ASSERT( fc( axconstdouble() ) = "double" )
100+
END_TEST
101+
102+
END_TEST_GROUP
103+
104+
TEST_GROUP( array )
105+
106+
'' base test using scalars
107+
function f0 overload( byref a as integer, byval x as integer ) as string
108+
function = "integer, integer"
109+
end function
110+
function f0 overload( byref a as integer, byval x as double ) as string
111+
function = "integer, double"
112+
end function
113+
114+
function f1 overload( byref a as const integer, byval x as integer ) as string
115+
function = "const integer, integer"
116+
end function
117+
function f1 overload( byref a as const integer, byval x as double ) as string
118+
function = "const integer, double"
119+
end function
120+
121+
'' array() tests
122+
function f2 overload( a() as integer, byval x as integer ) as string
123+
function = "() const integer, integer"
124+
end function
125+
function f2 overload( a() as integer, byval x as double ) as string
126+
function = "() const integer, double"
127+
end function
128+
129+
function f3 overload( a() as const integer, byval x as integer ) as string
130+
function = "() const integer, integer"
131+
end function
132+
function f3 overload( a() as const integer, byval x as double ) as string
133+
function = "() const integer, double"
134+
end function
135+
136+
function f4 overload( a() as integer, byval x as integer ) as string
137+
function = "() integer, integer"
138+
end function
139+
function f4 overload( a() as const integer, byval x as double ) as string
140+
function = "() const integer, double"
141+
end function
142+
143+
function f5 overload( a() as const integer, byval x as integer ) as string
144+
function = "() const integer, integer"
145+
end function
146+
function f5 overload( a() as integer, byval x as double ) as string
147+
function = "() integer, double"
148+
end function
149+
150+
TEST( array_number )
151+
152+
dim a(1 to ... ) as integer = {1, 2}
153+
dim ca( 1 to ...) as const integer = {1, 2}
154+
dim i as integer, ci as const integer = 1
155+
dim d as double
156+
157+
CU_ASSERT( f0( i, i ) = "integer, integer" )
158+
CU_ASSERT( f0( i, d ) = "integer, double" )
159+
160+
CU_ASSERT( f1( ci, i ) = "const integer, integer" )
161+
CU_ASSERT( f1( ci, d ) = "const integer, double" )
162+
163+
CU_ASSERT( f2( a(), i ) = "() const integer, integer" )
164+
CU_ASSERT( f2( a(), d ) = "() const integer, double" )
165+
166+
CU_ASSERT( f3( a(), i ) = "() const integer, integer" )
167+
CU_ASSERT( f3( ca(), i ) = "() const integer, integer" )
168+
CU_ASSERT( f3( a(), d ) = "() const integer, double" )
169+
CU_ASSERT( f3( ca(), d ) = "() const integer, double" )
170+
171+
CU_ASSERT( f4( a(), i ) = "() integer, integer" )
172+
CU_ASSERT( f4( ca(), i ) = "() const integer, double" )
173+
CU_ASSERT( f4( a(), d ) = "() const integer, double" )
174+
CU_ASSERT( f4( ca(), d ) = "() const integer, double" )
175+
176+
CU_ASSERT( f5( a(), i ) = "() const integer, integer" )
177+
CU_ASSERT( f5( ca(), i ) = "() const integer, integer" )
178+
CU_ASSERT( f5( a(), d ) = "() integer, double" )
179+
CU_ASSERT( f5( ca(), d ) = "() const integer, integer" )
180+
181+
END_TEST
182+
183+
END_TEST_GROUP
184+
53185
END_SUITE

0 commit comments

Comments
 (0)