View Issue Details

IDProjectCategoryView StatusLast Update
0018121FPCCompilerpublic2018-12-08 18:10
ReporterPaul IsheninAssigned ToJonas Maebe 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Platformwin32OSwindowsOS Versionwindows 7
Product Version2.5.1Product Build16490 
Target VersionFixed in Version3.1.1 
Summary0018121: Illegal expression if inherited is used in inline method
DescriptionAttached code produces illegal expression in nutils.pas load_self_node routine.
TagsNo tags attached.
Fixed in Revision30908
FPCOldBugId0
FPCTarget
Attached Files
  • project1.lpr (903 bytes)
  • callcontext.patch (25,960 bytes)
    Index: procinfo.pas
    ===================================================================
    --- procinfo.pas	(revision 16490)
    +++ procinfo.pas	(working copy)
    @@ -123,6 +123,10 @@
     
               { Allocate got register }
               procedure allocate_got_register(list: TAsmList);virtual;
    +
    +          { returns the value of the procdef field if assigned(self),
    +            nil otherwise }
    +          function safe_procdef: tprocdef;
            end;
            tcprocinfo = class of tprocinfo;
     
    @@ -207,5 +211,13 @@
             { most os/cpu combo's don't use this yet, so not yet abstract }
           end;
     
    +    function tprocinfo.safe_procdef: tprocdef;
    +      begin
    +        if assigned(self) then
    +          result:=procdef
    +        else
    +          result:=nil;
    +      end;
     
    +
     end.
    Index: pexpr.pas
    ===================================================================
    --- pexpr.pas	(revision 16490)
    +++ pexpr.pas	(working copy)
    @@ -844,7 +844,7 @@
                      if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                        p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
                      else
    -                   p1:=load_self_node;
    +                   p1:=load_self_node(current_procinfo.safe_procdef);
                      { We are calling a member }
                      maybe_load_methodpointer:=true;
                    end;
    @@ -914,7 +914,7 @@
                       begin
                         include(p2.flags,nf_inherited);
                         p1.free;
    -                    p1:=load_self_node;
    +                    p1:=load_self_node(current_procinfo.safe_procdef);
                       end;
                     if (p1.nodetype<>typen) then
                       tloadnode(p2).set_mp(p1)
    @@ -1466,7 +1466,7 @@
                               if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                                 p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
                               else
    -                            p1:=load_self_node;
    +                            p1:=load_self_node(current_procinfo.safe_procdef);
                             { now, if the field itself is part of an objectsymtab }
                             { (it can be even if it was found in a withsymtable,  }
                             {  e.g., "with classinstance do field := 5"), then    }
    @@ -1648,7 +1648,7 @@
                               { no self node in static class methods }
                                 p1:=cloadvmtaddrnode.create(ctypenode.create(hdef))
                               else
    -                            p1:=load_self_node;
    +                            p1:=load_self_node(current_procinfo.safe_procdef);
                             { not srsymtable.symtabletype since that can be }
                             { withsymtable as well                          }
                             if (srsym.owner.symtabletype=ObjectSymtable) then
    @@ -2311,7 +2311,7 @@
                   not(block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) and
                   assigned(current_objectdef) then
                  begin
    -               p1:=load_self_node;
    +               p1:=load_self_node(current_procinfo.safe_procdef);
                    consume(_ID);
                    again:=true;
                  end
    Index: nutils.pas
    ===================================================================
    --- nutils.pas	(revision 16490)
    +++ nutils.pas	(working copy)
    @@ -27,7 +27,7 @@
     
       uses
         globtype,constexp,
    -    symtype,symsym,symbase,symtable,
    +    symtype,symdef,symsym,symbase,symtable,
         node;
     
       const
    @@ -66,13 +66,13 @@
         function maybe_call_procvar(var p1:tnode;tponly:boolean):boolean;
         function get_high_value_sym(vs: tparavarsym):tsym; { marking it as inline causes IE 200311075 during loading from ppu file }
         function load_high_value_node(vs:tparavarsym):tnode;
    -    function load_self_node:tnode;
    -    function load_result_node:tnode;
    -    function load_self_pointer_node:tnode;
    -    function load_vmt_pointer_node:tnode;
    +    function load_self_node(contextpd:tprocdef):tnode;
    +    function load_result_node(contextpd:tprocdef):tnode;
    +    function load_self_pointer_node(contextpd:tprocdef):tnode;
    +    function load_vmt_pointer_node(contextpd:tprocdef):tnode;
         function is_self_node(p:tnode):boolean;
     
    -    function call_fail_node:tnode;
    +    function call_fail_node(contextpd:tprocdef):tnode;
         function initialize_data_node(p:tnode):tnode;
         function finalize_data_node(p:tnode):tnode;
     
    @@ -114,7 +114,7 @@
     
         uses
           cutils,verbose,globals,
    -      symconst,symdef,
    +      symconst,
           defutil,defcmp,
           nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
           cpubase,cgbase,procinfo,
    @@ -397,18 +397,16 @@
           end;
     
     
    -    function get_local_or_para_sym(const aname:string):tsym;
    -      var
    -        pd : tprocdef;
    +    { pd: the procdefinition in whose context 'aname' has to be searched }
    +    function get_local_or_para_sym(pd: tprocdef; const aname:string):tsym;
           begin
             result:=nil;
             { is not assigned while parsing a property }
    -        if not assigned(current_procinfo) then
    +        if not assigned(pd) then
               exit;
             { we can't use searchsym here, because the
               symtablestack is not fully setup when pass1
               is run for nested procedures }
    -        pd:=current_procinfo.procdef;
             repeat
               result := tsym(pd.localst.Find(aname));
               if assigned(result) then
    @@ -442,13 +440,13 @@
           end;
     
     
    -    function load_self_node:tnode;
    +    function load_self_node(contextpd:tprocdef):tnode;
           var
             srsym : tsym;
           begin
             result:=nil;
     
    -        srsym:=get_local_or_para_sym('self');
    +        srsym:=get_local_or_para_sym(contextpd,'self');
             if assigned(srsym) then
               begin
                 result:=cloadnode.create(srsym,srsym.owner);
    @@ -463,12 +461,12 @@
           end;
     
     
    -    function load_result_node:tnode;
    +    function load_result_node(contextpd:tprocdef):tnode;
           var
             srsym : tsym;
           begin
             result:=nil;
    -        srsym:=get_local_or_para_sym('result');
    +        srsym:=get_local_or_para_sym(contextpd,'result');
             if assigned(srsym) then
               result:=cloadnode.create(srsym,srsym.owner)
             else
    @@ -480,12 +478,12 @@
           end;
     
     
    -    function load_self_pointer_node:tnode;
    +    function load_self_pointer_node(contextpd:tprocdef):tnode;
           var
             srsym : tsym;
           begin
             result:=nil;
    -        srsym:=get_local_or_para_sym('self');
    +        srsym:=get_local_or_para_sym(contextpd,'self');
             if assigned(srsym) then
               begin
                 result:=cloadnode.create(srsym,srsym.owner);
    @@ -500,12 +498,12 @@
           end;
     
     
    -    function load_vmt_pointer_node:tnode;
    +    function load_vmt_pointer_node(contextpd: tprocdef):tnode;
           var
             srsym : tsym;
           begin
             result:=nil;
    -        srsym:=get_local_or_para_sym('vmt');
    +        srsym:=get_local_or_para_sym(contextpd,'vmt');
             if assigned(srsym) then
               result:=cloadnode.create(srsym,srsym.owner)
             else
    @@ -525,7 +523,7 @@
           end;
     
     
    -    function call_fail_node:tnode;
    +    function call_fail_node(contextpd: tprocdef):tnode;
           var
             para : tcallparanode;
             newstatement : tstatementnode;
    @@ -544,12 +542,12 @@
                     addstatement(newstatement,cifnode.create(
                         caddnode.create(andn,
                             caddnode.create(unequaln,
    -                            load_self_pointer_node,
    +                            load_self_pointer_node(contextpd),
                                 cnilnode.create),
                             caddnode.create(unequaln,
    -                            load_vmt_pointer_node,
    +                            load_vmt_pointer_node(contextpd),
                                 cnilnode.create)),
    -                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
    +                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.safe_procdef),[]),
                         nil));
                   end
                 else
    @@ -565,11 +563,11 @@
                             cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                         ccallparanode.create(
                             ctypeconvnode.create_internal(
    -                            load_vmt_pointer_node,
    +                            load_vmt_pointer_node(contextpd),
                                 voidpointertype),
                         ccallparanode.create(
                             ctypeconvnode.create_internal(
    -                            load_self_pointer_node,
    +                            load_self_pointer_node(contextpd),
                                 voidpointertype),
                         nil)));
                   addstatement(newstatement,
    @@ -579,7 +577,7 @@
               internalerror(200305132);
             { self:=nil }
             addstatement(newstatement,cassignmentnode.create(
    -            load_self_pointer_node,
    +            load_self_pointer_node(contextpd),
                 cnilnode.create));
             { exit }
             addstatement(newstatement,cexitnode.create(nil));
    @@ -1069,7 +1067,7 @@
                           withsymtable :
                             p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                           ObjectSymtable :
    -                        p1:=load_self_node;
    +                        p1:=load_self_node(current_procinfo.safe_procdef);
                         end;
                       end;
                      if assigned(p1) then
    Index: pstatmnt.pas
    ===================================================================
    --- pstatmnt.pas	(revision 16490)
    +++ pstatmnt.pas	(working copy)
    @@ -1100,7 +1100,7 @@
                     if (current_procinfo.procdef.proctypeoption<>potype_constructor) then
                       Message(parser_e_fail_only_in_constructor);
                     consume(_FAIL);
    -                code:=call_fail_node;
    +                code:=call_fail_node(current_procinfo.procdef);
                  end;
                _ASM :
                  code:=_asm_statement;
    Index: ncal.pas
    ===================================================================
    --- ncal.pas	(revision 16490)
    +++ ncal.pas	(working copy)
    @@ -116,6 +116,11 @@
               funcretnode    : tnode;
               { varargs parasyms }
               varargsparas : tvarargsparalist;
    +          { procdef of the routine in which this call is performed, to
    +            properly resolve "inherited" and other self-based references
    +            when e.g. inlining }
    +          contextpd      : tprocdef;
    +          contextpdderef : tderef;
     
               { separately specified resultdef for some compilerprocs (e.g. }
               { you can't have a function with an "array of char" resultdef }
    @@ -1012,6 +1017,10 @@
              funcretnode:=nil;
              paralength:=-1;
              varargsparas:=nil;
    +         if assigned(current_procinfo) then
    +           contextpd:=current_procinfo.procdef
    +         else
    +           contextpd:=nil;
           end;
     
     
    @@ -1028,6 +1037,10 @@
              funcretnode:=nil;
              paralength:=-1;
              varargsparas:=nil;
    +         if assigned(current_procinfo) then
    +           contextpd:=current_procinfo.procdef
    +         else
    +           contextpd:=nil;
           end;
     
     
    @@ -1122,6 +1135,7 @@
             symtableproc:=nil;
             ppufile.getderef(procdefinitionderef);
             ppufile.getsmallset(callnodeflags);
    +        ppufile.getderef(contextpdderef);
           end;
     
     
    @@ -1135,6 +1149,7 @@
             ppufile.putderef(symtableprocentryderef);
             ppufile.putderef(procdefinitionderef);
             ppufile.putsmallset(callnodeflags);
    +        ppufile.putderef(contextpdderef);
           end;
     
     
    @@ -1143,6 +1158,7 @@
             inherited buildderefimpl;
             symtableprocentryderef.build(symtableprocentry);
             procdefinitionderef.build(procdefinition);
    +        contextpdderef.build(contextpd);
             if assigned(methodpointer) then
               methodpointer.buildderefimpl;
             if assigned(callinitblock) then
    @@ -1164,6 +1180,7 @@
             if assigned(symtableprocentry) then
               symtableproc:=symtableprocentry.owner;
             procdefinition:=tabstractprocdef(procdefinitionderef.resolve);
    +        contextpd:=tprocdef(contextpdderef.resolve);
             if assigned(methodpointer) then
               methodpointer.derefimpl;
             if assigned(callinitblock) then
    @@ -1242,6 +1259,7 @@
              end
             else
              n.varargsparas:=nil;
    +        n.contextpd:=contextpd;
             result:=n;
           end;
     
    @@ -1255,7 +1273,12 @@
               (methodpointer.isequal(tcallnode(p).methodpointer)) and
               (((cnf_typedefset in callnodeflags) and (cnf_typedefset in tcallnode(p).callnodeflags) and
                 (equal_defs(typedef,tcallnode(p).typedef))) or
    -           (not(cnf_typedefset in callnodeflags) and not(cnf_typedefset in tcallnode(p).callnodeflags)));
    +           (not(cnf_typedefset in callnodeflags) and not(cnf_typedefset in tcallnode(p).callnodeflags))) and
    +          { only has to be equal for call nodes that actually use the contextpd,
    +            but there's no way to determine that in a non-fragile way and we
    +            currently probably never optimise away duplicate callnodes anyway
    +            since we have no side-effect tracking }
    +          (tcallnode(p).contextpd=contextpd);
           end;
     
     
    @@ -1640,7 +1663,7 @@
             { inherited }
             else if (cnf_inherited in callnodeflags) then
               begin
    -            selftree:=load_self_node;
    +            selftree:=load_self_node(contextpd);
                { we can call an inherited class static/method from a regular method
                  -> self node must change from instance pointer to vmt pointer)
                }
    @@ -1659,7 +1682,7 @@
                   else
                     begin
                       if methodpointer.nodetype=typen then
    -                    selftree:=load_self_node
    +                    selftree:=load_self_node(contextpd)
                       else
                         selftree:=methodpointer.getcopy;
                     end;
    @@ -1687,7 +1710,7 @@
             else
               begin
                 if methodpointer.nodetype=typen then
    -              selftree:=load_self_node
    +              selftree:=load_self_node(contextpd)
                 else
                   selftree:=methodpointer.getcopy;
               end;
    @@ -1904,11 +1927,11 @@
                  objcsupertype:=search_named_unit_globaltype('OBJC','OBJC_SUPER',true).typedef;
                  if (objcsupertype.typ<>recorddef) then
                    internalerror(2009032901);
    -             { temp for the for the objc_super record }
    +             { temp for the objc_super record }
                  temp:=ctempcreatenode.create(objcsupertype,objcsupertype.size,tt_persistent,false);
                  addstatement(statements,temp);
                  { initialize objc_super record }
    -             selftree:=load_self_node;
    +             selftree:=load_self_node(contextpd);
     
                  { we can call an inherited class static/method from a regular method
                    -> self node must change from instance pointer to vmt pointer)
    Index: ppu.pas
    ===================================================================
    --- ppu.pas	(revision 16490)
    +++ ppu.pas	(working copy)
    @@ -43,7 +43,7 @@
     {$endif Test_Double_checksum}
     
     const
    -  CurrentPPUVersion = 121;
    +  CurrentPPUVersion = 122;
     
     { buffer sizes }
       maxentrysize = 1024;
    Index: ncnv.pas
    ===================================================================
    --- ncnv.pas	(revision 16490)
    +++ ncnv.pas	(working copy)
    @@ -1834,7 +1834,7 @@
                                if assigned(tcallnode(left).methodpointer) then
                                  tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
                                else
    -                             tloadnode(hp).set_mp(load_self_node);
    +                             tloadnode(hp).set_mp(load_self_node(current_procinfo.safe_procdef));
                              end;
                             typecheckpass(hp);
                           end;
    Index: psub.pas
    ===================================================================
    --- psub.pas	(revision 16490)
    +++ psub.pas	(working copy)
    @@ -306,14 +306,14 @@
                             addstatement(newstatement,cifnode.create(
                                 caddnode.create(gtn,
                                     ctypeconvnode.create_internal(
    -                                    load_vmt_pointer_node,
    +                                    load_vmt_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                     cpointerconstnode.create(1,voidpointertype)),
                                 cassignmentnode.create(
                                     ctypeconvnode.create_internal(
    -                                    load_self_pointer_node,
    +                                    load_self_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
    -                                ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_vmt_pointer_node,[])),
    +                                ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_vmt_pointer_node(current_procinfo.procdef),[])),
                                 nil));
                           end
                         else
    @@ -331,16 +331,16 @@
                                     cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                                 ccallparanode.create(
                                     ctypeconvnode.create_internal(
    -                                    load_vmt_pointer_node,
    +                                    load_vmt_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                 ccallparanode.create(
                                     ctypeconvnode.create_internal(
    -                                    load_self_pointer_node,
    +                                    load_self_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                 nil)));
                           addstatement(newstatement,cassignmentnode.create(
                               ctypeconvnode.create_internal(
    -                              load_self_pointer_node,
    +                              load_self_pointer_node(current_procinfo.procdef),
                                   voidpointertype),
                               ccallnode.createintern('fpc_help_constructor',para)));
                         end
    @@ -351,7 +351,7 @@
                       there is nothing to dispose (PFV) }
                     addstatement(newstatement,cifnode.create(
                         caddnode.create(equaln,
    -                        load_self_pointer_node,
    +                        load_self_pointer_node(current_procinfo.procdef),
                             cnilnode.create),
                         cexitnode.create(nil),
                         nil));
    @@ -369,10 +369,10 @@
                         addstatement(newstatement,cifnode.create(
                             caddnode.create(gtn,
                                 ctypeconvnode.create_internal(
    -                              load_vmt_pointer_node,ptrsinttype),
    +                              load_vmt_pointer_node(current_procinfo.procdef),ptrsinttype),
                                 ctypeconvnode.create_internal(
                                   cnilnode.create,ptrsinttype)),
    -                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
    +                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                             nil));
                       end
                     else
    @@ -416,14 +416,14 @@
                             addstatement(newstatement,cifnode.create(
                                 caddnode.create(andn,
                                     caddnode.create(unequaln,
    -                                    load_self_pointer_node,
    +                                    load_self_pointer_node(current_procinfo.procdef),
                                         cnilnode.create),
                                     caddnode.create(unequaln,
                                         ctypeconvnode.create(
    -                                        load_vmt_pointer_node,
    +                                        load_vmt_pointer_node(current_procinfo.procdef),
                                             voidpointertype),
                                         cpointerconstnode.create(0,voidpointertype))),
    -                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
    +                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                                 nil));
                           end
                         else
    @@ -434,7 +434,7 @@
                         begin
                           { finalize object data }
                           if is_managed_type(current_objectdef) then
    -                        addstatement(newstatement,finalize_data_node(load_self_node));
    +                        addstatement(newstatement,finalize_data_node(load_self_node(current_procinfo.procdef)));
                           { parameter 3 : vmt_offset }
                           { parameter 2 : pointer to vmt }
                           { parameter 1 : self pointer }
    @@ -442,11 +442,11 @@
                                     cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                                 ccallparanode.create(
                                     ctypeconvnode.create_internal(
    -                                    load_vmt_pointer_node,
    +                                    load_vmt_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                 ccallparanode.create(
                                     ctypeconvnode.create_internal(
    -                                    load_self_pointer_node,
    +                                    load_self_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                 nil)));
                           addstatement(newstatement,
    @@ -480,7 +480,7 @@
                    is_managed_type(current_procinfo.procdef.returndef) and
                    (not paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption)) and
                    (not is_class(current_procinfo.procdef.returndef)) then
    -              addstatement(newstatement,finalize_data_node(load_result_node));
    +              addstatement(newstatement,finalize_data_node(load_result_node(current_procinfo.procdef)));
     {$if defined(x86) or defined(arm)}
                 { safecall handling }
                 if (tf_safecall_exceptions in target_info.flags) and
    @@ -520,7 +520,7 @@
                             ccallnode.create(
                               ccallparanode.create(ctemprefnode.create(exceptaddrnode),
                               ccallparanode.create(ctemprefnode.create(exceptobjnode),nil)),
    -                          tprocsym(exceptsym), tprocsym(exceptsym).owner,load_self_node,[])));
    +                          tprocsym(exceptsym), tprocsym(exceptsym).owner,load_self_node(current_procinfo.procdef),[])));
                         addstatement(newstatement,ccallnode.createintern('fpc_destroyexception',
                           ccallparanode.create(ctemprefnode.create(exceptobjnode),nil)));
                         addstatement(newstatement,ctempdeletenode.create(exceptobjnode));
    @@ -621,12 +621,12 @@
                         addstatement(newstatement,cifnode.create(
                           caddnode.create(andn,
                             caddnode.create(unequaln,
    -                          load_self_node,
    +                          load_self_node(current_procinfo.procdef),
                               cnilnode.create),
                             caddnode.create(unequaln,
    -                          load_vmt_pointer_node,
    +                          load_vmt_pointer_node(current_procinfo.procdef),
                               cnilnode.create)),
    -                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
    +                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                             nil));
                         tocode:=afterconstructionblock;
                       end
    @@ -649,10 +649,10 @@
                         { if vmt<>0 then call destructor }
                         addstatement(newstatement,cifnode.create(
                           caddnode.create(unequaln,
    -                        load_vmt_pointer_node,
    +                        load_vmt_pointer_node(current_procinfo.procdef),
                             cnilnode.create),
                           { cnf_create_failed -> don't call BeforeDestruction }
    -                      ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed]),
    +                      ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node(current_procinfo.procdef),[cnf_create_failed]),
                           nil));
                         { then re-raise the exception }
                         addstatement(newstatement,craisenode.create(nil,nil,nil));
    Index: optdfa.pas
    ===================================================================
    --- optdfa.pas	(revision 16490)
    +++ optdfa.pas	(working copy)
    @@ -556,7 +556,7 @@
               not(current_procinfo.procdef.proctypeoption=potype_constructor) then
               begin
                 { create a fake node using the result }
    -            resultnode:=load_result_node;
    +            resultnode:=load_result_node(current_procinfo.procdef);
                 resultnode.allocoptinfo;
                 dfarec.use:=@resultnode.optinfo^.use;
                 dfarec.def:=@resultnode.optinfo^.def;
    
    callcontext.patch (25,960 bytes)
  • tw18121.pp (191 bytes)
  • uw18121.pp (814 bytes)

