Skip to content

Commit b240a65

Browse files
authored
Merge pull request #112 from jayrm/rtl-const
fix internal declaration of lbound() & ubound() rtl to accept const arrays - rtl-const: lbound() & ubound() rtl functions should accept const arrays - internal lbound() and ubound() run-time functions were being declared expecting non-const bydesc array() as any. - added regression test - reference: https://www.freebasic.net/forum/viewtopic.php?p=254260#p254260 - mangling: mangle top-level const in to internal array descriptor structs to avoid C backend name conflicts where types differ only by const - suppress const warnings for internal array indexing - Fix #823: Function overload resolution for [const] array() and passing non-const array argument to const array parameter
2 parents b99bd06 + 360e748 commit b240a65

File tree

17 files changed

+434
-43
lines changed

17 files changed

+434
-43
lines changed

changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ Version 1.06.0
8181
- #883: when mapping 32 & 64 bit functions for PALETTE [GET] USING, check the data type pointed to and choose one of LONG PTR, LONGINT PTR, INTEGER PTR
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
84+
- 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
8486

8587

8688
Version 1.05.0

src/compiler/parser-expr-variable.bas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private function hFieldAccess _
179179
'' Dynamic array field; access the descriptor field (same offset)
180180
desc = symbGetArrayDescriptor( fld )
181181
varexpr = astNewBOP( AST_OP_ADD, varexpr, offsetexpr )
182-
varexpr = astNewCONV( typeAddrOf( symbGetFullType( desc ) ), symbGetSubtype( desc ), varexpr, AST_CONVOPT_DONTCHKPTR )
182+
varexpr = astNewCONV( typeAddrOf( symbGetFullType( desc ) ), symbGetSubtype( desc ), varexpr, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )
183183

184184
tree = NULL
185185
if( astHasSideFx( varexpr ) ) then
@@ -190,7 +190,7 @@ private function hFieldAccess _
190190

191191
'' *cptr( dtype ptr, var->descriptor.data + index )
192192
varexpr = astNewBOP( AST_OP_ADD, varexpr, astNewCONSTi( symb.fbarray_data ) )
193-
varexpr = astNewCONV( typeMultAddrOf( dtype, 2 ), subtype, varexpr, AST_CONVOPT_DONTCHKPTR )
193+
varexpr = astNewCONV( typeMultAddrOf( dtype, 2 ), subtype, varexpr, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )
194194
varexpr = astNewDEREF( varexpr )
195195
varexpr = astNewBOP( AST_OP_ADD, varexpr, indexexpr )
196196
varexpr = astNewDEREF( varexpr )

src/compiler/rtl-array.bas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@
213213
NULL, FB_RTL_OPT_NONE, _
214214
2, _
215215
{ _
216-
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ), _
216+
( typeSetIsConst( FB_DATATYPE_VOID ), FB_PARAMMODE_BYDESC, FALSE ), _
217217
( typeSetIsConst( FB_DATATYPE_INTEGER ), FB_PARAMMODE_BYVAL, FALSE ) _
218218
} _
219219
), _
@@ -224,7 +224,7 @@
224224
NULL, FB_RTL_OPT_NONE, _
225225
2, _
226226
{ _
227-
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ), _
227+
( typeSetIsConst( FB_DATATYPE_VOID ), FB_PARAMMODE_BYDESC, FALSE ), _
228228
( typeSetIsConst( FB_DATATYPE_INTEGER ), FB_PARAMMODE_BYVAL, FALSE ) _
229229
} _
230230
), _

src/compiler/symb-mangling.bas

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ private sub hMangleUdtId( byref mangled as string, byval sym as FBSYMBOL ptr )
183183
mangled += "I" '' begin of template argument list
184184

185185
symbGetDescTypeArrayDtype( sym, arraydtype, arraysubtype )
186-
symbMangleType( mangled, arraydtype, arraysubtype )
186+
symbMangleType( mangled, arraydtype, arraysubtype, FB_MANGLEOPT_KEEPTOPCONST )
187187

