mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-07 17:47:19 +01:00
* better fix for new/dispose bug with init/final data
This commit is contained in:
parent
7fb55bf4e4
commit
313e7a0053
@ -136,17 +136,27 @@ implementation
|
||||
var
|
||||
regstopush: tregisterset;
|
||||
pushed : tpushedsaved;
|
||||
lefttemp: treference;
|
||||
r : preference;
|
||||
oldleft: tnode;
|
||||
left_needs_initfinal: boolean;
|
||||
|
||||
procedure saveleft;
|
||||
begin
|
||||
tg.gettempofsizereference(exprasmlist,target_info.size_of_pointer,
|
||||
lefttemp);
|
||||
cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,lefttemp);
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
oldleft := nil;
|
||||
if tpointerdef(left.resulttype.def).pointertype.def.needs_inittable then
|
||||
{ we need to secondpass left twice in this case -> get a copy }
|
||||
oldleft := left.getcopy;
|
||||
secondpass(left);
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
left_needs_initfinal :=
|
||||
tpointerdef(left.resulttype.def).pointertype.def.needs_inittable;
|
||||
|
||||
regstopush := all_registers;
|
||||
remove_non_regvars_from_loc(left.location,regstopush);
|
||||
rg.saveusedregisters(exprasmlist,pushed,regstopush);
|
||||
@ -156,7 +166,7 @@ implementation
|
||||
case nodetype of
|
||||
simpledisposen:
|
||||
begin
|
||||
if assigned(oldleft) then
|
||||
if left_needs_initfinal then
|
||||
begin
|
||||
new(r);
|
||||
reset_reference(r^);
|
||||
@ -165,14 +175,18 @@ implementation
|
||||
dispose(r);
|
||||
{ push pointer adress }
|
||||
emit_push_loc(left.location);
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
{ save left and free its registers }
|
||||
saveleft;
|
||||
emitcall('FPC_FINALIZE');
|
||||
{ reload registers for left!! }
|
||||
secondpass(oldleft);
|
||||
oldleft.free;
|
||||
{ push left again as parameter for freemem }
|
||||
emit_push_mem(lefttemp);
|
||||
tg.ungetiftemp(exprasmlist,lefttemp);
|
||||
end
|
||||
else
|
||||
begin
|
||||
emit_push_loc(left.location);
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
end;
|
||||
emit_push_loc(left.location);
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
emitcall('FPC_FREEMEM');
|
||||
end;
|
||||
simplenewn:
|
||||
@ -180,21 +194,19 @@ implementation
|
||||
{ determines the size of the mem block }
|
||||
push_int(tpointerdef(left.resulttype.def).pointertype.def.size);
|
||||
emit_push_lea_loc(left.location,true);
|
||||
if not assigned(oldleft) then
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
{ save left and free its registers }
|
||||
if left_needs_initfinal then
|
||||
saveleft;
|
||||
emitcall('FPC_GETMEM');
|
||||
if assigned(oldleft) then
|
||||
if left_needs_initfinal then
|
||||
begin
|
||||
{ reload registers for left!! }
|
||||
secondpass(oldleft);
|
||||
oldleft.free;
|
||||
new(r);
|
||||
reset_reference(r^);
|
||||
r^.symbol:=tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti);
|
||||
emitpushreferenceaddr(r^);
|
||||
dispose(r);
|
||||
emit_push_loc(left.location);
|
||||
rg.del_location(exprasmlist,left.location);
|
||||
emit_push_mem(lefttemp);
|
||||
tg.ungetiftemp(exprasmlist,lefttemp);
|
||||
emitcall('FPC_INITIALIZE');
|
||||
end;
|
||||
end;
|
||||
@ -722,7 +734,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.21 2002-03-31 20:26:39 jonas
|
||||
Revision 1.22 2002-04-01 09:44:04 jonas
|
||||
* better fix for new/dispose bug with init/final data
|
||||
|
||||
Revision 1.21 2002/03/31 20:26:39 jonas
|
||||
+ a_loadfpu_* and a_loadmm_* methods in tcg
|
||||
* register allocation is now handled by a class and is mostly processor
|
||||
independent (+rgobj.pas and i386/rgcpu.pas)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user