Relationships

related to 0016582 closedJonas Maebe Compilation error with generics and inline 
has duplicate 0018776 resolvedJonas Maebe Inlining issue 
has duplicate 0018984 closedJonas Maebe INLINE class method not compile 
has duplicate 0021719 resolvedJonas Maebe inlining inherited does not compile 
has duplicate 0026397 resolvedJonas Maebe inline error 

Activities

2010-12-01 10:57

 

project1.lpr (903 bytes)

Paul Ishenin

2010-12-01 10:58

developer   ~0043835

issue 0016582 is caused by the same problem. I just reused the example from that issue to demonstrate that it is not related to generics.

Jonas Maebe

2010-12-01 15:50

manager   ~0043854

Last edited: 2013-09-05 14:24

View 2 revisions

I don't think this (and probably a bunch of other generics/inline-related issues) can be fixed without completely removing the use of current_procinfo.procdef from compiler/n*.pas (except maybe for ncgutil.pas)

I created a patch to fix the issue for load_self_node (and some related routines), but it just moves the problem (you'll now get an internalerror 200309284 in nld.pas, because the symtable level of the wrong function is checked and the compiler thinks it's in a nested function). Maybe the contextpd field I added for tcallnode should be moved to tnode and always be initialised so it can be used for all nodes.

