|
@@ -1298,11 +1298,9 @@ implementation
|
|
gotstring,
|
|
gotstring,
|
|
gotsubscript,
|
|
gotsubscript,
|
|
gotrecord,
|
|
gotrecord,
|
|
- gotpointer,
|
|
|
|
gotvec,
|
|
gotvec,
|
|
gotclass,
|
|
gotclass,
|
|
gotdynarray,
|
|
gotdynarray,
|
|
- gotderef,
|
|
|
|
gottypeconv : boolean;
|
|
gottypeconv : boolean;
|
|
fromdef,
|
|
fromdef,
|
|
todef : tdef;
|
|
todef : tdef;
|
|
@@ -1313,7 +1311,7 @@ implementation
|
|
begin
|
|
begin
|
|
result:=false;
|
|
result:=false;
|
|
{ allow p^:= constructions with p is const parameter }
|
|
{ allow p^:= constructions with p is const parameter }
|
|
- if gotderef or gotdynarray or (Valid_Const in opts) or
|
|
|
|
|
|
+ if gotdynarray or (Valid_Const in opts) or
|
|
((hp.nodetype=loadn) and
|
|
((hp.nodetype=loadn) and
|
|
(loadnf_isinternal_ignoreconst in tloadnode(hp).loadnodeflags)) then
|
|
(loadnf_isinternal_ignoreconst in tloadnode(hp).loadnodeflags)) then
|
|
result:=true
|
|
result:=true
|
|
@@ -1361,10 +1359,8 @@ implementation
|
|
result:=false;
|
|
result:=false;
|
|
gotsubscript:=false;
|
|
gotsubscript:=false;
|
|
gotvec:=false;
|
|
gotvec:=false;
|
|
- gotderef:=false;
|
|
|
|
gotrecord:=false;
|
|
gotrecord:=false;
|
|
gotclass:=false;
|
|
gotclass:=false;
|
|
- gotpointer:=false;
|
|
|
|
gotdynarray:=false;
|
|
gotdynarray:=false;
|
|
gotstring:=false;
|
|
gotstring:=false;
|
|
gottypeconv:=false;
|
|
gottypeconv:=false;
|
|
@@ -1384,8 +1380,6 @@ implementation
|
|
begin
|
|
begin
|
|
{ check return type }
|
|
{ check return type }
|
|
case hp.resultdef.typ of
|
|
case hp.resultdef.typ of
|
|
- pointerdef :
|
|
|
|
- gotpointer:=true;
|
|
|
|
objectdef :
|
|
objectdef :
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
recorddef :
|
|
recorddef :
|
|
@@ -1401,8 +1395,6 @@ implementation
|
|
temps like calls that return a structure and we
|
|
temps like calls that return a structure and we
|
|
are assigning to a member }
|
|
are assigning to a member }
|
|
if (valid_const in opts) or
|
|
if (valid_const in opts) or
|
|
- { if we got a deref, we won't modify the property itself }
|
|
|
|
- (gotderef) or
|
|
|
|
{ same when we got a class and subscript (= deref) }
|
|
{ same when we got a class and subscript (= deref) }
|
|
(gotclass and gotsubscript) or
|
|
(gotclass and gotsubscript) or
|
|
{ indexing a dynamic array = dereference }
|
|
{ indexing a dynamic array = dereference }
|
|
@@ -1433,8 +1425,7 @@ implementation
|
|
{ 1. if it returns a pointer and we've found a deref,
|
|
{ 1. if it returns a pointer and we've found a deref,
|
|
2. if it returns a class and a subscription or with is found
|
|
2. if it returns a class and a subscription or with is found
|
|
3. if the address is needed of a field (subscriptn, vecn) }
|
|
3. if the address is needed of a field (subscriptn, vecn) }
|
|
- if (gotpointer and gotderef) or
|
|
|
|
- (gotstring and gotvec) or
|
|
|
|
|
|
+ if (gotstring and gotvec) or
|
|
(gotclass and gotsubscript) or
|
|
(gotclass and gotsubscript) or
|
|
(
|
|
(
|
|
(gotvec and gotdynarray)
|
|
(gotvec and gotdynarray)
|
|
@@ -1460,8 +1451,10 @@ implementation
|
|
end;
|
|
end;
|
|
derefn :
|
|
derefn :
|
|
begin
|
|
begin
|
|
- gotderef:=true;
|
|
|
|
- hp:=tderefnode(hp).left;
|
|
|
|
|
|
+ { dereference -> always valid }
|
|
|
|
+ valid_for_assign:=true;
|
|
|
|
+ mayberesettypeconvs;
|
|
|
|
+ exit;
|
|
end;
|
|
end;
|
|
typeconvn :
|
|
typeconvn :
|
|
begin
|
|
begin
|
|
@@ -1476,9 +1469,8 @@ implementation
|
|
todef:=hp.resultdef;
|
|
todef:=hp.resultdef;
|
|
{ typeconversions on the assignment side must keep
|
|
{ typeconversions on the assignment side must keep
|
|
left.location the same }
|
|
left.location the same }
|
|
- if not(gotderef or
|
|
|
|
- ((target_info.system in systems_jvm) and
|
|
|
|
- (gotsubscript or gotvec))) then
|
|
|
|
|
|
+ if not((target_info.system in systems_jvm) and
|
|
|
|
+ (gotsubscript or gotvec)) then
|
|
begin
|
|
begin
|
|
ttypeconvnode(hp).assignment_side:=true;
|
|
ttypeconvnode(hp).assignment_side:=true;
|
|
if not assigned(typeconvs) then
|
|
if not assigned(typeconvs) then
|
|
@@ -1526,7 +1518,7 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
{ don't allow assignments to typeconvs that need special code }
|
|
{ don't allow assignments to typeconvs that need special code }
|
|
- if not(gotsubscript or gotvec or gotderef) and
|
|
|
|
|
|
+ if not(gotsubscript or gotvec) and
|
|
not(ttypeconvnode(hp).assign_allowed) then
|
|
not(ttypeconvnode(hp).assign_allowed) then
|
|
begin
|
|
begin
|
|
if report_errors then
|
|
if report_errors then
|
|
@@ -1535,8 +1527,6 @@ implementation
|
|
exit;
|
|
exit;
|
|
end;
|
|
end;
|
|
case hp.resultdef.typ of
|
|
case hp.resultdef.typ of
|
|
- pointerdef :
|
|
|
|
- gotpointer:=true;
|
|
|
|
objectdef :
|
|
objectdef :
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
classrefdef :
|
|
classrefdef :
|
|
@@ -1546,7 +1536,11 @@ implementation
|
|
{ pointer -> array conversion is done then we need to see it
|
|
{ pointer -> array conversion is done then we need to see it
|
|
as a deref, because a ^ is then not required anymore }
|
|
as a deref, because a ^ is then not required anymore }
|
|
if ttypeconvnode(hp).convtype=tc_pointer_2_array then
|
|
if ttypeconvnode(hp).convtype=tc_pointer_2_array then
|
|
- gotderef:=true;
|
|
|
|
|
|
+ begin
|
|
|
|
+ valid_for_assign:=true;
|
|
|
|
+ mayberesettypeconvs;
|
|
|
|
+ exit
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
hp:=ttypeconvnode(hp).left;
|
|
hp:=ttypeconvnode(hp).left;
|
|
@@ -1592,7 +1586,7 @@ implementation
|
|
begin
|
|
begin
|
|
{ asn can't be assigned directly, it returns the value in a register instead
|
|
{ asn can't be assigned directly, it returns the value in a register instead
|
|
of reference. }
|
|
of reference. }
|
|
- if not(gotsubscript or gotderef or gotvec) then
|
|
|
|
|
|
+ if not(gotsubscript or gotvec) then
|
|
begin
|
|
begin
|
|
if report_errors then
|
|
if report_errors then
|
|
CGMessagePos(hp.fileinfo,errmsg);
|
|
CGMessagePos(hp.fileinfo,errmsg);
|
|
@@ -1632,7 +1626,6 @@ implementation
|
|
subscript operation (to a temp location, so the assignment
|
|
subscript operation (to a temp location, so the assignment
|
|
will happen to the temp and be lost) }
|
|
will happen to the temp and be lost) }
|
|
if not gotsubscript and
|
|
if not gotsubscript and
|
|
- not gotderef and
|
|
|
|
not gotvec and
|
|
not gotvec and
|
|
not tstoreddef(hp.resultdef).is_intregable then
|
|
not tstoreddef(hp.resultdef).is_intregable then
|
|
make_not_regable(hp,[ra_addr_regable]);
|
|
make_not_regable(hp,[ra_addr_regable]);
|
|
@@ -1650,7 +1643,11 @@ implementation
|
|
{ implicit pointer object types result in dereferencing }
|
|
{ implicit pointer object types result in dereferencing }
|
|
hp:=tsubscriptnode(hp).left;
|
|
hp:=tsubscriptnode(hp).left;
|
|
if is_implicit_pointer_object_type(hp.resultdef) then
|
|
if is_implicit_pointer_object_type(hp.resultdef) then
|
|
- gotderef:=true;
|
|
|
|
|
|
+ begin
|
|
|
|
+ valid_for_assign:=true;
|
|
|
|
+ mayberesettypeconvs;
|
|
|
|
+ exit
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
muln,
|
|
muln,
|
|
divn,
|
|
divn,
|
|
@@ -1661,20 +1658,13 @@ implementation
|
|
subn,
|
|
subn,
|
|
addn :
|
|
addn :
|
|
begin
|
|
begin
|
|
- { Allow operators on a pointer, or on an integer
|
|
|
|
- if a pointer typecast and deref have been found }
|
|
|
|
- if ((hp.resultdef.typ=pointerdef) or
|
|
|
|
- (is_integer(hp.resultdef) and gotpointer)) and
|
|
|
|
- gotderef then
|
|
|
|
- result:=true
|
|
|
|
- else
|
|
|
|
{ Temp strings are stored in memory, for compatibility with
|
|
{ Temp strings are stored in memory, for compatibility with
|
|
delphi only }
|
|
delphi only }
|
|
- if (m_delphi in current_settings.modeswitches) and
|
|
|
|
- ((valid_addr in opts) or
|
|
|
|
- (valid_const in opts)) and
|
|
|
|
- (hp.resultdef.typ=stringdef) then
|
|
|
|
- result:=true
|
|
|
|
|
|
+ if (m_delphi in current_settings.modeswitches) and
|
|
|
|
+ ((valid_addr in opts) or
|
|
|
|
+ (valid_const in opts)) and
|
|
|
|
+ (hp.resultdef.typ=stringdef) then
|
|
|
|
+ result:=true
|
|
else
|
|
else
|
|
if report_errors then
|
|
if report_errors then
|
|
CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
|
|
CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
|
|
@@ -1684,11 +1674,7 @@ implementation
|
|
niln,
|
|
niln,
|
|
pointerconstn :
|
|
pointerconstn :
|
|
begin
|
|
begin
|
|
- { to support e.g. @tmypointer(0)^.data; see tests/tbs/tb0481 }
|
|
|
|
- if gotderef then
|
|
|
|
- result:=true
|
|
|
|
- else
|
|
|
|
- if report_errors then
|
|
|
|
|
|
+ if report_errors then
|
|
CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
|
|
CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
|
|
mayberesettypeconvs;
|
|
mayberesettypeconvs;
|
|
exit;
|
|
exit;
|
|
@@ -1717,10 +1703,7 @@ implementation
|
|
end;
|
|
end;
|
|
addrn :
|
|
addrn :
|
|
begin
|
|
begin
|
|
- if gotderef then
|
|
|
|
- result:=true
|
|
|
|
- else
|
|
|
|
- if report_errors then
|
|
|
|
|
|
+ if report_errors then
|
|
CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
|
|
CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
|
|
mayberesettypeconvs;
|
|
mayberesettypeconvs;
|
|
exit;
|
|
exit;
|
|
@@ -1740,12 +1723,11 @@ implementation
|
|
if is_dynamic_array(hp.resultdef) and
|
|
if is_dynamic_array(hp.resultdef) and
|
|
gotvec then
|
|
gotvec then
|
|
begin
|
|
begin
|
|
- gotderef:=true;
|
|
|
|
- gotpointer:=true;
|
|
|
|
|
|
+ valid_for_assign:=true;
|
|
|
|
+ mayberesettypeconvs;
|
|
|
|
+ exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
- pointerdef :
|
|
|
|
- gotpointer:=true;
|
|
|
|
objectdef :
|
|
objectdef :
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
gotclass:=is_implicit_pointer_object_type(hp.resultdef);
|
|
recorddef, { handle record like class it needs a subscription }
|
|
recorddef, { handle record like class it needs a subscription }
|
|
@@ -1754,11 +1736,9 @@ implementation
|
|
stringdef :
|
|
stringdef :
|
|
gotstring:=true;
|
|
gotstring:=true;
|
|
end;
|
|
end;
|
|
- { 1. if it returns a pointer and we've found a deref,
|
|
|
|
- 2. if it returns a class or record and a subscription or with is found
|
|
|
|
- 3. string is returned }
|
|
|
|
|
|
+ { 1. string element is returned
|
|
|
|
+ 2. if it returns a class or record and a subscription or with is found }
|
|
if (gotstring and gotvec) or
|
|
if (gotstring and gotvec) or
|
|
- (gotpointer and gotderef) or
|
|
|
|
(gotclass and gotsubscript) then
|
|
(gotclass and gotsubscript) then
|
|
result:=true
|
|
result:=true
|
|
else
|
|
else
|
|
@@ -1837,7 +1817,6 @@ implementation
|
|
begin
|
|
begin
|
|
{ loop counter? }
|
|
{ loop counter? }
|
|
if not(Valid_Const in opts) and
|
|
if not(Valid_Const in opts) and
|
|
- not gotderef and
|
|
|
|
(vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
|
|
(vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
|
|
begin
|
|
begin
|
|
if report_errors then
|
|
if report_errors then
|