188188
mangled += "E" '' end of template argument list
189189
end if
@@ -429,7 +429,8 @@ sub symbMangleType _
429429
( _
430430
byref mangled as string, _
431431
byval dtype as integer, _
432-
byval subtype as FBSYMBOL ptr _
432+
byval subtype as FBSYMBOL ptr, _
433+
byval options as FB_MANGLEOPT = FB_MANGLEOPT_NONE _
433434
)
434435

435436
dim as FBSYMBOL ptr ns = any
@@ -453,36 +454,17 @@ sub symbMangleType _
453454

454455
'' reference?
455456
if( typeIsRef( dtype ) ) then
456-
'' const?
457-
if( typeIsConst( dtype ) ) then
458-
mangled += "RK"
459-
else
460-
mangled + = "R"
461-
end if
462-
463-
symbMangleType( mangled, typeUnsetIsRef( dtype ), subtype )
464-
465-
hAbbrevAdd( dtype, subtype )
466-
exit sub
467-
end if
468-
469-
'' pointer? (must be checked/emitted before CONST)
470-
if( typeIsPtr( dtype ) ) then
471-
'' const?
472-
if( typeIsConstAt( dtype, 1 ) ) then
473-
mangled += "PK"
474-
else
475-
mangled += "P"
476-
end if
457+
mangled += "R"
477458

478-
symbMangleType( mangled, typeDeref( dtype ), subtype )
459+
symbMangleType( mangled, typeUnsetIsRef( dtype ), subtype, FB_MANGLEOPT_KEEPTOPCONST )
479460

480461
hAbbrevAdd( dtype, subtype )
481462
exit sub
482463
end if
483464

484465
'' const?
485-
if( typeGetConstMask( dtype ) ) then
466+
if( typeIsConst( dtype ) ) then
467+
486468
'' The type has some CONST bits. For C++ mangling we remove the
487469
'' toplevel one and recursively mangle the rest of the type.
488470
''
@@ -491,12 +473,27 @@ sub symbMangleType _
491473
'' difference. It's not allowed to have overloads that differ
492474
'' only in BYVAL CONSTness. The CONST only matters if it's a
493475
'' pointer or BYREF type.
476+
477+
if( (options and FB_MANGLEOPT_KEEPTOPCONST) <> 0 ) then
478+
mangled += "K"
479+
end if
480+
494481
symbMangleType( mangled, typeUnsetIsConst( dtype ), subtype )
495482

496483
hAbbrevAdd( dtype, subtype )
497484
exit sub
498485
end if
499486

487+
'' pointer?
488+
if( typeIsPtr( dtype ) ) then
489+
mangled += "P"
490+
491+
symbMangleType( mangled, typeDeref( dtype ), subtype, FB_MANGLEOPT_KEEPTOPCONST )
492+
493+
hAbbrevAdd( dtype, subtype )
494+
exit sub
495+
end if
496+
500497
''
501498
'' Plain type without reference/pointer/const bits
502499
''
@@ -573,7 +570,7 @@ sub symbMangleParam( byref mangled as string, byval param as FBSYMBOL ptr )
573570
'' Mangling array params as 'FBARRAY[1-8]<dtype>&' because
574571
'' that's what they really are from C++'s point of view.
575572
assert( symbIsDescriptor( param->param.bydescrealsubtype ) )
576-
symbMangleType( mangled, typeSetIsRef( FB_DATATYPE_STRUCT ), param->param.bydescrealsubtype )
573+
symbMangleType( mangled, typeSetIsRef( FB_DATATYPE_STRUCT ), param->param.bydescrealsubtype, FB_MANGLEOPT_KEEPTOPCONST )
577574

578575
case FB_PARAMMODE_VARARG
579576
mangled += "z"

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

src/compiler/symb-var.bas

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ sub symbGetDescTypeArrayDtype _
7777
fld = symbUdtGetFirstField( desctype )
7878
assert( typeIsPtr( symbGetType( fld ) ) )
7979

80-
arraydtype = typeDeref( symbGetType( fld ) )
80+
arraydtype = typeDeref( symbGetFullType( fld ) )
8181
arraysubtype = fld->subtype
8282