Or maybe someone else sees a better solution.

I've also attached a test with a unit, to check that the new contextpd field is properly saved to/restored from ppu files.

2010-12-01 15:50

 

callcontext.patch (25,960 bytes)
Index: procinfo.pas
===================================================================
--- procinfo.pas	(revision 16490)
+++ procinfo.pas	(working copy)
@@ -123,6 +123,10 @@
 
           { Allocate got register }
           procedure allocate_got_register(list: TAsmList);virtual;
+
+          { returns the value of the procdef field if assigned(self),
+            nil otherwise }
+          function safe_procdef: tprocdef;
        end;
        tcprocinfo = class of tprocinfo;
 
@@ -207,5 +211,13 @@
         { most os/cpu combo's don't use this yet, so not yet abstract }
       end;
 
+    function tprocinfo.safe_procdef: tprocdef;
+      begin
+        if assigned(self) then
+          result:=procdef
+        else
+          result:=nil;
+      end;
 
+
 end.
Index: pexpr.pas
===================================================================
--- pexpr.pas	(revision 16490)
+++ pexpr.pas	(working copy)
@@ -844,7 +844,7 @@
                  if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                    p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
                  else
-                   p1:=load_self_node;
+                   p1:=load_self_node(current_procinfo.safe_procdef);
                  { We are calling a member }
                  maybe_load_methodpointer:=true;
                end;
