Skip to content

Commit 84f11d6

Browse files
committed
fbc: new[count] returns null pointer if allocation failed
- if new[count] expression fails, do not attempt to call constructors and return null pointer instead - in -gen gcc, allow memclear on const 0 bytes - internal: wrap branching (IF's) for new[N] expressions in LOOP nodes to correctly clone labels in the expression
1 parent 0c0bece commit 84f11d6

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

src/compiler/ast-helper.bas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,8 @@ end function
288288
''
289289
'' CNT = INIVALUE
290290
'' WHILE( CNT )
291-
'' CNT -= 1
292291
'' <user code>
292+
'' CNT -= 1
293293
'' WEND
294294

295295
function astBuildWhileCounterBegin _

src/compiler/ast-node-mem.bas

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ function astNewMEM _
3232
end if
3333

3434
'' when clearing/moving more than IR_MEMBLOCK_MAXLEN bytes, take
35-
'' the adress-of and let emit() do the rest
36-
if( lgt > blkmaxlen ) then
35+
'' the adress-of and let emit() do the rest, or if blkmaxlen = 0,
36+
'' then emit() always handles it, even when lgt=0
37+
if( (lgt > blkmaxlen) or (blkmaxlen = 0) ) then
3738
l = astNewADDROF( l )
3839

3940
if( op = AST_OP_MEMMOVE ) then
@@ -83,12 +84,16 @@ private function hCallCtorList _
8384
tree = astNewLINK( tree, astBuildVarInc( iter, 1 ) )
8485

8586
'' wend
86-
tree = astBuildWhileCounterEnd( tree, cnt, label, exitlabel )
87+
tree = astBuildWhileCounterEnd( tree, cnt, label, exitlabel, FALSE )
8788

8889
'' Wrap into LOOP node so astCloneTree() can clone the label and update
8990
'' the loop code, because it's part of the new[] expression, and not
9091
'' a standalone statement.
91-
function = astNewLOOP( label, tree )
92+
tree = astNewLOOP( label, tree )
93+
94+
tree = astNewLOOP( exitlabel, tree )
95+
96+
function = tree
9297
end function
9398

9499
private function hElements _
@@ -131,6 +136,7 @@ function astBuildNewOp _
131136

132137
dim as ASTNODE ptr lenexpr = any, tree = any
133138
dim as integer save_elmts = any, init = any, elementstreecount = any
139+
dim as FBSYMBOL ptr exitlabel = any
134140

135141
init = INIT_NONE
136142
tree = NULL
@@ -212,6 +218,13 @@ function astBuildNewOp _
212218
'' tempptr = new( len )
213219
tree = astNewLINK( tree, astBuildVarAssign( tmp, newexpr, AST_OPOPT_ISINI ) )
214220

221+
'' if( tempptr <> NULL ) then
222+
exitlabel = symbAddLabel( NULL )
223+
224+
'' handle like IIF, we don't want dtors called if tempptr was never allocated
225+
tree = astNewLINK( tree, _
226+
astBuildBranch( astNewBOP( AST_OP_NE, astNewVAR( tmp ), astNewCONSTi( 0 ) ), exitlabel, FALSE, TRUE ) )
227+
215228
'' save elements count?
216229
if( save_elmts ) then
217230
'' *tempptr = elements
@@ -258,7 +271,17 @@ function astBuildNewOp _
258271

259272
end select
260273

261-
function = astNewLINK( tree, initexpr )
274+
'' *tempptr = initializers
275+
tree = astNewLINK( tree, initexpr )
276+
277+
'' end if
278+
tree = astNewLINK( tree, astNewLABEL( exitlabel, FALSE ) )
279+
280+
'' because this is an expression, exitlabel must be cloned with a new label
281+
'' instead of just copied. astNewLOOP() allows this (but naming could be better).
282+
tree = astNewLOOP( exitlabel, tree )
283+
284+
function = tree
262285
end function
263286

264287
private function hCallDtorList( byval ptrexpr as ASTNODE ptr ) as ASTNODE ptr

0 commit comments

Comments
 (0)