8383
end sub
@@ -160,10 +160,11 @@ function symbAddArrayDescriptorType _
160160
'' Some unique internal id that allows this descriptor type to be looked
161161
'' up later when we need one with the same dimensions & array dtype
162162
'' again. '$' prefix ensures that there are no collisions with user's
163-
'' ids.
163+
'' ids. Always keep the top-level const for array datatypes to avoid
164+
'' conflicts between types differing only by const.
164165
id = "$" + aliasid
165166
id += "<"
166-
symbMangleType( id, arraydtype, arraysubtype )
167+
symbMangleType( id, arraydtype, arraysubtype, FB_MANGLEOPT_KEEPTOPCONST )
167168
symbMangleResetAbbrev( )
168169
id += ">"
169170

src/compiler/symb.bi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ enum FB_MANGLING
249249
FB_MANGLING_PASCAL
250250
end enum
251251

252+
''
253+
enum FB_MANGLEOPT
254+
FB_MANGLEOPT_NONE = 0 '' no special options
255+
FB_MANGLEOPT_KEEPTOPCONST = 1 '' keep the top-level const when mangling
256+
end enum
257+
252258
type FBSYMBOL_ as FBSYMBOL
253259

254260
#ifndef ASTNODE_
@@ -1747,7 +1753,8 @@ declare sub symbMangleType _
17471753
( _
17481754
byref mangled as string, _
17491755
byval dtype as integer, _
1750-
byval subtype as FBSYMBOL ptr _
1756+
byval subtype as FBSYMBOL ptr, _
1757+
byval options as FB_MANGLEOPT = FB_MANGLEOPT_NONE _
17511758
)
17521759
declare sub symbMangleParam( byref mangled as string, byval param as FBSYMBOL ptr )
17531760

tests/cpp/cpp-mangle.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,98 @@ namespace cpp_mangle
146146
return a;
147147
}
148148

149+
/* byval const, pointer, reference */
150+
151+
double cpp_byval_const_double( const double a )
152+
{
153+
return a;
154+
}
155+
156+
double cpp_byval_double_ptr( double* a )
157+
{
158+
return *a;
159+
}
160+
161+
double cpp_byval_const_double_ptr( double const* a )
162+
{
163+
return *a;
164+
}
165+
166+
double cpp_byval_double_const_ptr( double* const a )
167+
{
168+
return *a;
169+
}
170+
171+
double cpp_byval_const_double_const_ptr( double const* const a )
172+
{
173+
return *a;
174+
}
175+
176+
double cpp_byval_double_ptr_ptr( double** a )
177+
{
178+
return **a;
179+
}
180+
181+
double cpp_byval_const_double_ptr_ptr( double const** a )
182+
{
183+
return **a;
184+
}
185+
186+
double cpp_byval_double_const_ptr_ptr( double* const* a )
187+
{
188+
return **a;
189+
}
190+
191+
double cpp_byval_double_ptr_const_ptr( double** const a )
192+
{
193+
return **a;
194+
}
195+
196+
/* byval const, pointer, reference */
197+
198+
double cpp_byref_const_double( double const& a )
199+
{
200+
return a;
201+
}
202+
203+
double cpp_byref_double_ptr( double*& a )
204+
{
205+
return *a;
206+
}
207+
208+
double cpp_byref_const_double_ptr( double const*& a )
209+
{
210+
return *a;
211+
}
212+
213+
double cpp_byref_double_const_ptr( double* const& a )
214+
{
215+
return *a;
216+
}
217+
218+
double cpp_byref_const_double_const_ptr( double const* const& a )
219+
{
220+
return *a;
221+
}
222+
223+
double cpp_byref_double_ptr_ptr( double**& a )
224+
{
225+
return **a;
226+
}
227+
228+
double cpp_byref_const_double_ptr_ptr( double const**& a )
229+
{
230+
return **a;
231+
}
232+
233+
double cpp_byref_double_const_ptr_ptr( double* const*& a )
234+
{
235+
return **a;
236+
}
237+
238+
double cpp_byref_double_ptr_const_ptr( double** const& a )
239+
{
240+
return **a;
241+
}
242+
149243
}