@@ -914,7 +914,7 @@
                   begin
                     include(p2.flags,nf_inherited);
                     p1.free;
-                    p1:=load_self_node;
+                    p1:=load_self_node(current_procinfo.safe_procdef);
                   end;
                 if (p1.nodetype<>typen) then
                   tloadnode(p2).set_mp(p1)
@@ -1466,7 +1466,7 @@
                           if assigned(current_procinfo) and current_procinfo.procdef.no_self_node then
                             p1:=cloadvmtaddrnode.create(ctypenode.create(current_procinfo.procdef._class))
                           else
-                            p1:=load_self_node;
+                            p1:=load_self_node(current_procinfo.safe_procdef);
                         { now, if the field itself is part of an objectsymtab }
                         { (it can be even if it was found in a withsymtable,  }
                         {  e.g., "with classinstance do field := 5"), then    }
@@ -1648,7 +1648,7 @@
                           { no self node in static class methods }
                             p1:=cloadvmtaddrnode.create(ctypenode.create(hdef))
                           else
-                            p1:=load_self_node;
+                            p1:=load_self_node(current_procinfo.safe_procdef);
                         { not srsymtable.symtabletype since that can be }
                         { withsymtable as well                          }
                         if (srsym.owner.symtabletype=ObjectSymtable) then
