Browse Source

* fixed storing "self" (nestedfpstruct) when taking the address of a nested
routine

git-svn-id: trunk@32551 -

Jonas Maebe 9 years ago
parent
commit
e144ba05c1
1 changed files with 10 additions and 1 deletions
  1. 10 1
      compiler/llvm/nllvmld.pas

+ 10 - 1
compiler/llvm/nllvmld.pas

@@ -74,6 +74,7 @@ procedure tllvmloadnode.pass_generate_code;
     href, mpref: treference;
     href, mpref: treference;
     field: tfieldvarsym;
     field: tfieldvarsym;
     procreg, selfreg: tregister;
     procreg, selfreg: tregister;
+    selfdef: tdef;
   begin
   begin
     inherited;
     inherited;
     case symtableentry.typ of
     case symtableentry.typ of
@@ -100,10 +101,18 @@ procedure tllvmloadnode.pass_generate_code;
                   procreg:=location.registerhi;
                   procreg:=location.registerhi;
                   selfreg:=location.register
                   selfreg:=location.register
                 end;
                 end;
+              { left can be a pointerdef when we take the address of a nested
+                procedure, as left will then be a pointer to the nestedfpstruct
+              }
+              if is_implicit_pointer_object_type(left.resultdef) or
+                  (left.resultdef.typ in [classrefdef,pointerdef]) then
+                selfdef:=left.resultdef
+              else
+                selfdef:=cpointerdef.getreusable(left.resultdef);
               mpref:=href;
               mpref:=href;
               hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(resultdef),cpointerdef.getreusable(methodpointertype),mpref);
               hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(resultdef),cpointerdef.getreusable(methodpointertype),mpref);
               hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,cprocvardef.getreusableprocaddr(procdef),trecorddef(methodpointertype),procreg,'proc',mpref);
               hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,cprocvardef.getreusableprocaddr(procdef),trecorddef(methodpointertype),procreg,'proc',mpref);
-              hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,left.resultdef,trecorddef(methodpointertype),selfreg,'self',mpref);
+              hlcg.g_load_reg_field_by_name(current_asmdata.CurrAsmList,selfdef,trecorddef(methodpointertype),selfreg,'self',mpref);
               location_reset_ref(location,LOC_REFERENCE,location.size,href.alignment);
               location_reset_ref(location,LOC_REFERENCE,location.size,href.alignment);
               location.reference:=href;
               location.reference:=href;
             end;
             end;