tests/cpp/fbc-mangle.bas

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ namespace cpp_mangle
5959
declare function cpp_byref_ulonglongint( byref a as unsigned longint ) as unsigned longint
6060
declare function cpp_byref_slonglongint( byref a as longint ) as longint
6161

62+
declare function cpp_byval_const_double( byval a as const double ) as double
63+
declare function cpp_byval_double_ptr( byval a as double ptr ) as double
64+
declare function cpp_byval_const_double_ptr( byval a as const double ptr ) as double
65+
declare function cpp_byval_double_const_ptr( byval a as double const ptr ) as double
66+
declare function cpp_byval_const_double_const_ptr( byval a as const double const ptr ) as double
67+
declare function cpp_byval_double_ptr_ptr( byval a as double ptr ptr ) as double
68+
declare function cpp_byval_const_double_ptr_ptr( byval a as const double ptr ptr ) as double
69+
declare function cpp_byval_double_const_ptr_ptr( byval a as double const ptr ptr ) as double
70+
declare function cpp_byval_double_ptr_const_ptr( byval a as double ptr const ptr ) as double
71+
72+
declare function cpp_byref_const_double( byref a as const double ) as double
73+
declare function cpp_byref_double_ptr( byref a as double ptr ) as double
74+
declare function cpp_byref_const_double_ptr( byref a as const double ptr ) as double
75+
declare function cpp_byref_double_const_ptr( byref a as double const ptr ) as double
76+
declare function cpp_byref_const_double_const_ptr( byref a as const double const ptr ) as double
77+
declare function cpp_byref_double_ptr_ptr( byref a as double ptr ptr ) as double
78+
declare function cpp_byref_const_double_ptr_ptr( byref a as const double ptr ptr ) as double
79+
declare function cpp_byref_double_const_ptr_ptr( byref a as double const ptr ptr ) as double
80+
declare function cpp_byref_double_ptr_const_ptr( byref a as double ptr const ptr ) as double
81+
6282
end namespace
6383

6484
end extern
@@ -209,3 +229,37 @@ scope
209229
ASSERT( cpp_byref_slonglongint(sll) = &h7fffffffffffffff )
210230

211231
end scope
232+
233+
scope
234+
'' [const] pointers and references
235+
236+
dim d as double = 1
237+
dim dp as double ptr = @d
238+
dim dpp as double ptr ptr = @dp
239+
240+
ASSERT( cpp_byval_double( d ) = d )
241+
ASSERT( cpp_byval_const_double( d ) = d )
242+
ASSERT( cpp_byval_double_ptr( dp ) = d )
243+
ASSERT( cpp_byval_const_double_ptr( dp ) = d )
244+
ASSERT( cpp_byval_double_const_ptr( dp ) = d )
245+
ASSERT( cpp_byval_const_double_const_ptr( dp ) = d )
246+
247+
ASSERT( cpp_byval_double_ptr_ptr( dpp ) = d )
248+
ASSERT( cpp_byval_const_double_ptr_ptr( dpp ) = d )
249+
ASSERT( cpp_byval_double_const_ptr_ptr( dpp ) = d )
250+
ASSERT( cpp_byval_double_ptr_const_ptr( dpp ) = d )
251+
252+
ASSERT( cpp_byref_double( d ) = d )
253+
ASSERT( cpp_byref_const_double( d ) = d )
254+
ASSERT( cpp_byref_double_ptr( dp ) = d )
255+
ASSERT( cpp_byref_const_double_ptr( dp ) = d )
256+
ASSERT( cpp_byref_double_const_ptr( dp ) = d )
257+
ASSERT( cpp_byref_const_double_const_ptr( dp ) = d )
258+
259+
ASSERT( cpp_byref_double_ptr_ptr( dpp ) = d )
260+
ASSERT( cpp_byref_const_double_ptr_ptr( dpp ) = d )
261+
ASSERT( cpp_byref_double_const_ptr_ptr( dpp ) = d )
262+
ASSERT( cpp_byref_double_ptr_const_ptr( dpp ) = d )
263+
264+
265+
end scope

0 commit comments

Comments
 (0)