@@ -2311,7 +2311,7 @@
               not(block_type in [bt_const,bt_type,bt_const_type,bt_var_type]) and
               assigned(current_objectdef) then
              begin
-               p1:=load_self_node;
+               p1:=load_self_node(current_procinfo.safe_procdef);
                consume(_ID);
                again:=true;
              end
Index: nutils.pas
===================================================================
--- nutils.pas	(revision 16490)
+++ nutils.pas	(working copy)
@@ -27,7 +27,7 @@
 
   uses
     globtype,constexp,
-    symtype,symsym,symbase,symtable,
+    symtype,symdef,symsym,symbase,symtable,
     node;
 
   const
@@ -66,13 +66,13 @@
     function maybe_call_procvar(var p1:tnode;tponly:boolean):boolean;
     function get_high_value_sym(vs: tparavarsym):tsym; { marking it as inline causes IE 200311075 during loading from ppu file }
     function load_high_value_node(vs:tparavarsym):tnode;
-    function load_self_node:tnode;
-    function load_result_node:tnode;
-    function load_self_pointer_node:tnode;
-    function load_vmt_pointer_node:tnode;
+    function load_self_node(contextpd:tprocdef):tnode;
+    function load_result_node(contextpd:tprocdef):tnode;
+    function load_self_pointer_node(contextpd:tprocdef):tnode;
+    function load_vmt_pointer_node(contextpd:tprocdef):tnode;
     function is_self_node(p:tnode):boolean;
 
-    function call_fail_node:tnode;
+    function call_fail_node(contextpd:tprocdef):tnode;
     function initialize_data_node(p:tnode):tnode;
     function finalize_data_node(p:tnode):tnode;
 
@@ -114,7 +114,7 @@
 
     uses
       cutils,verbose,globals,
-      symconst,symdef,
+      symconst,
       defutil,defcmp,
       nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
       cpubase,cgbase,procinfo,
@@ -397,18 +397,16 @@
       end;
 
 
-    function get_local_or_para_sym(const aname:string):tsym;
-      var
-        pd : tprocdef;
+    { pd: the procdefinition in whose context 'aname' has to be searched }
+    function get_local_or_para_sym(pd: tprocdef; const aname:string):tsym;
       begin
         result:=nil;
         { is not assigned while parsing a property }
-        if not assigned(current_procinfo) then
+        if not assigned(pd) then
           exit;
         { we can't use searchsym here, because the
           symtablestack is not fully setup when pass1
           is run for nested procedures }
-        pd:=current_procinfo.procdef;
         repeat
           result := tsym(pd.localst.Find(aname));
           if assigned(result) then
@@ -442,13 +440,13 @@
       end;
 
 
-    function load_self_node:tnode;
+    function load_self_node(contextpd:tprocdef):tnode;
       var
         srsym : tsym;
       begin
         result:=nil;
 
-        srsym:=get_local_or_para_sym('self');
+        srsym:=get_local_or_para_sym(contextpd,'self');
         if assigned(srsym) then
           begin
             result:=cloadnode.create(srsym,srsym.owner);
@@ -463,12 +461,12 @@
       end;
 
 
-    function load_result_node:tnode;
+    function load_result_node(contextpd:tprocdef):tnode;
       var
         srsym : tsym;
       begin
         result:=nil;
-        srsym:=get_local_or_para_sym('result');
+        srsym:=get_local_or_para_sym(contextpd,'result');
         if assigned(srsym) then
           result:=cloadnode.create(srsym,srsym.owner)
         else
@@ -480,12 +478,12 @@
       end;
 
 
-    function load_self_pointer_node:tnode;
+    function load_self_pointer_node(contextpd:tprocdef):tnode;
       var
         srsym : tsym;
       begin
         result:=nil;
-        srsym:=get_local_or_para_sym('self');
+        srsym:=get_local_or_para_sym(contextpd,'self');
         if assigned(srsym) then
           begin
             result:=cloadnode.create(srsym,srsym.owner);
@@ -500,12 +498,12 @@
       end;
 
 
