Skip to content

Commit e4ddfba

Browse files
committed
Allow byref initializers of byref vars
1 parent 3dc8d7c commit e4ddfba

File tree

3 files changed

+340
-1
lines changed

3 files changed

+340
-1
lines changed

src/compiler/parser-decl-var.bas

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,49 @@ private function hBuildFakeByrefInitExpr( byval dtype as integer, byval subtype
854854
function = astNewDEREF( expr )
855855
end function
856856

857+
'' resolve reference to a reference
858+
private function hResolveRefToRefInitializer( byval dtype as integer, byval expr as ASTNODE ptr ) as ASTNODE ptr
859+
860+
dim tree as ASTNODE ptr = any
861+
dim n as ASTNODE ptr = any
862+
863+
'' if initializer expr is a REF VAR, then crawl the INITREE of the var
864+
'' it references for a VAR initializer. If none found just return the
865+
'' original expr.
866+
867+
if( expr andalso astIsDEREF( expr ) ) then
868+
if( expr->l andalso astIsVAR( expr->l ) ) then
869+
if( expr->l->sym andalso symbIsRef( expr->l->sym ) ) then
870+
tree = expr->l->sym->var_.initree
871+
if( tree andalso astIsTYPEINI( tree ) ) then
872+
if( tree->l andalso tree->l->class = AST_NODECLASS_TYPEINI_ASSIGN ) then
873+
n = tree->l->l
874+
if( n ) then
875+
876+
select case astGetClass( n )
877+
case AST_NODECLASS_OFFSET
878+
n = n->l
879+
if( n andalso astIsVAR( n ) ) then
880+
'' compatible types?
881+
if( astGetFullType( n ) = dtype ) then
882+
astDelTree( expr )
883+
expr = astCloneTree( n )
884+
end if
885+
end if
886+
end select
887+
888+
end if
889+
end if
890+
end if
891+
892+
end if
893+
end if
894+
end if
895+
896+
function = expr
897+
898+
end function
899+
857900
private function hCheckAndBuildByrefInitializer( byval sym as FBSYMBOL ptr, byref expr as ASTNODE ptr ) as ASTNODE ptr
858901
'' Check data types, CONSTness, etc.
859902
var ok = astCheckByrefAssign( sym->typ, sym->subtype, expr )
@@ -866,6 +909,8 @@ private function hCheckAndBuildByrefInitializer( byval sym as FBSYMBOL ptr, byre
866909
errReport( FB_ERRMSG_INVALIDDATATYPES )
867910
astDelTree( expr )
868911
expr = hBuildFakeByrefInitExpr( sym->typ, sym->subtype )
912+
else
913+
expr = hResolveRefToRefInitializer( sym->typ, expr )
869914
end if
870915

871916
'' Build the TYPEINI for initializing the reference/pointer
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# include "fbcunit.bi"
2+
3+
4+
'' INTEGER: shared refer to same shared
5+
6+
dim shared as integer I01
7+
dim shared byref as integer I02 = I01
8+
dim shared byref as integer I03 = I01
9+
dim shared byref as integer I04 = I01
10+
11+
'' INTEGER: shared refer to shared chain
12+
13+
dim shared as integer I11
14+
dim shared byref as integer I12 = I11
15+
dim shared byref as integer I13 = I12
16+
dim shared byref as integer I14 = I13
17+
18+
'' INTEGER: static shared refer to same static shared
19+
20+
static shared as integer I21
21+
static shared byref as integer I22 = I21
22+
static shared byref as integer I23 = I21
23+
static shared byref as integer I24 = I21
24+
25+
'' INTEGER: static shared refer to static shared chain
26+
27+
static shared as integer I31
28+
static shared byref as integer I32 = I31
29+
static shared byref as integer I33 = I32
30+
static shared byref as integer I34 = I33
31+
32+
33+
'' INTEGER: shared & static shared mixed
34+
35+
dim shared as integer I41
36+
static shared byref as integer I42 = I41
37+
dim shared byref as integer I43 = I41
38+
static shared byref as integer I44 = I41
39+
40+
dim shared as integer I51
41+
static shared byref as integer I52 = I51
42+
dim shared byref as integer I53 = I52
43+
static shared byref as integer I54 = I53
44+
45+
46+
'' INTEGER: static shared & shared mixed
47+
48+
static shared as integer I61
49+
dim shared byref as integer I62 = I61
50+
static shared byref as integer I63 = I61
51+
dim shared byref as integer I64 = I61
52+
53+
static shared as integer I71
54+
dim shared byref as integer I72 = I71
55+
static shared byref as integer I73 = I72
56+
dim shared byref as integer I74 = I73
57+
58+
59+
''
60+
type T
61+
__ as integer
62+
end type
63+
64+
'' Simple UDT: shared refer to same shared
65+
66+
dim shared as T T01
67+
dim shared byref as T T02 = T01
68+
dim shared byref as T T03 = T01
69+
dim shared byref as T T04 = T01
70+
71+
'' Simple UDT: shared refer to shared chain
72+
73+
dim shared as T T11
74+
dim shared byref as T T12 = T11
75+
dim shared byref as T T13 = T12
76+
dim shared byref as T T14 = T13
77+
78+
'' Simple UDT: static shared refer to same static shared
79+
80+
static shared as T T21
81+
static shared byref as T T22 = T21
82+
static shared byref as T T23 = T21
83+
static shared byref as T T24 = T21
84+
85+
'' Simple UDT: static shared refer to static shared chain
86+
87+
static shared as T T31
88+
static shared byref as T T32 = T31
89+
static shared byref as T T33 = T32
90+
static shared byref as T T34 = T33
91+
92+
93+
'' Simple UDT: shared & static shared mixed
94+
95+
dim shared as T T41
96+
static shared byref as T T42 = T41
97+
dim shared byref as T T43 = T41
98+
static shared byref as T T44 = T41
99+
100+
dim shared as T T51
101+
static shared byref as T T52 = T51
102+
dim shared byref as T T53 = T52
103+
static shared byref as T T54 = T53
104+
105+
'' Simple UDT: static shared & shared mixed
106+
107+
static shared as T T61
108+
dim shared byref as T T62 = T61
109+
static shared byref as T T63 = T61
110+
dim shared byref as T T64 = T61
111+
112+
dim shared as T T71
113+
static shared byref as T T72 = T71
114+
dim shared byref as T T73 = T72
115+
static shared byref as T T74 = T73
116+
117+
118+
'' UDT with static byref fields
119+
120+
type T1
121+
dim as integer F
122+
end type
123+
124+
type T2
125+
dim as integer F
126+
static byref as T1 R1
127+
static byref as T1 R2
128+
static byref as T1 R3
129+
static byref as T1 R4
130+
end type
131+
132+
dim shared T2_Initializer as T1
133+
134+
dim byref as T1 T2.R1 = T2_Initializer
135+
dim byref as T1 T2.R2 = T2.R1
136+
dim byref as T1 T2.R3 = T2.R2
137+
dim byref as T1 T2.R4 = T2.R3
138+
139+
dim shared byref as T1 RT1 = T2.R1
140+
dim shared byref as T1 RT2 = T2.R2
141+
dim shared byref as T1 RT3 = T2.R3
142+
dim shared byref as T1 RT4 = T2.R4
143+
144+
145+
SUITE( fbc_tests.dim_.byref_init_from_byref )
146+
147+
#macro CheckAddrs( A1, A2, A3, A4 )
148+
CU_ASSERT( @A1 <> 0 and @A1 = @A2 and @A1 = @A3 and @A1 = @A4 )
149+
#endmacro
150+
151+
'' -------- INTEGER ---------------
152+
153+
TEST( integer_shared )
154+
CheckAddrs( I01, I02, I03, I04 )
155+
CheckAddrs( I11, I12, I13, I14 )
156+
END_TEST
157+
158+
TEST( static_shared_integer )
159+
CheckAddrs( I21, I22, I23, I24 )
160+
CheckAddrs( I31, I32, I33, I34 )
161+
END_TEST
162+
163+
TEST( integer_shared_and_static_shared )
164+
CheckAddrs( I41, I42, I43, I44 )
165+
CheckAddrs( I51, I52, I53, I54 )
166+
END_TEST
167+
168+
TEST( integer_static_shared_and_shared )
169+
CheckAddrs( I61, I62, I63, I64 )
170+
CheckAddrs( I71, I72, I73, I74 )
171+
END_TEST
172+
173+
TEST( integer_local_same )
174+
dim as integer a
175+
dim byref as integer b = a
176+
dim byref as integer c = a
177+
dim byref as integer d = a
178+
CheckAddrs( a, b, c, d )
179+
END_TEST
180+
181+
TEST( integer_local_chain )
182+
dim as integer a
183+
dim byref as integer b = a
184+
dim byref as integer c = b
185+
dim byref as integer d = c
186+
CheckAddrs( a, b, c, d )
187+
END_TEST
188+
189+
TEST( integer_local_to_shared )
190+
static byref as integer b = I11
191+
dim byref as integer c = I14
192+
dim byref as integer d = c
193+
CheckAddrs( I11, b, c, d )
194+
END_TEST
195+
196+
TEST( integer_local_to_static_shared )
197+
static byref as integer b = I31
198+
dim byref as integer c = I34
199+
dim byref as integer d = c
200+
CheckAddrs( I31, b, c, d )
201+
END_TEST
202+
203+
TEST( integer_static_local_to_shared )
204+
static byref as integer b = I51
205+
static byref as integer c = I54
206+
dim byref as integer d = c
207+
CheckAddrs( I51, b, c, d )
208+
END_TEST
209+
210+
TEST( integer_static_local_to_static_shared )
211+
static byref as integer b = I71
212+
static byref as integer c = I74
213+
dim byref as integer d = c
214+
CheckAddrs( I71, b, c, d )
215+
END_TEST
216+
217+
'' -------- UDT -------------------
218+
219+
TEST( UDT_shared )
220+
CheckAddrs( T01, T02, T03, T04 )
221+
CheckAddrs( T11, T12, T13, T14 )
222+
END_TEST
223+
224+
TEST( UDT_static_shared )
225+
CheckAddrs( T21, T22, T23, T24 )
226+
CheckAddrs( T31, T32, T33, T34 )
227+
END_TEST
228+
229+
TEST( static_shared_and_static_shared )
230+
CheckAddrs( T41, T42, T43, T44 )
231+
CheckAddrs( T51, T52, T53, T54 )
232+
END_TEST
233+
234+
TEST( UDT_static_shared_and_shared )
235+
CheckAddrs( T61, T62, T63, T64 )
236+
CheckAddrs( T71, T72, T73, T74 )
237+
END_TEST
238+
239+
TEST( UDT_local_same )
240+
dim as T a
241+
dim byref as T b = a
242+
dim byref as T c = a
243+
dim byref as T d = a
244+
CheckAddrs( a, b, c, d )
245+
END_TEST
246+
247+
TEST( UDT_local_chain )
248+
dim as T a
249+
dim byref as T b = a
250+
dim byref as T c = b
251+
dim byref as T d = c
252+
CheckAddrs( a, b, c, d )
253+
END_TEST
254+
255+
TEST( UDT_local_to_shared )
256+
static byref as T b = T11
257+
dim byref as T c = T14
258+
dim byref as T d = c
259+
CheckAddrs( T11, b, c, d )
260+
END_TEST
261+
262+
TEST( UDT_local_to_static_shared )
263+
static byref as T b = T31
264+
dim byref as T c = T34
265+
dim byref as T d = c
266+
CheckAddrs( T31, b, c, d )
267+
END_TEST
268+
269+
TEST( UDT_static_local_to_shared )
270+
static byref as T b = T51
271+
static byref as T c = T54
272+
dim byref as T d = c
273+
CheckAddrs( T51, b, c, d )
274+
END_TEST
275+
276+
TEST( UDT_static_local_to_static_shared )
277+
static byref as T b = T51
278+
static byref as T c = T54
279+
dim byref as T d = c
280+
CheckAddrs( T51, b, c, d )
281+
END_TEST
282+
283+
'' -------- UDT2 -------------------
284+
285+
TEST( UDT2_static_members )
286+
CheckAddrs( T2.R1, T2.R2, T2.R3, T2.R4 )
287+
END_TEST
288+
289+
TEST( UDT2_shared )
290+
CheckAddrs( RT1, RT2, RT3, RT4 )
291+
END_TEST
292+
293+
294+
END_SUITE

tests/dim/byref-shared-from-shared-ref.bas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
' TEST_MODE : COMPILE_ONLY_FAIL
1+
' TEST_MODE : COMPILE_ONLY_OK
22

33
public dim shared a as integer = 5
44
public dim shared byref as integer b = a

0 commit comments

Comments
 (0)