mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 12:39:09 +02:00
* Nil constants that are type converted to a method procvar are now
properly converted. The conversion is done at runtime to generate a two pointer memory reference as result location, something which the code generator can handle very well, which minimizes the chance of side effects. git-svn-id: trunk@7978 -
This commit is contained in:
parent
b86574cf36
commit
6e0a7bb0eb
@ -63,6 +63,7 @@ interface
|
|||||||
tc_int_2_real,
|
tc_int_2_real,
|
||||||
tc_real_2_currency,
|
tc_real_2_currency,
|
||||||
tc_proc_2_procvar,
|
tc_proc_2_procvar,
|
||||||
|
tc_nil_2_methodprocvar,
|
||||||
tc_arrayconstructor_2_set,
|
tc_arrayconstructor_2_set,
|
||||||
tc_set_to_set,
|
tc_set_to_set,
|
||||||
tc_cord_2_pointer,
|
tc_cord_2_pointer,
|
||||||
@ -1155,7 +1156,12 @@ implementation
|
|||||||
{ nil is compatible with procvars }
|
{ nil is compatible with procvars }
|
||||||
if (fromtreetype=niln) then
|
if (fromtreetype=niln) then
|
||||||
begin
|
begin
|
||||||
doconv:=tc_equal;
|
if not Tprocvardef(def_to).is_addressonly then
|
||||||
|
{Nil to method pointers requires to convert a single
|
||||||
|
pointer nil value to a two pointer procvardef.}
|
||||||
|
doconv:=tc_nil_2_methodprocvar
|
||||||
|
else
|
||||||
|
doconv:=tc_equal;
|
||||||
eq:=te_convert_l1;
|
eq:=te_convert_l1;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -41,6 +41,7 @@ interface
|
|||||||
procedure second_real_to_real;override;
|
procedure second_real_to_real;override;
|
||||||
procedure second_cord_to_pointer;override;
|
procedure second_cord_to_pointer;override;
|
||||||
procedure second_proc_to_procvar;override;
|
procedure second_proc_to_procvar;override;
|
||||||
|
procedure second_nil_to_methodprocvar;override;
|
||||||
procedure second_bool_to_int;override;
|
procedure second_bool_to_int;override;
|
||||||
procedure second_bool_to_bool;override;
|
procedure second_bool_to_bool;override;
|
||||||
procedure second_ansistring_to_pchar;override;
|
procedure second_ansistring_to_pchar;override;
|
||||||
@ -372,6 +373,18 @@ interface
|
|||||||
location_copy(location,left.location);
|
location_copy(location,left.location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure Tcgtypeconvnode.second_nil_to_methodprocvar;
|
||||||
|
|
||||||
|
var r:Treference;
|
||||||
|
|
||||||
|
begin
|
||||||
|
tg.gettemp(current_asmdata.currasmlist,2*sizeof(aword),tt_normal,r);
|
||||||
|
location_reset(location,LOC_REFERENCE,OS_NO);
|
||||||
|
location.reference:=r;
|
||||||
|
cg.a_load_const_ref(current_asmdata.currasmlist,OS_ADDR,0,r);
|
||||||
|
inc(r.offset,8);
|
||||||
|
cg.a_load_const_ref(current_asmdata.currasmlist,OS_ADDR,0,r);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure tcgtypeconvnode.second_bool_to_int;
|
procedure tcgtypeconvnode.second_bool_to_int;
|
||||||
var
|
var
|
||||||
|
@ -100,6 +100,7 @@ interface
|
|||||||
function first_int_to_bool : tnode;virtual;
|
function first_int_to_bool : tnode;virtual;
|
||||||
function first_bool_to_bool : tnode;virtual;
|
function first_bool_to_bool : tnode;virtual;
|
||||||
function first_proc_to_procvar : tnode;virtual;
|
function first_proc_to_procvar : tnode;virtual;
|
||||||
|
function first_nil_to_methodprocvar : tnode;virtual;
|
||||||
function first_set_to_set : tnode;virtual;
|
function first_set_to_set : tnode;virtual;
|
||||||
function first_cord_to_pointer : tnode;virtual;
|
function first_cord_to_pointer : tnode;virtual;
|
||||||
function first_ansistring_to_pchar : tnode;virtual;
|
function first_ansistring_to_pchar : tnode;virtual;
|
||||||
@ -126,6 +127,7 @@ interface
|
|||||||
function _first_int_to_bool : tnode;
|
function _first_int_to_bool : tnode;
|
||||||
function _first_bool_to_bool : tnode;
|
function _first_bool_to_bool : tnode;
|
||||||
function _first_proc_to_procvar : tnode;
|
function _first_proc_to_procvar : tnode;
|
||||||
|
function _first_nil_to_methodprocvar : tnode;
|
||||||
function _first_cord_to_pointer : tnode;
|
function _first_cord_to_pointer : tnode;
|
||||||
function _first_ansistring_to_pchar : tnode;
|
function _first_ansistring_to_pchar : tnode;
|
||||||
function _first_arrayconstructor_to_set : tnode;
|
function _first_arrayconstructor_to_set : tnode;
|
||||||
@ -146,6 +148,7 @@ interface
|
|||||||
procedure _second_real_to_real;virtual;
|
procedure _second_real_to_real;virtual;
|
||||||
procedure _second_cord_to_pointer;virtual;
|
procedure _second_cord_to_pointer;virtual;
|
||||||
procedure _second_proc_to_procvar;virtual;
|
procedure _second_proc_to_procvar;virtual;
|
||||||
|
procedure _second_nil_to_methodprocvar;virtual;
|
||||||
procedure _second_bool_to_int;virtual;
|
procedure _second_bool_to_int;virtual;
|
||||||
procedure _second_int_to_bool;virtual;
|
procedure _second_int_to_bool;virtual;
|
||||||
procedure _second_bool_to_bool;virtual;
|
procedure _second_bool_to_bool;virtual;
|
||||||
@ -168,6 +171,7 @@ interface
|
|||||||
procedure second_real_to_real;virtual;abstract;
|
procedure second_real_to_real;virtual;abstract;
|
||||||
procedure second_cord_to_pointer;virtual;abstract;
|
procedure second_cord_to_pointer;virtual;abstract;
|
||||||
procedure second_proc_to_procvar;virtual;abstract;
|
procedure second_proc_to_procvar;virtual;abstract;
|
||||||
|
procedure second_nil_to_methodprocvar;virtual;abstract;
|
||||||
procedure second_bool_to_int;virtual;abstract;
|
procedure second_bool_to_int;virtual;abstract;
|
||||||
procedure second_int_to_bool;virtual;abstract;
|
procedure second_int_to_bool;virtual;abstract;
|
||||||
procedure second_bool_to_bool;virtual;abstract;
|
procedure second_bool_to_bool;virtual;abstract;
|
||||||
@ -726,6 +730,7 @@ implementation
|
|||||||
'tc_int_2_real',
|
'tc_int_2_real',
|
||||||
'tc_real_2_currency',
|
'tc_real_2_currency',
|
||||||
'tc_proc_2_procvar',
|
'tc_proc_2_procvar',
|
||||||
|
'tc_nil_2_methodprocvar',
|
||||||
'tc_arrayconstructor_2_set',
|
'tc_arrayconstructor_2_set',
|
||||||
'tc_set_2_set',
|
'tc_set_2_set',
|
||||||
'tc_cord_2_pointer',
|
'tc_cord_2_pointer',
|
||||||
@ -1461,6 +1466,7 @@ implementation
|
|||||||
{ int_2_real } @ttypeconvnode.typecheck_int_to_real,
|
{ int_2_real } @ttypeconvnode.typecheck_int_to_real,
|
||||||
{ real_2_currency } @ttypeconvnode.typecheck_real_to_currency,
|
{ real_2_currency } @ttypeconvnode.typecheck_real_to_currency,
|
||||||
{ proc_2_procvar } @ttypeconvnode.typecheck_proc_to_procvar,
|
{ proc_2_procvar } @ttypeconvnode.typecheck_proc_to_procvar,
|
||||||
|
{ nil_2_methodprocvar } nil,
|
||||||
{ arrayconstructor_2_set } @ttypeconvnode.typecheck_arrayconstructor_to_set,
|
{ arrayconstructor_2_set } @ttypeconvnode.typecheck_arrayconstructor_to_set,
|
||||||
{ set_to_set } @ttypeconvnode.typecheck_set_to_set,
|
{ set_to_set } @ttypeconvnode.typecheck_set_to_set,
|
||||||
{ cord_2_pointer } @ttypeconvnode.typecheck_cord_to_pointer,
|
{ cord_2_pointer } @ttypeconvnode.typecheck_cord_to_pointer,
|
||||||
@ -2272,6 +2278,13 @@ implementation
|
|||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ttypeconvnode.first_nil_to_methodprocvar : tnode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
first_nil_to_methodprocvar:=nil;
|
||||||
|
registersint:=0;
|
||||||
|
expectloc:=LOC_REFERENCE;
|
||||||
|
end;
|
||||||
|
|
||||||
function ttypeconvnode.first_set_to_set : tnode;
|
function ttypeconvnode.first_set_to_set : tnode;
|
||||||
var
|
var
|
||||||
@ -2422,6 +2435,11 @@ implementation
|
|||||||
result:=first_proc_to_procvar;
|
result:=first_proc_to_procvar;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ttypeconvnode._first_nil_to_methodprocvar : tnode;
|
||||||
|
begin
|
||||||
|
result:=first_nil_to_methodprocvar;
|
||||||
|
end;
|
||||||
|
|
||||||
function ttypeconvnode._first_set_to_set : tnode;
|
function ttypeconvnode._first_set_to_set : tnode;
|
||||||
begin
|
begin
|
||||||
result:=first_set_to_set;
|
result:=first_set_to_set;
|
||||||
@ -2479,6 +2497,7 @@ implementation
|
|||||||
@ttypeconvnode._first_int_to_real,
|
@ttypeconvnode._first_int_to_real,
|
||||||
nil, { removed in typecheck_real_to_currency }
|
nil, { removed in typecheck_real_to_currency }
|
||||||
@ttypeconvnode._first_proc_to_procvar,
|
@ttypeconvnode._first_proc_to_procvar,
|
||||||
|
@ttypeconvnode._first_nil_to_methodprocvar,
|
||||||
@ttypeconvnode._first_arrayconstructor_to_set,
|
@ttypeconvnode._first_arrayconstructor_to_set,
|
||||||
@ttypeconvnode._first_set_to_set,
|
@ttypeconvnode._first_set_to_set,
|
||||||
@ttypeconvnode._first_cord_to_pointer,
|
@ttypeconvnode._first_cord_to_pointer,
|
||||||
@ -2646,6 +2665,10 @@ implementation
|
|||||||
second_proc_to_procvar;
|
second_proc_to_procvar;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ttypeconvnode._second_nil_to_methodprocvar;
|
||||||
|
begin
|
||||||
|
second_nil_to_methodprocvar;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure ttypeconvnode._second_bool_to_int;
|
procedure ttypeconvnode._second_bool_to_int;
|
||||||
begin
|
begin
|
||||||
@ -2721,6 +2744,7 @@ implementation
|
|||||||
@ttypeconvnode._second_int_to_real,
|
@ttypeconvnode._second_int_to_real,
|
||||||
@ttypeconvnode._second_nothing, { real_to_currency, handled in resultdef pass }
|
@ttypeconvnode._second_nothing, { real_to_currency, handled in resultdef pass }
|
||||||
@ttypeconvnode._second_proc_to_procvar,
|
@ttypeconvnode._second_proc_to_procvar,
|
||||||
|
@ttypeconvnode._second_nil_to_methodprocvar,
|
||||||
@ttypeconvnode._second_nothing, { arrayconstructor_to_set }
|
@ttypeconvnode._second_nothing, { arrayconstructor_to_set }
|
||||||
@ttypeconvnode._second_nothing, { second_set_to_set, handled in first pass }
|
@ttypeconvnode._second_nothing, { second_set_to_set, handled in first pass }
|
||||||
@ttypeconvnode._second_cord_to_pointer,
|
@ttypeconvnode._second_cord_to_pointer,
|
||||||
|
Loading…
Reference in New Issue
Block a user