-    function load_vmt_pointer_node:tnode;
+    function load_vmt_pointer_node(contextpd: tprocdef):tnode;
       var
         srsym : tsym;
       begin
         result:=nil;
-        srsym:=get_local_or_para_sym('vmt');
+        srsym:=get_local_or_para_sym(contextpd,'vmt');
         if assigned(srsym) then
           result:=cloadnode.create(srsym,srsym.owner)
         else
@@ -525,7 +523,7 @@
       end;
 
 
-    function call_fail_node:tnode;
+    function call_fail_node(contextpd: tprocdef):tnode;
       var
         para : tcallparanode;
         newstatement : tstatementnode;
@@ -544,12 +542,12 @@
                 addstatement(newstatement,cifnode.create(
                     caddnode.create(andn,
                         caddnode.create(unequaln,
-                            load_self_pointer_node,
+                            load_self_pointer_node(contextpd),
                             cnilnode.create),
                         caddnode.create(unequaln,
-                            load_vmt_pointer_node,
+                            load_vmt_pointer_node(contextpd),
                             cnilnode.create)),
-                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.safe_procdef),[]),
                     nil));
               end
             else
@@ -565,11 +563,11 @@
                         cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                     ccallparanode.create(
                         ctypeconvnode.create_internal(
-                            load_vmt_pointer_node,
+                            load_vmt_pointer_node(contextpd),
                             voidpointertype),
                     ccallparanode.create(
                         ctypeconvnode.create_internal(
-                            load_self_pointer_node,
+                            load_self_pointer_node(contextpd),
                             voidpointertype),
                     nil)));
               addstatement(newstatement,
@@ -579,7 +577,7 @@
           internalerror(200305132);
         { self:=nil }
         addstatement(newstatement,cassignmentnode.create(
-            load_self_pointer_node,
+            load_self_pointer_node(contextpd),
             cnilnode.create));
         { exit }
         addstatement(newstatement,cexitnode.create(nil));
@@ -1069,7 +1067,7 @@
                       withsymtable :
                         p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                       ObjectSymtable :
-                        p1:=load_self_node;
+                        p1:=load_self_node(current_procinfo.safe_procdef);
                     end;
                   end;
                  if assigned(p1) then
Index: pstatmnt.pas
===================================================================
--- pstatmnt.pas	(revision 16490)
+++ pstatmnt.pas	(working copy)
@@ -1100,7 +1100,7 @@
                 if (current_procinfo.procdef.proctypeoption<>potype_constructor) then
                   Message(parser_e_fail_only_in_constructor);
                 consume(_FAIL);
-                code:=call_fail_node;
+                code:=call_fail_node(current_procinfo.procdef);
              end;
            _ASM :
              code:=_asm_statement;
Index: ncal.pas
===================================================================
--- ncal.pas	(revision 16490)
+++ ncal.pas	(working copy)
@@ -116,6 +116,11 @@
           funcretnode    : tnode;
           { varargs parasyms }
           varargsparas : tvarargsparalist;
+          { procdef of the routine in which this call is performed, to
+            properly resolve "inherited" and other self-based references
+            when e.g. inlining }
+          contextpd      : tprocdef;
+          contextpdderef : tderef;
 
           { separately specified resultdef for some compilerprocs (e.g. }
           { you can't have a function with an "array of char" resultdef }
@@ -1012,6 +1017,10 @@
          funcretnode:=nil;
          paralength:=-1;
          varargsparas:=nil;
+         if assigned(current_procinfo) then
+           contextpd:=current_procinfo.procdef
+         else
+           contextpd:=nil;
       end;
 
 
@@ -1028,6 +1037,10 @@
          funcretnode:=nil;
          paralength:=-1;
          varargsparas:=nil;
+         if assigned(current_procinfo) then
+           contextpd:=current_procinfo.procdef
+         else
+           contextpd:=nil;
       end;
 
 
@@ -1122,6 +1135,7 @@
         symtableproc:=nil;
         ppufile.getderef(procdefinitionderef);
         ppufile.getsmallset(callnodeflags);
+        ppufile.getderef(contextpdderef);
       end;
 
 
@@ -1135,6 +1149,7 @@
         ppufile.putderef(symtableprocentryderef);
         ppufile.putderef(procdefinitionderef);
         ppufile.putsmallset(callnodeflags);
+        ppufile.putderef(contextpdderef);
       end;
 
 
@@ -1143,6 +1158,7 @@
         inherited buildderefimpl;
         symtableprocentryderef.build(symtableprocentry);
         procdefinitionderef.build(procdefinition);
+        contextpdderef.build(contextpd);
         if assigned(methodpointer) then
           methodpointer.buildderefimpl;
         if assigned(callinitblock) then
@@ -1164,6 +1180,7 @@
         if assigned(symtableprocentry) then
           symtableproc:=symtableprocentry.owner;
         procdefinition:=tabstractprocdef(procdefinitionderef.resolve);
+        contextpd:=tprocdef(contextpdderef.resolve);
         if assigned(methodpointer) then
           methodpointer.derefimpl;
         if assigned(callinitblock) then
@@ -1242,6 +1259,7 @@
          end
         else
          n.varargsparas:=nil;
+        n.contextpd:=contextpd;
         result:=n;
       end;
 
@@ -1255,7 +1273,12 @@
           (methodpointer.isequal(tcallnode(p).methodpointer)) and
           (((cnf_typedefset in callnodeflags) and (cnf_typedefset in tcallnode(p).callnodeflags) and
             (equal_defs(typedef,tcallnode(p).typedef))) or
-           (not(cnf_typedefset in callnodeflags) and not(cnf_typedefset in tcallnode(p).callnodeflags)));
+           (not(cnf_typedefset in callnodeflags) and not(cnf_typedefset in tcallnode(p).callnodeflags))) and
+          { only has to be equal for call nodes that actually use the contextpd,
+            but there's no way to determine that in a non-fragile way and we
+            currently probably never optimise away duplicate callnodes anyway
+            since we have no side-effect tracking }
+          (tcallnode(p).contextpd=contextpd);
       end;
 
 
@@ -1640,7 +1663,7 @@
         { inherited }
         else if (cnf_inherited in callnodeflags) then
           begin
-            selftree:=load_self_node;
+            selftree:=load_self_node(contextpd);
            { we can call an inherited class static/method from a regular method
              -> self node must change from instance pointer to vmt pointer)
            }
@@ -1659,7 +1682,7 @@
               else
                 begin
                   if methodpointer.nodetype=typen then
-                    selftree:=load_self_node
+                    selftree:=load_self_node(contextpd)
                   else
                     selftree:=methodpointer.getcopy;
                 end;
@@ -1687,7 +1710,7 @@
         else
           begin
             if methodpointer.nodetype=typen then
-              selftree:=load_self_node
+              selftree:=load_self_node(contextpd)
             else
               selftree:=methodpointer.getcopy;
           end;
@@ -1904,11 +1927,11 @@
              objcsupertype:=search_named_unit_globaltype('OBJC','OBJC_SUPER',true).typedef;
              if (objcsupertype.typ<>recorddef) then
                internalerror(2009032901);
-             { temp for the for the objc_super record }
+             { temp for the objc_super record }
              temp:=ctempcreatenode.create(objcsupertype,objcsupertype.size,tt_persistent,false);
              addstatement(statements,temp);
              { initialize objc_super record }
-             selftree:=load_self_node;
+             selftree:=load_self_node(contextpd);
 
              { we can call an inherited class static/method from a regular method
                -> self node must change from instance pointer to vmt pointer)
Index: ppu.pas
===================================================================
--- ppu.pas	(revision 16490)
+++ ppu.pas	(working copy)
@@ -43,7 +43,7 @@
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 121;
+  CurrentPPUVersion = 122;
 
 { buffer sizes }
   maxentrysize = 1024;
Index: ncnv.pas
===================================================================
--- ncnv.pas	(revision 16490)
+++ ncnv.pas	(working copy)
@@ -1834,7 +1834,7 @@
                            if assigned(tcallnode(left).methodpointer) then
                              tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
                            else
-                             tloadnode(hp).set_mp(load_self_node);
+                             tloadnode(hp).set_mp(load_self_node(current_procinfo.safe_procdef));
                          end;
                         typecheckpass(hp);
                       end;
Index: psub.pas
===================================================================
--- psub.pas	(revision 16490)
+++ psub.pas	(working copy)
@@ -306,14 +306,14 @@
                         addstatement(newstatement,cifnode.create(
                             caddnode.create(gtn,
                                 ctypeconvnode.create_internal(
-                                    load_vmt_pointer_node,
+                                    load_vmt_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
                                 cpointerconstnode.create(1,voidpointertype)),
                             cassignmentnode.create(
                                 ctypeconvnode.create_internal(
-                                    load_self_pointer_node,
+                                    load_self_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
-                                ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_vmt_pointer_node,[])),
+                                ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_vmt_pointer_node(current_procinfo.procdef),[])),
                             nil));
                       end
                     else
