* set the correct resultdef after converting a dynamic array to an open array

in ncnv
  * handle the fact that we overwrite the open array resultdef of a parameters'
    left node with the original resultdef (i.e., also for dynamic arrays) with
    regards to LLVM type rules
   o use the parameter's formal type (open array) instead of the value's type
     (dynamic array) when loading/using its value, since that's the type the
     value has been converted to
   o this change is not really nice since it adds several independent checks in
     different places, but I can't find a way to nicely unify the code to work
     around this (nor one to get rid of that hack in the first place)

git-svn-id: trunk@34515 -
This commit is contained in:
Jonas Maebe 2016-09-11 17:12:04 +00:00
parent dfb20f3f6a
commit 66be068365
3 changed files with 26 additions and 3 deletions

View File

@ -666,6 +666,18 @@ implementation
is_managed_type(tarraydef(resultdef).elementdef)) and
not(target_info.system in systems_garbage_collected_managed_types) then
begin
{ after converting a parameter to an open array, its resultdef is
set back to its original resultdef so we can get the value of the
"high" parameter correctly, even though we already inserted a
type conversion to "open array". Since here we work on this
converted parameter, set it back to the type to which it was
converted in order to avoid type mismatches at the LLVM level }
if is_open_array(parasym.vardef) and
is_dynamic_array(orgparadef) then
begin
left.resultdef:=resultdef;
orgparadef:=resultdef;
end;
paraaddrtype:=cpointerdef.getreusable(orgparadef);
{ create temp with address of the parameter }
temp:=ctempcreatenode.create(

View File

@ -163,10 +163,22 @@ implementation
procedure tcgcallparanode.push_addr_para;
var
valuedef: tdef;
begin
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
internalerror(200304235);
hlcg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,left.resultdef,left.location.reference,tempcgpara);
{ see the call to keep_para_array_range in ncal: if that call returned
true, we overwrite the resultdef of left with its original resultdef
(to keep track of the range of the original array); we inserted a type
conversion to parasym.vardef, so that is the type this value actually
has }
if is_dynamic_array(left.resultdef) and
is_open_array(parasym.vardef) then
valuedef:=parasym.vardef
else
valuedef:=left.resultdef;
hlcg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,valuedef,left.location.reference,tempcgpara);
end;

View File

@ -1611,13 +1611,12 @@ implementation
begin
{ a dynamic array is a pointer to an array, so to convert it to }
{ an open array, we have to dereference it (JM) }
result := ctypeconvnode.create_internal(left,voidpointertype);
result := ctypeconvnode.create_internal(left,cpointerdef.getreusable(resultdef));
typecheckpass(result);
{ left is reused }
left := nil;
result := cderefnode.create(result);
include(result.flags,nf_no_checkpointer);
result.resultdef := resultdef;
end;