diff --git a/compiler/globtype.pas b/compiler/globtype.pas index df126f5dde..f486d962e1 100644 --- a/compiler/globtype.pas +++ b/compiler/globtype.pas @@ -236,7 +236,9 @@ than 255 characters. That's why using Ansi Strings} { procedure uses fpu} pi_uses_fpu, { procedure uses GOT for PIC code } - pi_needs_got + pi_needs_got, + { references local var/proc } + pi_inline_local_only ); tprocinfoflags=set of tprocinfoflag; @@ -313,7 +315,11 @@ implementation end. { $Log$ - Revision 1.64 2004-10-31 21:45:03 peter + Revision 1.65 2004-12-15 21:08:15 peter + * disable inlining across units when the inline procedure references + a variable or procedure in the static symtable + + Revision 1.64 2004/10/31 21:45:03 peter * generic tlocation * move tlocation to cgutils diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 811fc4dfb4..eaf9a2bf9e 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -2119,6 +2119,8 @@ type function tcallnode.pass_1 : tnode; + var + st : tsymtable; begin result:=nil; @@ -2126,8 +2128,21 @@ type if (procdefinition.proccalloption=pocall_inline) and (po_has_inlininginfo in procdefinition.procoptions) then begin - result:=pass1_inline; - exit; + { Check if we can inline the procedure when it references proc/var that + are not in the globally available } + st:=procdefinition.owner; + if (st.symtabletype=objectsymtable) then + st:=st.defowner.owner; + if (pi_inline_local_only in tprocdef(procdefinition).inlininginfo^.flags) and + (st.unitid<>0) then + begin + Comment(V_lineinfo+V_Debug,'Not inlining "'+tprocdef(procdefinition).procsym.realname+'", references static symtable'); + end + else + begin + result:=pass1_inline; + exit; + end; end; { calculate the parameter info for the procdef } @@ -2434,7 +2449,11 @@ begin end. { $Log$ - Revision 1.270 2004-12-15 19:30:16 peter + Revision 1.271 2004-12-15 21:08:15 peter + * disable inlining across units when the inline procedure references + a variable or procedure in the static symtable + + Revision 1.270 2004/12/15 19:30:16 peter * give error when paraloc is not filled in order_parameter Revision 1.269 2004/12/07 16:11:52 peter diff --git a/compiler/psub.pas b/compiler/psub.pas index 8ef39dfa4b..dd007609fc 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -959,6 +959,20 @@ implementation end; + function checklocalinlining(var n: tnode; arg: pointer): foreachnoderesult; + begin + result:=fen_false; + case n.nodetype of + loadn : + if tloadnode(n).symtableentry.owner.symtabletype=staticsymtable then + result:=fen_norecurse_true; + calln : + if tcallnode(n).procdefinition.owner.symtabletype=staticsymtable then + result:=fen_norecurse_true; + end; + end; + + procedure tcgprocinfo.parse_body; var oldprocinfo : tprocinfo; @@ -1046,6 +1060,10 @@ implementation include(procdef.procoptions,po_has_inlininginfo); procdef.inlininginfo^.code:=code.getcopy; procdef.inlininginfo^.flags:=current_procinfo.flags; + { References a local var or proc? } + if foreachnodestatic(procdef.inlininginfo^.code,@checklocalinlining,nil) then + include(procdef.inlininginfo^.flags,pi_inline_local_only); + { The blocknode needs to set an exit label } if procdef.inlininginfo^.code.nodetype=blockn then include(procdef.inlininginfo^.code.flags,nf_block_with_exit); end; @@ -1446,7 +1464,11 @@ implementation end. { $Log$ - Revision 1.224 2004-12-15 17:01:28 peter + Revision 1.225 2004-12-15 21:08:15 peter + * disable inlining across units when the inline procedure references + a variable or procedure in the static symtable + + Revision 1.224 2004/12/15 17:01:28 peter * fixed crash with -vp Revision 1.223 2004/12/15 16:00:16 peter