@@ -331,16 +331,16 @@
                                 cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                             ccallparanode.create(
                                 ctypeconvnode.create_internal(
-                                    load_vmt_pointer_node,
+                                    load_vmt_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
                             ccallparanode.create(
                                 ctypeconvnode.create_internal(
-                                    load_self_pointer_node,
+                                    load_self_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
                             nil)));
                       addstatement(newstatement,cassignmentnode.create(
                           ctypeconvnode.create_internal(
-                              load_self_pointer_node,
+                              load_self_pointer_node(current_procinfo.procdef),
                               voidpointertype),
                           ccallnode.createintern('fpc_help_constructor',para)));
                     end
@@ -351,7 +351,7 @@
                   there is nothing to dispose (PFV) }
                 addstatement(newstatement,cifnode.create(
                     caddnode.create(equaln,
-                        load_self_pointer_node,
+                        load_self_pointer_node(current_procinfo.procdef),
                         cnilnode.create),
                     cexitnode.create(nil),
                     nil));
@@ -369,10 +369,10 @@
                     addstatement(newstatement,cifnode.create(
                         caddnode.create(gtn,
                             ctypeconvnode.create_internal(
-                              load_vmt_pointer_node,ptrsinttype),
+                              load_vmt_pointer_node(current_procinfo.procdef),ptrsinttype),
                             ctypeconvnode.create_internal(
                               cnilnode.create,ptrsinttype)),
-                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                         nil));
                   end
                 else
@@ -416,14 +416,14 @@
                         addstatement(newstatement,cifnode.create(
                             caddnode.create(andn,
                                 caddnode.create(unequaln,
-                                    load_self_pointer_node,
+                                    load_self_pointer_node(current_procinfo.procdef),
                                     cnilnode.create),
                                 caddnode.create(unequaln,
                                     ctypeconvnode.create(
-                                        load_vmt_pointer_node,
+                                        load_vmt_pointer_node(current_procinfo.procdef),
                                         voidpointertype),
                                     cpointerconstnode.create(0,voidpointertype))),
-                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                             nil));
                       end
                     else
@@ -434,7 +434,7 @@
                     begin
                       { finalize object data }
                       if is_managed_type(current_objectdef) then
-                        addstatement(newstatement,finalize_data_node(load_self_node));
+                        addstatement(newstatement,finalize_data_node(load_self_node(current_procinfo.procdef)));
                       { parameter 3 : vmt_offset }
                       { parameter 2 : pointer to vmt }
                       { parameter 1 : self pointer }
@@ -442,11 +442,11 @@
                                 cordconstnode.create(current_objectdef.vmt_offset,s32inttype,false),
                             ccallparanode.create(
                                 ctypeconvnode.create_internal(
-                                    load_vmt_pointer_node,
+                                    load_vmt_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
                             ccallparanode.create(
                                 ctypeconvnode.create_internal(
-                                    load_self_pointer_node,
+                                    load_self_pointer_node(current_procinfo.procdef),
                                     voidpointertype),
                             nil)));
                       addstatement(newstatement,
@@ -480,7 +480,7 @@
                is_managed_type(current_procinfo.procdef.returndef) and
                (not paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption)) and
                (not is_class(current_procinfo.procdef.returndef)) then
