From 66be068365d61b10316c5007ae378d4df7a6afee Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 11 Sep 2016 17:12:04 +0000 Subject: [PATCH] * 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 - --- compiler/ncal.pas | 12 ++++++++++++ compiler/ncgcal.pas | 14 +++++++++++++- compiler/ncnv.pas | 3 +-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/compiler/ncal.pas b/compiler/ncal.pas index ac86b07910..95a95b0e02 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -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( diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index f3c6996790..7a56009253 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -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; diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index dd83cd0f47..d22efd2ea5 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -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;