Skip to content

Commit 79d17a3

Browse files
committed
fbc: fix compiler fault when accessing this.member
- where member is incorrectly inherited from a namespace (i.e. not derived from UDT) - report 'Element not defined' instead Example: Namespace M Sub ok() : Print "OK" : End Sub End Namespace Type UDT Declare Sub test() Dim As Integer __ End Type Sub UDT.test() Using M This.ok() '' <<< --- segfault in fbc-1.08 and earlier End Sub
1 parent 39f507d commit 79d17a3

File tree

4 files changed

+162
-27
lines changed

4 files changed

+162
-27
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Version 1.09.0
9797
- sf.net #892: Bug when default calling via a pointer to a 'Sub' defined with the only 'Any Ptr' - fbc now differentiates between function pointers that have different numbers and positions of optional parameters
9898
- sf.net #948: Overriding class members doesn't work inside methods of further-extended subclasses
9999
- sf.net #948: Duplicated class members inherit from the base class instead of incorrectly from the namespace
100+
- compiler fault when accessing this.member, where member is incorrectly inherited from a namespace (i.e. not derived from UDT) and report 'Element not defined' instead
100101

101102

102103
Version 1.08.0

src/compiler/symb.bas

Lines changed: 115 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ declare function hLookupImportList _
5555
byval index as uinteger _
5656
) as FBSYMCHAIN ptr
5757

58+
declare function hLookupImportListByParents _
59+
( _
60+
byval ns as FBSYMBOL ptr, _
61+
byval id as const zstring ptr, _
62+
byval index as uinteger _
63+
) as FBSYMCHAIN ptr
64+
5865

5966
''globals
6067
dim shared as SYMBCTX symb
@@ -247,15 +254,15 @@ function symbCanDuplicate _
247254
select case as const s->class
248255
'' adding a define, keyword, namespace, class or field?
249256
case FB_SYMBCLASS_DEFINE, FB_SYMBCLASS_KEYWORD, _
250-
FB_SYMBCLASS_NAMESPACE, FB_SYMBCLASS_CLASS, _
251-
FB_SYMBCLASS_FIELD
257+
FB_SYMBCLASS_NAMESPACE, FB_SYMBCLASS_CLASS, _
258+
FB_SYMBCLASS_FIELD
252259

253260
'' no dups allowed
254261
exit function
255262

256263
'' struct, enum or typedef?
257264
case FB_SYMBCLASS_STRUCT, FB_SYMBCLASS_ENUM, _
258-
FB_SYMBCLASS_TYPEDEF
265+
FB_SYMBCLASS_TYPEDEF
259266

260267
'' note: if it's a struct, we don't have to check if it's unique,
261268
'' because that will be only set after the symbol is added
@@ -265,9 +272,9 @@ function symbCanDuplicate _
265272
'' anything but a define or themselves is allowed (keywords
266273
'' (but quirk-keywords) are refused when parsing)
267274
case FB_SYMBCLASS_DEFINE, FB_SYMBCLASS_NAMESPACE, _
268-
FB_SYMBCLASS_STRUCT, FB_SYMBCLASS_ENUM, _
269-
FB_SYMBCLASS_TYPEDEF, FB_SYMBCLASS_CLASS, _
270-
FB_SYMBCLASS_FIELD
275+
FB_SYMBCLASS_STRUCT, FB_SYMBCLASS_ENUM, _
276+
FB_SYMBCLASS_TYPEDEF, FB_SYMBCLASS_CLASS, _
277+
FB_SYMBCLASS_FIELD
271278

272279
exit function
273280
end select
@@ -356,7 +363,7 @@ function symbCanDuplicate _
356363
select case as const head_sym->class
357364
'' allow labels or UDTs as dups
358365
case FB_SYMBCLASS_LABEL, FB_SYMBCLASS_ENUM, _
359-
FB_SYMBCLASS_TYPEDEF, FB_SYMBCLASS_FWDREF
366+
FB_SYMBCLASS_TYPEDEF, FB_SYMBCLASS_FWDREF
360367

361368
'' struct? only it's not unique
362369
case FB_SYMBCLASS_STRUCT
@@ -545,7 +552,7 @@ function symbNewSymbol _
545552
'' QB quirks
546553
if( (options and FB_SYMBOPT_UNSCOPE) <> 0 ) then
547554
if( (parser.currproc->stats and (FB_SYMBSTATS_MAINPROC or _
548-
FB_SYMBSTATS_MODLEVELPROC)) <> 0 ) then
555+
FB_SYMBSTATS_MODLEVELPROC)) <> 0 ) then
549556
s->scope = FB_MAINSCOPE
550557
else
551558
s->scope = parser.currproc->scope + 1
@@ -561,7 +568,7 @@ function symbNewSymbol _
561568
if( (options and FB_SYMBOPT_PRESERVECASE) = 0 ) then
562569
hUcase( id, s->id.name )
563570
else
564-
*s->id.name = *id
571+
*s->id.name = *id
565572
end if
566573
else
567574
s->id.name = NULL
@@ -772,8 +779,8 @@ sub symbHashListInsertNamespace _
772779
chain_->isimport = TRUE
773780