-              addstatement(newstatement,finalize_data_node(load_result_node));
+              addstatement(newstatement,finalize_data_node(load_result_node(current_procinfo.procdef)));
 {$if defined(x86) or defined(arm)}
             { safecall handling }
             if (tf_safecall_exceptions in target_info.flags) and
@@ -520,7 +520,7 @@
                         ccallnode.create(
                           ccallparanode.create(ctemprefnode.create(exceptaddrnode),
                           ccallparanode.create(ctemprefnode.create(exceptobjnode),nil)),
-                          tprocsym(exceptsym), tprocsym(exceptsym).owner,load_self_node,[])));
+                          tprocsym(exceptsym), tprocsym(exceptsym).owner,load_self_node(current_procinfo.procdef),[])));
                     addstatement(newstatement,ccallnode.createintern('fpc_destroyexception',
                       ccallparanode.create(ctemprefnode.create(exceptobjnode),nil)));
                     addstatement(newstatement,ctempdeletenode.create(exceptobjnode));
@@ -621,12 +621,12 @@
                     addstatement(newstatement,cifnode.create(
                       caddnode.create(andn,
                         caddnode.create(unequaln,
-                          load_self_node,
+                          load_self_node(current_procinfo.procdef),
                           cnilnode.create),
                         caddnode.create(unequaln,
-                          load_vmt_pointer_node,
+                          load_vmt_pointer_node(current_procinfo.procdef),
                           cnilnode.create)),
-                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node(current_procinfo.procdef),[]),
                         nil));
                     tocode:=afterconstructionblock;
                   end
@@ -649,10 +649,10 @@
                     { if vmt<>0 then call destructor }
                     addstatement(newstatement,cifnode.create(
                       caddnode.create(unequaln,
-                        load_vmt_pointer_node,
+                        load_vmt_pointer_node(current_procinfo.procdef),
                         cnilnode.create),
                       { cnf_create_failed -> don't call BeforeDestruction }
-                      ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node,[cnf_create_failed]),
+                      ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node(current_procinfo.procdef),[cnf_create_failed]),
                       nil));
                     { then re-raise the exception }
                     addstatement(newstatement,craisenode.create(nil,nil,nil));
Index: optdfa.pas
===================================================================
--- optdfa.pas	(revision 16490)
+++ optdfa.pas	(working copy)
@@ -556,7 +556,7 @@
           not(current_procinfo.procdef.proctypeoption=potype_constructor) then
           begin
             { create a fake node using the result }
-            resultnode:=load_result_node;
+            resultnode:=load_result_node(current_procinfo.procdef);
             resultnode.allocoptinfo;
             dfarec.use:=@resultnode.optinfo^.use;
             dfarec.def:=@resultnode.optinfo^.def;
callcontext.patch (25,960 bytes)

2010-12-01 15:51

 

tw18121.pp (191 bytes)

2010-12-01 15:51

 

uw18121.pp (814 bytes)

Jonas Maebe

2010-12-01 15:54

manager   ~0043855

The patch itself is also not 100% safe: the contextpd field should be passed explicitly to the node constructor instead of being read from current_procinfo.procdef, since it's possible that a new (call) node is created while typechecking/firstpassing another node (at which point current_procinfo.procdef may not be actually required procdef, just like in the case of this bug report).

Paul Ishenin

2010-12-04 12:32

developer   ~0043976

Will you create a 100% safe patch?

Jonas Maebe

2010-12-06 13:11

manager   ~0044040

> Will you create a 100% safe patch?

Not in the near future.

Giel

2010-12-09 15:38

reporter   ~0044125

Interestingly inlined methods which call "inherited" do compile in my project for some reason. They cause access violations at runtime.

When I try to narrow it down to a nice test case the compiler does show illegal expression errors, just like this bug describes.

Jonas Maebe

2010-12-09 15:43

manager   ~0044126

Last edited: 2010-12-09 15:44

It can compile by accident if you call such an inlined method inside another method for which an inherited version is available. The result will however indeed be invalid code in most cases.

Sven Barth

2014-07-05 10:35

manager   ~0076077

@Jonas: Maybe it would indeed be better to have a contextpd field for each node so that we can be sure to know where the node came from...

Regards,
Sven

Issue History

Date Modified Username Field Change
2010-12-01 10:57 Paul Ishenin New Issue
2010-12-01 10:57 Paul Ishenin File Added: project1.lpr
2010-12-01 10:57 Paul Ishenin FPCOldBugId => 0
2010-12-01 10:58 Paul Ishenin Relationship added related to 0016582
2010-12-01 10:58 Paul Ishenin Note Added: 0043835
2010-12-01 15:50 Jonas Maebe Note Added: 0043854
2010-12-01 15:50 Jonas Maebe File Added: callcontext.patch
2010-12-01 15:51 Jonas Maebe File Added: tw18121.pp
2010-12-01 15:51 Jonas Maebe File Added: uw18121.pp
2010-12-01 15:54 Jonas Maebe Note Added: 0043855
2010-12-04 12:32 Paul Ishenin Note Added: 0043976
2010-12-06 13:11 Jonas Maebe Note Added: 0044040
2010-12-09 15:38 Giel Note Added: 0044125
2010-12-09 15:43 Jonas Maebe Note Added: 0044126
2010-12-09 15:44 Jonas Maebe Note Edited: 0044126
2011-02-23 11:48 Jonas Maebe Relationship added has duplicate 0018776
2011-03-24 20:13 Jonas Maebe Relationship added has duplicate 0018984
2012-04-12 11:12 Jonas Maebe Relationship added has duplicate 0021719
2013-09-05 14:24 Jonas Maebe Note Edited: 0043854 View Revisions
2014-06-26 20:34 Jonas Maebe Relationship added has duplicate 0026397
2014-07-05 10:35 Sven Barth Note Added: 0076077
2015-05-25 14:57 Jonas Maebe Fixed in Revision => 30908
2015-05-25 14:57 Jonas Maebe Status new => resolved
2015-05-25 14:57 Jonas Maebe Fixed in Version => 3.1.1
2015-05-25 14:57 Jonas Maebe Resolution open => fixed
2015-05-25 14:57 Jonas Maebe Assigned To => Jonas Maebe