774781
dim as FBSYMCHAIN ptr head = hashLookupEx( @symb.imphashtb, _
775-
s->id.name, _
776-
s->hash.index )
782+
s->id.name, _
783+
s->hash.index )
777784
'' not defined yet? create a new hash node
778785
if( head = NULL ) then
779786
chain_->item = hashAdd( @symb.imphashtb, _
@@ -884,6 +891,10 @@ refactor the duplicated code in:
884891
- symbLookupNS()
885892
- symbLookupTypeNS()
886893
- symbLookup()
894+
- symbLookupAt()
895+
- hLookupImportList()
896+
- hLookupImportListByParents()
897+
- remove env.clopt.lookup108 and #pragma lookup108 before the next release
887898
'/
888899

889900
'':::::
@@ -1040,7 +1051,7 @@ function symbLookupNS _
10401051

10411052
'' We have both an ancestor (which was reached directly in the current
10421053
'' namespace, plus we also have imports.
1043-
'' !!!TODO!!! scoped+non-eplicit enums are going to give us trouble here
1054+
'' !!!TODO!!! scoped+non-explicit enums are going to give us trouble here
10441055
'' because the enum member is imported in to the current namespace
10451056
'' The choices are:
10461057
'' - always return the first_ancestor found
@@ -1137,7 +1148,6 @@ function symbLookupTypeNS _
11371148
loop while( hashtb <> NULL )
11381149
end scope
11391150

1140-
11411151
scope
11421152
'' Search symbols in the UDT's namespace
11431153
dim as FBSYMBOL ptr ns = symbGetCurrentNamespc( )
@@ -1177,11 +1187,16 @@ function symbLookupTypeNS _
11771187
sym = chain_->sym
11781188
while( sym )
11791189
dim as FBSYMBOL ptr parent = symbGetParent( sym )
1180-
if( symbGetType( parent ) = FB_DATATYPE_STRUCT ) then
1190+
select case symbGetType( parent )
1191+
case FB_DATATYPE_STRUCT ', FB_DATATYPE_CLASS
11811192
if( symbGetUDTBaseLevel( ns, parent ) > 0 ) then
11821193
return symbNewChainpool( chain_->sym )
11831194
end if
1184-
end if
1195+
case FB_DATATYPE_ENUM
1196+
'' !!!TODO!!! scoped+non-explicit enums?
1197+
'' They will probably need special treatment
1198+
'' or we need to confirm they don't
1199+
end select
11851200
sym = sym->hash.next
11861201
wend
11871202

@@ -1301,11 +1316,15 @@ private function hLookupImportList _
13011316
'' for each namespace imported by this ns..
13021317
dim as FBSYMBOL ptr imp_ = symbGetCompImportHead( ns )
13031318
do while( imp_ <> NULL )
1304-
dim as FBSYMBOL ptr sym = hashLookupEx( _
1305-
@symbGetCompHashTb( _
1319+
dim as FBSYMBOL ptr sym = _
1320+
hashLookupEx _
1321+
( _
1322+
@symbGetCompHashTb( _
13061323
symbGetImportNamespc( imp_ ) ).tb, _
1307-
id, _
1308-
index )
1324+
id, _
1325+
index _
1326+
)
1327+
13091328
if( sym <> NULL ) then
13101329
dim as FBSYMCHAIN ptr chain_ = chainpoolNext()
13111330

@@ -1333,6 +1352,69 @@ private function hLookupImportList _
13331352

13341353
end function
13351354

1355+
'':::::
1356+
private function hLookupImportListByParents _
1357+
( _
1358+
byval ns as FBSYMBOL ptr, _
1359+
byval id as const zstring ptr, _
1360+
byval index as uinteger _
1361+
) as FBSYMCHAIN ptr
1362+
1363+
dim as FBSYMCHAIN ptr head = NULL, tail = NULL
1364+
1365+
'' for each namespace imported by this ns..
1366+
dim as FBSYMBOL ptr imp_ = symbGetCompImportHead( ns )
1367+
do while( imp_ <> NULL )
1368+
dim as FBSYMBOL ptr sym = _
1369+
hashLookupEx _
1370+
( _
1371+
@symbGetCompHashTb( _
1372+
symbGetImportNamespc( imp_ ) ).tb, _
1373+
id, _
1374+
index _
1375+
)
1376+
1377+
if( sym <> NULL ) then
1378+
dim as FBSYMCHAIN ptr chain_ = chainpoolNext()
1379+
dim add as integer = FALSE
1380+
1381+
dim as FBSYMBOL ptr parent = symbGetParent( sym )
1382+
select case symbGetType( parent )
1383+
case FB_DATATYPE_STRUCT ', FB_DATATYPE_CLASS
1384+
if( symbGetUDTBaseLevel( ns, parent ) > 0 ) then
1385+
add = true
1386+
end if
1387+
case FB_DATATYPE_ENUM
1388+
add = true
1389+
end select
1390+
1391+
if( add = TRUE ) then
1392+
1393+
chain_->sym = sym
1394+
chain_->next = NULL
1395+
chain_->isimport = TRUE
1396+
1397+
if( head = NULL ) then
1398+
head = chain_
1399+
else
1400+
tail->next = chain_
1401+
'' it's ambiguous, instead of returning just the current head
1402+
'' which would indicate that access is ambiguous, keep going
1403+
'' and return all of the matches so we can show a better error
1404+
'' message
1405+
end if
1406+
1407+
tail = chain_
1408+
end if
1409+
end if
1410+
1411+
imp_ = symbGetImportNext( imp_ )
1412+
loop
1413+
1414+
return head
1415+
1416+
end function
1417+
13361418
'':::::
13371419
function symbLookupAt _
13381420
( _
@@ -1394,12 +1476,18 @@ function symbLookupAt _
13941476
'' special cases: the global ns
13951477
if( ns = @symbGetGlobalNamespc( ) ) then
13961478
return hLookupImportHash( ns, id, index )
1479+
end if
13971480

1398-
'' do a per-hash slow search..
1399-
else
1400-
return hLookupImportList( ns, id, index )
1481+
if( env.clopt.lookup108 = FALSE ) then
1482+
'' Are we in a type's namespace? Only search for inherited members
1483+
select case symbGetClass( ns )
1484+
case FB_SYMBCLASS_STRUCT, FB_SYMBCLASS_CLASS
1485+
return hLookupImportListByParents( ns, id, index )
1486+
end select
14011487
end if
14021488

1489+
return hLookupImportList( ns, id, index )
1490+
14031491
end function
14041492

14051493
'':::::
@@ -2724,8 +2812,8 @@ function typeDumpToStr _
27242812
else
27252813
select case( typeGetDtOnly( dtype ) )
27262814
case FB_DATATYPE_STRUCT, FB_DATATYPE_ENUM, _
2727-
FB_DATATYPE_NAMESPC, _
2728-
FB_DATATYPE_FUNCTION, FB_DATATYPE_FWDREF
2815+
FB_DATATYPE_NAMESPC, _
2816+
FB_DATATYPE_FUNCTION, FB_DATATYPE_FWDREF
27292817
ok = FALSE
27302818
case else
27312819
ok = TRUE
@@ -2737,7 +2825,7 @@ function typeDumpToStr _
27372825
dump += ", "
27382826
if( subtype ) then
27392827
if( (subtype->class >= FB_SYMBCLASS_VAR) and _
2740-
(subtype->class < FB_SYMBCLASS_NSIMPORT) ) then
2828+
(subtype->class < FB_SYMBCLASS_NSIMPORT) ) then
27412829
dump += *classnames(subtype->class)
27422830
else
27432831
dump += str( subtype->class )
@@ -3113,7 +3201,7 @@ sub symbDumpLookup( byval id as zstring ptr )
31133201
id = @sname
31143202

31153203
print "symbol: " & *id
3116-
3204+
31173205
if( symbGetCurrentNamespc( ) <> NULL ) then
31183206
print "namespace: " & symbDumpToStr( symbGetCurrentNamespc( ) )
31193207
else
@@ -3134,7 +3222,7 @@ sub symbDumpLookup( byval id as zstring ptr )
31343222

31353223
dim as FBSYMCHAIN ptr imp_chain = hashLookupEx( @symb.imphashtb, id, index )
31363224
symbDumpChain( imp_chain )
3137-
3225+
31383226
end sub
31393227
#endif '' __FB_DEBUG__
31403228

tests/structs/inherit-type-6.bas

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
' TEST_MODE : COMPILE_ONLY_FAIL
2+
3+
dim shared as zstring * 32 duplicate = " ..duplicate"
4+
5+
namespace m
6+
dim as zstring *32 duplicate = " m.duplicate"
7+
end namespace
8+
9+
type udt extends object
10+
declare sub test()
11+
end type
12+
13+
sub udt.test()
14+
using m
15+
print this.duplicate '' expected: element not defined
16+
end sub
17+
18+
print "from type:"
19+
dim as udt u
20+
u.test()
21+
print

tests/structs/inherit-type-7.bas

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
' TEST_MODE : COMPILE_ONLY_FAIL
2+
3+
sub duplicate()
4+
print " ..duplicate"
5+
end sub
6+
7+
namespace m
8+
sub duplicate()
9+
print " m.duplicate"
10+
end sub
11+
end namespace
12+
13+
type udt extends object
14+
declare sub test()
15+
end type
16+
17+
sub udt.test()
18+
using m
19+
this.duplicate() '' expected: element not defined
20+
end sub
21+
22+
print "from type:"
23+
dim as udt u
24+
u.test()
25+
print

0 commit comments

Comments
 (0)