Parcourir la source

Merged revisions 1913-1914,1920,1922,1925,1957,1976,2024,2038,2052,2126,2140 via svnmerge from
http://[email protected]/svn/fpc/trunk

........
r1913 | jonas | 2005-12-10 17:51:26 +0100 (Sat, 10 Dec 2005) | 6 lines

* new categories for vs_*: vs_declared, vs_initialised, vs_read,
vs_written, vs_readwritten. vs_initialised is the old vs_assigned;
vs_used has been replaced by vs_read, vs_written and vs_readwritten
* the valid_for_*() routines in htypechk now get an extra parameter to
decide whether or not errors should be reported

........
r1914 | jonas | 2005-12-10 18:01:07 +0100 (Sat, 10 Dec 2005) | 6 lines

* use more precise vs_* information to replace less parameters of inlined
procedures with const and value parameters with temps, allowing a bit
more value propagation
+ tinline6.pp for testing wrong propagation of value parameters in
dangerous situations

........
r1920 | florian | 2005-12-10 22:00:37 +0100 (Sat, 10 Dec 2005) | 2 lines

* fixed generation of exports from units/programs supporting it

........
r1922 | florian | 2005-12-10 23:00:33 +0100 (Sat, 10 Dec 2005) | 2 lines

* exports info handling refactored, -E will be passed to ld if necessary

........
r1925 | florian | 2005-12-10 23:06:10 +0100 (Sat, 10 Dec 2005) | 3 lines

* -s renamed to -S (build static lib)
* -s is now strip

........
r1957 | peter | 2005-12-15 13:04:39 +0100 (Thu, 15 Dec 2005) | 2 lines

* fix win32 linking

........
r1976 | jonas | 2005-12-17 16:20:33 +0100 (Sat, 17 Dec 2005) | 2 lines

* indexes in vecn's are only read, not written

........
r2024 | florian | 2005-12-22 08:40:28 +0100 (Thu, 22 Dec 2005) | 2 lines

+ compiled and added

........
r2038 | jonas | 2005-12-23 22:08:48 +0100 (Fri, 23 Dec 2005) | 6 lines

* fixed tw4554:
* proper uninitialized checking for arrays
* first check uninitialized status of right side of assignment
before setting the left side to "written" (-> catch "x:=x" if
x is uninitialized)

........
r2052 | jonas | 2005-12-26 15:44:03 +0100 (Mon, 26 Dec 2005) | 3 lines

* also honour vsf_use_hints for uninitialised warnings for the
function result variable

........
r2126 | florian | 2006-01-02 19:35:01 +0100 (Mon, 02 Jan 2006) | 2 lines

* proper setting of symbol sizes and types

........
r2140 | jonas | 2006-01-03 16:37:49 +0100 (Tue, 03 Jan 2006) | 6 lines

* never make vs_var or vs_out variabled non-regable, unless it's an
access from a nested procedure. This allows keeping the address
of large function results like shortstrings in a register,
because they were always made non-regable by a typeconversionnode
due to the fact that they are aliased by an absolute alias.

........

git-svn-id: branches/fixes_2_0@2250 -

peter il y a 19 ans
Parent
commit
9759c14244

+ 3 - 0
.gitattributes

@@ -5114,6 +5114,8 @@ tests/test/cg/obj/linux/powerpc64/tcext3.o -text
 tests/test/cg/obj/linux/powerpc64/tcext4.o -text
 tests/test/cg/obj/linux/sparc/ctest.o -text
 tests/test/cg/obj/linux/x86_64/ctest.o -text
+tests/test/cg/obj/linux/x86_64/tcext3.o -text
+tests/test/cg/obj/linux/x86_64/tcext4.o -text
 tests/test/cg/obj/macos/powerpc/ctest.o -text
 tests/test/cg/obj/netbsd/m68k/ctest.o -text
 tests/test/cg/obj/os2/i386/ctest.o -text
@@ -5330,6 +5332,7 @@ tests/test/tinline2.pp svneol=native#text/plain
 tests/test/tinline3.pp svneol=native#text/plain
 tests/test/tinline4.pp svneol=native#text/plain
 tests/test/tinline5.pp -text
+tests/test/tinline6.pp svneol=native#text/plain
 tests/test/tint641.pp svneol=native#text/plain
 tests/test/tint642.pp svneol=native#text/plain
 tests/test/tint643.pp svneol=native#text/plain

+ 5 - 5
compiler/alpha/radirect.pas

@@ -80,7 +80,7 @@ interface
             { consider it set function set if the offset was loaded }
            if assigned(aktprocdef.funcretsym) and
               (pos(retstr,upper(s))>0) then
-             tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+             tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
            s:='';
          end;
 
@@ -89,7 +89,7 @@ interface
        s:='';
        if assigned(aktprocdef.funcretsym) and
           is_fpu(aktprocdef.rettype.def) then
-         tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+         tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
        { !!!!!
        if (not is_void(aktprocdef.rettype.def)) then
          retstr:=upper(tostr(procinfo^.return_offset)+'('+gas_reg2str[procinfo^.framepointer]+')')
@@ -149,7 +149,7 @@ interface
                                    ret_in_acc(aktprocdef.rettype.def) and
                                    ((pos('AX',upper(hs))>0) or
                                    (pos('AL',upper(hs))>0)) then
-                                  tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+                                  tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
                                 }
                                 if ((s[length(s)]<>'0') or (hs[1]<>'x')) then
                                   begin
@@ -197,7 +197,7 @@ interface
                                                     inc(l,aktprocdef.parast.address_fixup);
                                                     hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer]+')';
                                                     if pos(',',s) > 0 then
-                                                      tvarsym(sym).varstate:=vs_used;
+                                                      tvarsym(sym).varstate:=vs_readwritten;
                                                  end;
                                             end
                                           { I added that but it creates a problem in line.ppi
@@ -277,7 +277,7 @@ interface
               '{',';',#10,#13:
                 begin
                    if pos(retstr,s) > 0 then
-                     tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
+                     tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_initialised;
                    writeasmline;
                    c:=current_scanner.asmgetchar;
                 end;

+ 96 - 45
compiler/htypechk.pas

@@ -141,11 +141,11 @@ interface
     { takes care of type casts etc.                 }
     procedure set_unique(p : tnode);
 
-    function  valid_for_formal_var(p : tnode) : boolean;
-    function  valid_for_formal_const(p : tnode) : boolean;
-    function  valid_for_var(p:tnode):boolean;
-    function  valid_for_assignment(p:tnode):boolean;
-    function  valid_for_addr(p : tnode) : boolean;
+    function  valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
+    function  valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
+    function  valid_for_var(p:tnode; report_errors: boolean):boolean;
+    function  valid_for_assignment(p:tnode; report_errors: boolean):boolean;
+    function  valid_for_addr(p : tnode; report_errors: boolean) : boolean;
 
 
 implementation
@@ -642,7 +642,11 @@ implementation
             typeconvn :
               make_not_regable(ttypeconvnode(p).left);
             loadn :
-              if tloadnode(p).symtableentry.typ in [globalvarsym,localvarsym,paravarsym] then
+              if (tloadnode(p).symtableentry.typ in [globalvarsym,localvarsym]) or
+                 ((tloadnode(p).symtableentry.typ = paravarsym) and
+                  { not a nested variable }
+                  (assigned(tloadnode(p).left) or
+                   not(tparavarsym(tloadnode(p).symtableentry).varspez in [vs_var,vs_out]))) then
                 tabstractvarsym(tloadnode(p).symtableentry).varregable:=vr_none;
          end;
       end;
@@ -734,6 +738,20 @@ implementation
 
 
     procedure set_varstate(p:tnode;newstate:tvarstate;varstateflags:tvarstateflags);
+      const
+        vstrans: array[tvarstate,tvarstate] of tvarstate = (
+          { vs_none -> ... }
+          (vs_none,vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_declared -> ... }
+          (vs_none,vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_initialised -> ... }
+          (vs_none,vs_initialised,vs_initialised,vs_read,vs_written,vs_readwritten),
+          { vs_read -> ... }
+          (vs_none,vs_read,vs_read,vs_read,vs_readwritten,vs_readwritten),
+          { vs_written -> ... }
+          (vs_none,vs_written,vs_written,vs_readwritten,vs_written,vs_readwritten),
+          { vs_readwritten -> ... }
+          (vs_none,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten,vs_readwritten));
       var
         hsym : tabstractvarsym;
       begin
@@ -757,9 +775,12 @@ implementation
                p:=tunarynode(p).left;
              vecn:
                begin
-                 set_varstate(tbinarynode(p).right,vs_used,[vsf_must_be_valid]);
-                 if not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then
-                   include(varstateflags,vsf_must_be_valid);
+                 set_varstate(tbinarynode(p).right,vs_read,[vsf_must_be_valid]);
+                 if (newstate in [vs_read,vs_readwritten]) or
+                    not(tunarynode(p).left.resulttype.def.deftype in [stringdef,arraydef]) then
+                   include(varstateflags,vsf_must_be_valid)
+                 else if (newstate = vs_written) then
+                   exclude(varstateflags,vsf_must_be_valid);
                  p:=tunarynode(p).left;
                end;
              { do not parse calln }
@@ -780,7 +801,12 @@ implementation
                             (vo_is_funcret in hsym.varoptions)) then
                           begin
                             if (vo_is_funcret in hsym.varoptions) then
-                               CGMessage(sym_w_function_result_not_set)
+                              begin
+                                if (vsf_use_hints in varstateflags) then
+                                  CGMessage(sym_h_function_result_uninitialized)
+                                else
+                                  CGMessage(sym_w_function_result_uninitialized)
+                              end
                             else
                               begin
                                 if tloadnode(p).symtable.symtabletype=localsymtable then
@@ -800,9 +826,8 @@ implementation
                               end;
                           end;
                       end;
-                    { don't override vs_used with vs_assigned }
-                    if hsym.varstate<>vs_used then
-                      hsym.varstate:=newstate;
+                    { don't override vs_readwritten with vs_initialised }
+                    hsym.varstate := vstrans[hsym.varstate,newstate];
                   end;
                  break;
                end;
@@ -836,7 +861,7 @@ implementation
       end;
 
 
-    function  valid_for_assign(p:tnode;opts:TValidAssigns):boolean;
+    function  valid_for_assign(p:tnode;opts:TValidAssigns; report_errors: boolean):boolean;
       var
         hp : tnode;
         gotstring,
@@ -870,7 +895,8 @@ implementation
         if not(valid_void in opts) and
            is_void(hp.resulttype.def) then
          begin
-           CGMessagePos(hp.fileinfo,errmsg);
+           if report_errors then
+             CGMessagePos(hp.fileinfo,errmsg);
            exit;
          end;
         while assigned(hp) do
@@ -905,7 +931,8 @@ implementation
                             ) then
                         result:=true
                       else
-                        CGMessagePos(hp.fileinfo,errmsg);
+                        if report_errors then
+                          CGMessagePos(hp.fileinfo,errmsg);
                     end
                   else
                     begin
@@ -927,7 +954,8 @@ implementation
                          ) then
                         result:=true
                       else
-                        CGMessagePos(hp.fileinfo,errmsg);
+                        if report_errors then
+                          CGMessagePos(hp.fileinfo,errmsg);
                     end;
                 end
               else
@@ -976,13 +1004,15 @@ implementation
                        (todef.size<fromdef.size) then
                       make_not_regable(hp)
                     else
-                      CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
+                      if report_errors then
+                        CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
                   end;
                  { don't allow assignments to typeconvs that need special code }
                  if not(gotsubscript or gotvec or gotderef) and
                     not(ttypeconvnode(hp).assign_allowed) then
                    begin
-                     CGMessagePos(hp.fileinfo,errmsg);
+                     if report_errors then
+                       CGMessagePos(hp.fileinfo,errmsg);
                      exit;
                    end;
                  case hp.resulttype.def.deftype of
@@ -1016,7 +1046,8 @@ implementation
                    of reference. }
                  if not(gotsubscript or gotderef or gotvec) then
                    begin
-                     CGMessagePos(hp.fileinfo,errmsg);
+                     if report_errors then
+                       CGMessagePos(hp.fileinfo,errmsg);
                      exit;
                    end;
                  hp:=tunarynode(hp).left;
@@ -1027,7 +1058,12 @@ implementation
                  { loop counter? }
                  if not(Valid_Const in opts) and
                     (vo_is_loop_counter in tsubscriptnode(hp).vs.varoptions) then
-                   CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname);
+                   begin
+                     if report_errors then
+                       CGMessage1(parser_e_illegal_assignment_to_count_var,tsubscriptnode(hp).vs.realname)
+                     else
+                       exit;
+                   end;                     
                  { a class/interface access is an implicit }
                  { dereferencing                           }
                  hp:=tsubscriptnode(hp).left;
@@ -1058,7 +1094,8 @@ implementation
                       (hp.resulttype.def.deftype=stringdef) then
                      result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
              niln,
@@ -1068,7 +1105,8 @@ implementation
                  if gotderef then
                   result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
                  exit;
                end;
              addrn :
@@ -1076,7 +1114,8 @@ implementation
                  if gotderef then
                   result:=true
                  else
-                  CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,type_e_no_assign_to_addr);
                  exit;
                end;
              calln :
@@ -1122,7 +1161,8 @@ implementation
                    if ([valid_const,valid_addr] * opts = [valid_const]) then
                      result:=true
                  else
-                  CGMessagePos(hp.fileinfo,errmsg);
+                  if report_errors then
+                   CGMessagePos(hp.fileinfo,errmsg);
                  exit;
                end;
              inlinen :
@@ -1131,7 +1171,8 @@ implementation
                     (tinlinenode(hp).inlinenumber in [in_typeof_x]) then
                    result:=true
                  else
-                   CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                   if report_errors then
+                    CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
              loadn :
@@ -1146,7 +1187,10 @@ implementation
                        if not(Valid_Const in opts) and
                           not gotderef and
                           (vo_is_loop_counter in tabstractvarsym(tloadnode(hp).symtableentry).varoptions) then
-                         CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname);
+                         if report_errors then
+                          CGMessage1(parser_e_illegal_assignment_to_count_var,tloadnode(hp).symtableentry.realname)
+                         else
+                          exit;
                        { derefed pointer }
                        if (tabstractvarsym(tloadnode(hp).symtableentry).varspez=vs_const) then
                         begin
@@ -1154,7 +1198,8 @@ implementation
                           if gotderef or gotdynarray or (Valid_Const in opts) then
                            result:=true
                           else
-                           CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
+                           if report_errors then
+                            CGMessagePos(tloadnode(hp).fileinfo,type_e_no_assign_to_const);
                           exit;
                         end;
                        { Are we at a with symtable, then we need to process the
@@ -1178,7 +1223,8 @@ implementation
                           (valid_const in opts) then
                         result:=true
                        else
-                        CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
+                        if report_errors then
+                         CGMessagePos(hp.fileinfo,type_e_no_assign_to_const);
                        exit;
                      end;
                    procsym :
@@ -1186,7 +1232,8 @@ implementation
                        if (Valid_Const in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    labelsym :
@@ -1194,7 +1241,8 @@ implementation
                        if (Valid_Addr in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    constsym:
@@ -1203,19 +1251,22 @@ implementation
                          (valid_addr in opts) then
                          result:=true
                        else
-                         CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                         if report_errors then
+                          CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                    else
                      begin
-                       CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                       if report_errors then
+                        CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                        exit;
                      end;
                  end;
                end;
              else
                begin
-                 CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
+                 if report_errors then
+                  CGMessagePos(hp.fileinfo,type_e_variable_id_expected);
                  exit;
                end;
             end;
@@ -1223,34 +1274,34 @@ implementation
       end;
 
 
-    function  valid_for_var(p:tnode):boolean;
+    function  valid_for_var(p:tnode; report_errors: boolean):boolean;
       begin
-        valid_for_var:=valid_for_assign(p,[]);
+        valid_for_var:=valid_for_assign(p,[],report_errors);
       end;
 
 
-    function  valid_for_formal_var(p : tnode) : boolean;
+    function  valid_for_formal_var(p : tnode; report_errors: boolean) : boolean;
       begin
-        valid_for_formal_var:=valid_for_assign(p,[valid_void]);
+        valid_for_formal_var:=valid_for_assign(p,[valid_void],report_errors);
       end;
 
 
-    function  valid_for_formal_const(p : tnode) : boolean;
+    function  valid_for_formal_const(p : tnode; report_errors: boolean) : boolean;
       begin
         valid_for_formal_const:=(p.resulttype.def.deftype=formaldef) or
-          valid_for_assign(p,[valid_void,valid_const]);
+          valid_for_assign(p,[valid_void,valid_const],report_errors);
       end;
 
 
-    function  valid_for_assignment(p:tnode):boolean;
+    function  valid_for_assignment(p:tnode; report_errors: boolean):boolean;
       begin
-        valid_for_assignment:=valid_for_assign(p,[valid_property]);
+        valid_for_assignment:=valid_for_assign(p,[valid_property],report_errors);
       end;
 
 
-    function  valid_for_addr(p : tnode) : boolean;
+    function  valid_for_addr(p : tnode; report_errors: boolean) : boolean;
       begin
-        result:=valid_for_assign(p,[valid_const,valid_addr,valid_void]);
+        result:=valid_for_assign(p,[valid_const,valid_addr,valid_void],report_errors);
       end;
 
 
@@ -2126,7 +2177,7 @@ implementation
           begin
             { Maybe passing the correct type but passing a const to var parameter }
             if (compare_defs(pt.resulttype.def,wrongpara.vartype.def,pt.nodetype)<>te_incompatible) and
-               not valid_for_var(pt.left) then
+               not valid_for_var(pt.left,true) then
               CGMessagePos(pt.left.fileinfo,type_e_variable_id_expected)
             else
               CGMessagePos2(pt.left.fileinfo,parser_e_call_by_ref_without_typeconv,

+ 12 - 1
compiler/msg/errore.msg

@@ -1261,7 +1261,7 @@ type_e_illegal_count_var=04058_E_Illegal counter variable
 #
 # Symtable
 #
-# 05055 is the last used one
+# 05060 is the last used one
 #
 % \section{Symbol handling}
 % This section lists all the messages that concern the handling of symbols.
@@ -1405,6 +1405,17 @@ sym_h_uninitialized_variable=05058_H_Variable "$1" does not seem to be initializ
 % be used (i.e. appears in the right-hand-side of an expression) when it
 % was not initialized first (i.e. appeared in the left-hand side of an
 % assigment)
+sym_w_function_result_uninitialized=05059_W_Function result variable does not seem to initialized
+% This message is displayed if the compiler thinks that the function result
+% variable will be used (i.e. appears in the right-hand-side of an expression)
+% before it is initialized (i.e. appeared in the left-hand side of an
+% assigment)
+sym_h_function_result_uninitialized=05060_H_Function result variable does not seem to be initialized
+% This message is displayed if the compiler thinks that the function result
+% variable will be used (i.e. appears in the right-hand-side of an expression)
+% before it is initialized (i.e. appeared in the left-hand side of an
+% assigment)
+
 % \end{description}
 #
 # Codegenerator

+ 4 - 2
compiler/msgidx.inc

@@ -393,6 +393,8 @@ const
   sym_e_cant_create_unique_type=05056;
   sym_h_uninitialized_local_variable=05057;
   sym_h_uninitialized_variable=05058;
+  sym_w_function_result_uninitialized=05059;
+  sym_h_function_result_uninitialized=05060;
   cg_e_parasize_too_big=06009;
   cg_e_file_must_call_by_reference=06012;
   cg_e_cant_use_far_pointer_there=06013;
@@ -666,9 +668,9 @@ const
   option_info=11024;
   option_help_pages=11025;
 
-  MsgTxtSize = 39453;
+  MsgTxtSize = 39580;
 
   MsgIdxMax : array[1..20] of longint=(
-    19,74,219,59,59,47,100,20,135,60,
+    19,74,219,59,61,47,100,20,135,60,
     41,1,1,1,1,1,1,1,1,1
   );

+ 183 - 182
compiler/msgtxt.inc

@@ -435,292 +435,294 @@ const msgtxt : array[0..000164,1..240] of char=(
   '05056_E_Can'#039't create uni','que type from this type'#000+
   '05057_H_Local variable "$1" does not seem to be initialized'#000+
   '05058_H_Variable "$1" does not seem to be initialized'#000+
+  '05059_W_Function result variable does not seem to initialized'#000+
+  '05060_H_Function result variable does no','t seem to be initialized'#000+
   '06009_E_Parameter list size exceeds 65535 bytes'#000+
   '06012_E_File types must be var parameters'#000+
-  '06013_E_The ','use of a far pointer isn'#039't allowed there'#000+
+  '06013_E_The use of a far pointer isn'#039't allowed there'#000+
   '06015_E_EXPORT declared functions can'#039't be called'#000+
-  '06016_W_Possible illegal call of constructor or destructor'#000+
+  '06016_W_Possible illeg','al call of constructor or destructor'#000+
   '06017_N_Inefficient code'#000+
   '06018_W_unreachable code'#000+
-  '06020_E_Abstract methods can'#039't be called',' directly'#000+
+  '06020_E_Abstract methods can'#039't be called directly'#000+
   '06027_DL_Register $1 weight $2 $3'#000+
   '06029_DL_Stack frame is omitted'#000+
-  '06031_E_Object or class methods can'#039't be inline.'#000+
+  '06031_E_Object or class methods can'#039't',' be inline.'#000+
   '06032_E_Procvar calls cannot be inline.'#000+
   '06033_E_No code for inline procedure stored'#000+
-  '06035_E_Element zero of an ansi','/wide- or longstring can'#039't be acc'+
-  'essed, use (set)length instead'#000+
-  '06037_E_Constructors or destructors can not be called inside a '#039'wi'+
-  'th'#039' clause'#000+
+  '06035_E_Element zero of an ansi/wide- or longstring can'#039't be acces'+
+  'sed, use (set)length instead'#000+
+  '06037_E_Constructors or destructors can not be ca','lled inside a '#039'w'+
+  'ith'#039' clause'#000+
   '06038_E_Cannot call message handler methods directly'#000+
-  '06039_E_Jump in or outside of an exception blo','ck'#000+
+  '06039_E_Jump in or outside of an exception block'#000+
   '06040_E_Control flow statements aren'#039't allowed in a finally block'#000+
-  '06041_W_Parameters size exceeds limit for certain cpu'#039's'#000+
+  '06041_W_Parameters size exceeds limit for ce','rtain cpu'#039's'#000+
   '06042_W_Local variable size exceed limit for certain cpu'#039's'#000+
   '06043_E_Local variables size exceeds supported limit'#000+
-  '060','44_E_BREAK not allowed'#000+
+  '06044_E_BREAK not allowed'#000+
   '06045_E_CONTINUE not allowed'#000+
-  '06046_F_Unknown compilerproc "$1". Check if you use the correct run ti'+
-  'me library.'#000+
+  '06046_F_Unknown compilerproc "$1". Check if you use the corre','ct run '+
+  'time library.'#000+
   '07000_DL_Starting $1 styled assembler parsing'#000+
   '07001_DL_Finished $1 styled assembler parsing'#000+
-  '07002_E_Non-la','bel pattern contains @'#000+
+  '07002_E_Non-label pattern contains @'#000+
   '07004_E_Error building record offset'#000+
   '07005_E_OFFSET used without identifier'#000+
-  '07006_E_TYPE used without identifier'#000+
+  '07006_E_TYPE u','sed without identifier'#000+
   '07007_E_Cannot use local variable or parameters here'#000+
   '07008_E_need to use OFFSET here'#000+
-  '07009_E_need to use',' $ here'#000+
+  '07009_E_need to use $ here'#000+
   '07010_E_Cannot use multiple relocatable symbols'#000+
   '07011_E_Relocatable symbol can only be added'#000+
-  '07012_E_Invalid constant expression'#000+
+  '07012_E_Inva','lid constant expression'#000+
   '07013_E_Relocatable symbol is not allowed'#000+
   '07014_E_Invalid reference syntax'#000+
-  '07015_E_You can not reach $1',' from that code'#000+
+  '07015_E_You can not reach $1 from that code'#000+
   '07016_E_Local symbols/labels aren'#039't allowed as references'#000+
-  '07017_E_Invalid base and index register usage'#000+
+  '07017_E_Invalid base and index register',' usage'#000+
   '07018_W_Possible error in object field handling'#000+
   '07019_E_Wrong scale factor specified'#000+
-  '07020_E_Multiple index register usa','ge'#000+
+  '07020_E_Multiple index register usage'#000+
   '07021_E_Invalid operand type'#000+
   '07022_E_Invalid string as opcode operand: $1'#000+
-  '07023_W_@CODE and @DATA not supported'#000+
+  '07023_W_@CODE and @DATA not supporte','d'#000+
   '07024_E_Null label references are not allowed'#000+
   '07025_E_Divide by zero in asm evaluator'#000+
   '07026_E_Illegal expression'#000+
-  '07027_E_esca','pe sequence ignored: $1'#000+
+  '07027_E_escape sequence ignored: $1'#000+
   '07028_E_Invalid symbol reference'#000+
   '07029_W_Fwait can cause emulation problems with emu387'#000+
-  '07030_W_$1 without operand translated into $1P'#000+
+  '0','7030_W_$1 without operand translated into $1P'#000+
   '07031_W_ENTER instruction is not supported by Linux kernel'#000+
-  '07032_W_Calling an ove','rload function in assembler'#000+
+  '07032_W_Calling an overload function in assembler'#000+
   '07033_E_Unsupported symbol type for operand'#000+
   '07034_E_Constant value out of bounds'#000+
-  '07035_E_Error converting decimal $1'#000+
+  '0703','5_E_Error converting decimal $1'#000+
   '07036_E_Error converting octal $1'#000+
   '07037_E_Error converting binary $1'#000+
-  '07038_E_Error converting h','exadecimal $1'#000+
+  '07038_E_Error converting hexadecimal $1'#000+
   '07039_H_$1 translated to $2'#000+
   '07040_W_$1 is associated to an overloaded function'#000+
-  '07041_E_Cannot use SELF outside a method'#000+
+  '07041_E_Cannot use S','ELF outside a method'#000+
   '07042_E_Cannot use OLDEBP outside a nested procedure'#000+
-  '07043_W_Procedures can'#039't return any value in asm code',#000+
+  '07043_W_Procedures can'#039't return any value in asm code'#000+
   '07044_E_SEG not supported'#000+
   '07045_E_Size suffix and destination or source size do not match'#000+
-  '07046_W_Size suffix and destination or source size do not match'#000+
+  '07046_W_Size suffix an','d destination or source size do not match'#000+
   '07047_E_Assembler syntax error'#000+
   '07048_E_Invalid combination of opcode and operands'#000+
-  '070','49_E_Assembler syntax error in operand'#000+
+  '07049_E_Assembler syntax error in operand'#000+
   '07050_E_Assembler syntax error in constant'#000+
-  '07051_E_Invalid String expression'#000+
+  '07051_E_Invalid String expressi','on'#000+
   '07052_W_constant with symbol $1 for address which is not on a pointer'#000+
   '07053_E_Unrecognized opcode $1'#000+
-  '07054_E_Invalid or miss','ing opcode'#000+
+  '07054_E_Invalid or missing opcode'#000+
   '07055_E_Invalid combination of prefix and opcode: $1'#000+
-  '07056_E_Invalid combination of override and opcode: $1'#000+
+  '07056_E_Invalid combination of override and opcod','e: $1'#000+
   '07057_E_Too many operands on line'#000+
   '07058_W_NEAR ignored'#000+
   '07059_W_FAR ignored'#000+
   '07060_E_Duplicate local symbol $1'#000+
-  '07061_E_Unde','fined local symbol $1'#000+
+  '07061_E_Undefined local symbol $1'#000+
   '07062_E_Unknown label identifier $1'#000+
   '07063_E_Invalid register name'#000+
-  '07064_E_Invalid floating point register name'#000+
+  '07064_E_Invalid floating ','point register name'#000+
   '07066_W_Modulo not supported'#000+
   '07067_E_Invalid floating point constant $1'#000+
-  '07068_E_Invalid floating point expr','ession'#000+
+  '07068_E_Invalid floating point expression'#000+
   '07069_E_Wrong symbol type'#000+
   '07070_E_Cannot index a local var or parameter with a register'#000+
-  '07071_E_Invalid segment override expression'#000+
+  '07071_E_Invalid se','gment override expression'#000+
   '07072_W_Identifier $1 supposed external'#000+
   '07073_E_Strings not allowed as constants'#000+
-  '07074_No type of var','iable specified'#000+
+  '07074_No type of variable specified'#000+
   '07075_E_assembler code not returned to text section'#000+
   '07076_E_Not a directive or local symbol $1'#000+
-  '07077_E_Using a defined name as a local label'#000+
+  '07','077_E_Using a defined name as a local label'#000+
   '07078_E_Dollar token is used without an identifier'#000+
-  '07079_W_32bit constant created f','or address'#000+
+  '07079_W_32bit constant created for address'#000+
   '07080_N_.align is target specific, use .balign or .p2align'#000+
-  '07081_E_Can'#039't access fields directly for parameters'#000+
+  '07081_E_Can'#039't access fields directly for pa','rameters'#000+
   '07082_E_Can'#039't access fields of objects/classes directly'#000+
-  '07083_E_No size specified and unable to determine the size of ','the op'+
-  'erands'#000+
+  '07083_E_No size specified and unable to determine the size of the oper'+
+  'ands'#000+
   '07084_E_Cannot use RESULT in this function'#000+
-  '07086_W_"$1" without operand translated into "$1 %st,%st(1)"'#000+
+  '07086_W_"$1" without operand translated into "$1 %st,%st(','1)"'#000+
   '07087_W_"$1 %st(n)" translated into "$1 %st,%st(n)"'#000+
   '07088_W_"$1 %st(n)" translated into "$1 %st(n),%st"'#000+
-  '07089_E_Char < not ','allowed here'#000+
+  '07089_E_Char < not allowed here'#000+
   '07090_E_Char > not allowed here'#000+
   '07093_W_ALIGN not supported'#000+
   '07094_E_Inc and Dec cannot be together'#000+
-  '07095_E_Invalid reglist for movem'#000+
+  '0','7095_E_Invalid reglist for movem'#000+
   '07096_E_Reglist invalid for opcode'#000+
   '07097_E_Higher cpu mode required ($1)'#000+
-  '07098_W_No size speci','fied and unable to determine the size of the op'+
-  'erands, using DWORD as default'#000+
-  '07099_E_Syntax error while trying to parse a shifter operand'#000+
+  '07098_W_No size specified and unable to determine the size of the oper'+
+  'ands, using DWORD as default'#000+
+  '07099_E_Syntax error while trying t','o parse a shifter operand'#000+
   '08000_F_Too many assembler files'#000+
   '08001_F_Selected assembler output not supported'#000+
-  '08002_F_Comp not sup','ported'#000+
+  '08002_F_Comp not supported'#000+
   '08003_F_Direct not support for binary writers'#000+
   '08004_E_Allocating of data is only allowed in bss section'#000+
-  '08005_F_No binary writer selected'#000+
+  '08','005_F_No binary writer selected'#000+
   '08006_E_Asm: Opcode $1 not in table'#000+
-  '08007_E_Asm: $1 invalid combination of opcode and operands'#000,
+  '08007_E_Asm: $1 invalid combination of opcode and operands'#000+
   '08008_E_Asm: 16 Bit references not supported'#000+
   '08009_E_Asm: Invalid effective address'#000+
-  '08010_E_Asm: Immediate or reference expected'#000+
+  '08010_E_Asm: Immediate or ref','erence expected'#000+
   '08011_E_Asm: $1 value exceeds bounds $2'#000+
   '08012_E_Asm: Short jump is out of range $1'#000+
-  '08013_E_Asm: Undefined label',' $1'#000+
+  '08013_E_Asm: Undefined label $1'#000+
   '08014_E_Asm: Comp type not supported for this target'#000+
-  '08015_E_Asm: Extended type not supported for this target'#000+
+  '08015_E_Asm: Extended type not supported for this target',#000+
   '08016_E_Asm: Duplicate label $1'#000+
   '08017_E_Asm: Redefined label $1'#000+
   '08018_E_Asm: First defined here'#000+
-  '08019_E_Asm: Invalid register ','$1'#000+
+  '08019_E_Asm: Invalid register $1'#000+
   '09000_W_Source operating system redefined'#000+
   '09001_I_Assembling (pipe) $1'#000+
-  '09002_E_Can'#039't create assembler file: $1'#000+
+  '09002_E_Can'#039't create assembler file: $1',#000+
   '09003_E_Can'#039't create object file: $1'#000+
   '09004_E_Can'#039't create archive file: $1'#000+
-  '09005_E_Assembler $1 not found, switching to extern','al assembling'#000+
+  '09005_E_Assembler $1 not found, switching to external assembling'#000+
   '09006_T_Using assembler: $1'#000+
   '09007_E_Error while assembling exitcode $1'#000+
-  '09008_E_Can'#039't call the assembler, error $1 switching to external a'+
-  'ssembling'#000+
+  '09008_E_Can'#039't call the assem','bler, error $1 switching to external'+
+  ' assembling'#000+
   '09009_I_Assembling $1'#000+
   '09010_I_Assembling with smartlinking $1'#000+
-  '09011_W_Object $1',' not found, Linking may fail !'#000+
+  '09011_W_Object $1 not found, Linking may fail !'#000+
   '09012_W_Library $1 not found, Linking may fail !'#000+
   '09013_E_Error while linking'#000+
-  '09014_E_Can'#039't call the linker, switching to external linking'#000+
+  '09014','_E_Can'#039't call the linker, switching to external linking'#000+
   '09015_I_Linking $1'#000+
-  '09016_E_Util $1 not found, switching to external lin','king'#000+
+  '09016_E_Util $1 not found, switching to external linking'#000+
   '09017_T_Using util $1'#000+
   '09018_E_Creation of Executables not supported'#000+
-  '09019_E_Creation of Dynamic/Shared Libraries not supported'#000+
+  '09019_E_Creation of Dynamic/Shared Libra','ries not supported'#000+
   '09020_I_Closing script $1'#000+
   '09021_E_resource compiler not found, switching to external mode'#000+
-  '09022_I_Compiling ','resource $1'#000+
+  '09022_I_Compiling resource $1'#000+
   '09023_T_unit $1 can'#039't be statically linked, switching to smart lin'+
   'king'#000+
-  '09024_T_unit $1 can'#039't be smart linked, switching to static linking'+
-  #000+
+  '09024_T_unit $1 can'#039't be smart',' linked, switching to static linki'+
+  'ng'#000+
   '09025_T_unit $1 can'#039't be shared linked, switching to static linkin'+
   'g'#000+
-  '09026_E_unit $1 can'#039't ','be smart or static linked'#000+
+  '09026_E_unit $1 can'#039't be smart or static linked'#000+
   '09027_E_unit $1 can'#039't be shared or static linked'#000+
-  '09028_D_Calling resource compiler "$1" with "$2" as command line'#000+
+  '09028_D_Calling resource compiler "$1"',' with "$2" as command line'#000+
   '09128_F_Can'#039't post process executable $1'#000+
   '09129_F_Can'#039't open executable $1'#000+
-  '09130_X_Size of Code: $1 b','ytes'#000+
+  '09130_X_Size of Code: $1 bytes'#000+
   '09131_X_Size of initialized data: $1 bytes'#000+
   '09132_X_Size of uninitialized data: $1 bytes'#000+
-  '09133_X_Stack space reserved: $1 bytes'#000+
+  '09133_X_Stack space ','reserved: $1 bytes'#000+
   '09134_X_Stack space committed: $1 bytes'#000+
   '10000_T_Unitsearch: $1'#000+
   '10001_T_PPU Loading $1'#000+
   '10002_U_PPU Name: $1'#000+
-  '1','0003_U_PPU Flags: $1'#000+
+  '10003_U_PPU Flags: $1'#000+
   '10004_U_PPU Crc: $1'#000+
   '10005_U_PPU Time: $1'#000+
   '10006_U_PPU File too short'#000+
-  '10007_U_PPU Invalid Header (no PPU at the begin)'#000+
+  '10007_U_PPU Invalid Head','er (no PPU at the begin)'#000+
   '10008_U_PPU Invalid Version $1'#000+
   '10009_U_PPU is compiled for another processor'#000+
-  '10010_U_PPU is compiled f','or an other target'#000+
+  '10010_U_PPU is compiled for an other target'#000+
   '10011_U_PPU Source: $1'#000+
   '10012_U_Writing $1'#000+
   '10013_F_Can'#039't Write PPU-File'#000+
-  '10014_F_Error reading PPU-File'#000+
+  '10014_F_Error reading P','PU-File'#000+
   '10015_F_unexpected end of PPU-File'#000+
   '10016_F_Invalid PPU-File entry: $1'#000+
   '10017_F_PPU Dbx count problem'#000+
-  '10018_E_Illegal uni','t name: $1'#000+
+  '10018_E_Illegal unit name: $1'#000+
   '10019_F_Too much units'#000+
   '10020_F_Circular unit reference between $1 and $2'#000+
-  '10021_F_Can'#039't compile unit $1, no sources available'#000+
+  '10021_F_Can'#039't compile unit $1',', no sources available'#000+
   '10022_F_Can'#039't find unit $1'#000+
   '10023_W_Unit $1 was not found but $2 exists'#000+
-  '10024_F_Unit $1 searched but $2 f','ound'#000+
+  '10024_F_Unit $1 searched but $2 found'#000+
   '10025_W_Compiling the system unit requires the -Us switch'#000+
-  '10026_F_There were $1 errors compiling module, stopping'#000+
+  '10026_F_There were $1 errors compiling module, sto','pping'#000+
   '10027_U_Load from $1 ($2) unit $3'#000+
   '10028_U_Recompiling $1, checksum changed for $2'#000+
-  '10029_U_Recompiling $1, source found on','ly'#000+
+  '10029_U_Recompiling $1, source found only'#000+
   '10030_U_Recompiling unit, static lib is older than ppufile'#000+
-  '10031_U_Recompiling unit, shared lib is older than ppufile'#000+
+  '10031_U_Recompiling unit, shared lib is older than ','ppufile'#000+
   '10032_U_Recompiling unit, obj and asm are older than ppufile'#000+
   '10033_U_Recompiling unit, obj is older than asm'#000+
-  '10034_U_Pa','rsing interface of $1'#000+
+  '10034_U_Parsing interface of $1'#000+
   '10035_U_Parsing implementation of $1'#000+
   '10036_U_Second load for unit $1'#000+
-  '10037_U_PPU Check file $1 time $2'#000+
+  '10037_U_PPU Check file',' $1 time $2'#000+
   '10040_W_Can'#039't recompile unit $1, but found modifed include files'#000+
-  '10041_H_File $1 is newer than Release PPU file $2'#000,
+  '10041_H_File $1 is newer than Release PPU file $2'#000+
   '10042_U_Using a unit which was not compiled with correct FPU mode'#000+
   '10043_U_Loading interface units from $1'#000+
-  '10044_U_Loading implementation units from $1'#000+
+  '10044_U','_Loading implementation units from $1'#000+
   '10045_U_Interface CRC changed for unit $1'#000+
-  '10046_U_Implementation CRC changed for unit $1'#000,
+  '10046_U_Implementation CRC changed for unit $1'#000+
   '10047_U_Finished compiling unit $1'#000+
   '10048_U_Add dependency of $1 to $2'#000+
   '10049_U_No reload, is caller: $1'#000+
-  '10050_U_No reload, already in second compile: $1'#000+
+  '10050_U_No',' reload, already in second compile: $1'#000+
   '10051_U_Flag for reload: $1'#000+
   '10052_U_Forced reloading'#000+
   '10053_U_Previous state of $1: $2'#000+
-  '10','054_U_Already compiling $1, setting second compile'#000+
+  '10054_U_Already compiling $1, setting second compile'#000+
   '10055_U_Loading unit $1'#000+
   '10056_U_Finished loading unit $1'#000+
-  '10057_U_Registering new unit $1'#000+
+  '10057','_U_Registering new unit $1'#000+
   '10058_U_Re-resolving unit $1'#000+
   '10059_U_Skipping re-resolving unit $1, still loading used units'#000+
-  '11000_O','_$1 [options] <inputfile> [options]'#000+
+  '11000_O_$1 [options] <inputfile> [options]'#000+
   '11001_W_Only one source file supported'#000+
-  '11002_W_DEF file can be created only for OS/2'#000+
+  '11002_W_DEF file can be created only f','or OS/2'#000+
   '11003_E_nested response files are not supported'#000+
   '11004_F_No source file name in command line'#000+
-  '11005_N_No option inside $1',' config file'#000+
+  '11005_N_No option inside $1 config file'#000+
   '11006_E_Illegal parameter: $1'#000+
   '11007_H_-? writes help pages'#000+
   '11008_F_Too many config files nested'#000+
-  '11009_F_Unable to open file $1'#000+
+  '1100','9_F_Unable to open file $1'#000+
   '11010_D_Reading further options from $1'#000+
   '11011_W_Target is already set to: $1'#000+
-  '11012_W_Shared libs not',' supported on DOS platform, reverting to stat'+
-  'ic'#000+
+  '11012_W_Shared libs not supported on DOS platform, reverting to static'+
+  #000+
   '11013_F_too many IF(N)DEFs'#000+
   '11014_F_too many ENDIFs'#000+
-  '11015_F_open conditional at the end of the file'#000+
+  '11015_F_open c','onditional at the end of the file'#000+
   '11016_W_Debug information generation is not supported by this executab'+
   'le'#000+
-  '11017_H_Try recompil','ing with -dGDB'#000+
+  '11017_H_Try recompiling with -dGDB'#000+
   '11018_E_You are using the obsolete switch $1'#000+
-  '11019_E_You are using the obsolete switch $1, please use $2'#000+
+  '11019_E_You are using the obsolete switch $1, please ','use $2'#000+
   '11020_N_Switching assembler to default source writing assembler'#000+
-  '11021_W_Assembler output selected "$1" is not compatible',' with "$2"'#000+
+  '11021_W_Assembler output selected "$1" is not compatible with "$2"'#000+
   '11022_W_"$1" assembler use forced'#000+
   '11026_T_Reading options from file $1'#000+
-  '11027_T_Reading options from environment $1'#000+
+  '11027_T_Reading options from en','vironment $1'#000+
   '11028_D_Handling option "$1"'#000+
   '11029__*** press enter ***'#000+
   '11030_H_Start of reading config file $1'#000+
-  '11031_H_End of rea','ding config file $1'#000+
+  '11031_H_End of reading config file $1'#000+
   '11032_D_interpreting option "$1"'#000+
   '11036_D_interpreting firstpass option "$1"'#000+
-  '11033_D_interpreting file option "$1"'#000+
+  '11033_D_interpret','ing file option "$1"'#000+
   '11034_D_Reading config file "$1"'#000+
   '11035_D_found source file name "$1"'#000+
   '11039_E_Unknown code page'#000+
-  '11040_F_Con','fig file $1 is a directory'#000+
+  '11040_F_Config file $1 is a directory'#000+
   '11023_Free Pascal Compiler version $FPCVERSION [$FPCDATE] for $FPCCPU'#010+
-  'Copyright (c) 1993-2005 by Florian Klaempfl'#000+
+  'Copyright (c) 19','93-2005 by Florian Klaempfl'#000+
   '11024_Free Pascal Compiler version $FPCVERSION'#010+
   #010+
   'Compiler Date      : $FPCDATE'#010+
-  'Compiler CPU Target: ','$FPCCPU'#010+
+  'Compiler CPU Target: $FPCCPU'#010+
   #010+
   'Supported targets:'#010+
   '  $OSTARGETS'#010+
@@ -728,232 +730,231 @@ const msgtxt : array[0..000164,1..240] of char=(
   'Supported CPU instruction sets:'#010+
   '  $INSTRUCTIONSETS'#010+
   #010+
-  'Supported FPU instruction sets:'#010+
+  'Supported FPU instr','uction sets:'#010+
   '  $FPUINSTRUCTIONSETS'#010+
   #010+
   'This program comes under the GNU General Public Licence'#010+
-  'For more information read COPYING.F','PC'#010+
+  'For more information read COPYING.FPC'#010+
   #010+
   'Report bugs,suggestions etc to:'#010+
   '                 [email protected]'#000+
-  '11025_**0*_put + after a boolean switch option to enable it, - to disa'+
-  'ble it'#010+
+  '11025_**0*_put + after a boolean switc','h option to enable it, - to di'+
+  'sable it'#010+
   '**1a_the compiler doesn'#039't delete the generated assembler file'#010+
-  '**2al_list sourcecode line','s in assembler file'#010+
+  '**2al_list sourcecode lines in assembler file'#010+
   '**2an_list node info in assembler file'#010+
-  '*L2ap_use pipes instead of creating temporary assembler files'#010+
+  '*L2ap_use pipes instead of creating temporary assemble','r files'#010+
   '**2ar_list register allocation/release info in assembler file'#010+
-  '**2at_list temp allocation/release info in assembler file',#010+
+  '**2at_list temp allocation/release info in assembler file'#010+
   '**1A<x>_output format:'#010+
   '**2Adefault_use default assembler'#010+
   '3*2Aas_assemble using GNU AS'#010+
-  '3*2Anasmcoff_coff (Go32v2) file using Nasm'#010+
+  '3*2Anasmcoff_coff (Go32v2)',' file using Nasm'#010+
   '3*2Anasmelf_elf32 (Linux) file using Nasm'#010+
   '3*2Anasmwin32_Win32 object file using Nasm'#010+
-  '3*2Anasmwdosx_Win32/WDOSX',' object file using Nasm'#010+
+  '3*2Anasmwdosx_Win32/WDOSX object file using Nasm'#010+
   '3*2Awasm_obj file using Wasm (Watcom)'#010+
   '3*2Anasmobj_obj file using Nasm'#010+
-  '3*2Amasm_obj file using Masm (Microsoft)'#010+
+  '3*2Amasm_obj file u','sing Masm (Microsoft)'#010+
   '3*2Atasm_obj file using Tasm (Borland)'#010+
   '3*2Aelf_elf32 (Linux) using internal writer'#010+
-  '3*2Acoff_coff (Go32v2)',' using internal writer'#010+
+  '3*2Acoff_coff (Go32v2) using internal writer'#010+
   '3*2Apecoff_pecoff (Win32) using internal writer'#010+
   '4*2Aas_assemble using GNU AS'#010+
-  '6*2Aas_Unix o-file using GNU AS'#010+
+  '6*2Aas_Unix o','-file using GNU AS'#010+
   '6*2Agas_GNU Motorola assembler'#010+
   '6*2Amit_MIT Syntax (old GAS)'#010+
   '6*2Amot_Standard Motorola assembler'#010+
-  'A*2Aas_assem','ble using GNU AS'#010+
+  'A*2Aas_assemble using GNU AS'#010+
   'P*2Aas_assemble using GNU AS'#010+
   'S*2Aas_assemble using GNU AS'#010+
   '**1b_generate browser info'#010+
-  '**2bl_generate local symbol info'#010+
+  '**2bl_gener','ate local symbol info'#010+
   '**1B_build all modules'#010+
   '**1C<x>_code generation options:'#010+
   '**2Cc<x>_set default calling convention to <x>'#010+
-  '**','2CD_create also dynamic library (not supported)'#010+
+  '**2CD_create also dynamic library (not supported)'#010+
   '**2Ce_Compilation with emulated floating point opcodes'#010+
-  '**2Cf<x>_Select fpu instruction set to use, see fpc -i for possible va'+
-  'lues'#010+
+  '**2Cf<x>_S','elect fpu instruction set to use, see fpc -i for possible '+
+  'values'#010+
   '**2Cg_Generate PIC code'#010+
-  '**2Ch<n>_<n> bytes heap (between 1023 ','and 67107840)'#010+
+  '**2Ch<n>_<n> bytes heap (between 1023 and 67107840)'#010+
   '**2Ci_IO-checking'#010+
   '**2Cn_omit linking stage'#010+
   '**2Co_check overflow of integer operations'#010+
-  '**2Cp<x>_select instruction set, see fpc -i for possible values'#010+
+  '**2Cp<x>_sele','ct instruction set, see fpc -i for possible values'#010+
   '**2Cr_range checking'#010+
   '**2CR_verify object method call validity'#010+
-  '**2Cs<n>_set s','tack size to <n>'#010+
+  '**2Cs<n>_set stack size to <n>'#010+
   '**2Ct_stack checking'#010+
   '**2CX_create also smartlinked library'#010+
   '**1d<x>_defines the symbol <x>'#010+
-  '**1D_generate a DEF file'#010+
+  '**1D_g','enerate a DEF file'#010+
   '**2Dd<x>_set description to <x>'#010+
   '**2Dv<x>_set DLL version to <x>'#010+
   '*O2Dw_PM application'#010+
-  '**1e<x>_set path to exe','cutable'#010+
+  '**1e<x>_set path to executable'#010+
   '**1E_same as -Cn'#010+
   '**1F<x>_set file names and paths:'#010+
-  '**2Fa<x>[,y]_for a program load first units <x> and [y] before uses is'+
-  ' parsed'#010+
+  '**2Fa<x>[,y]_for a program load first units <x> and [y','] before uses '+
+  'is parsed'#010+
   '**2Fc<x>_sets input codepage to <x>'#010+
-  '**2FD<x>_sets the directory where to search for compiler utilities'#010,
+  '**2FD<x>_sets the directory where to search for compiler utilities'#010+
   '**2Fe<x>_redirect error output to <x>'#010+
   '**2FE<x>_set exe/unit output path to <x>'#010+
-  '**2Fi<x>_adds <x> to include path'#010+
+  '**2Fi<x>_adds <x> to include path'#010,
   '**2Fl<x>_adds <x> to library path'#010+
   '**2FL<x>_uses <x> as dynamic linker'#010+
   '**2Fo<x>_adds <x> to object path'#010+
-  '**2Fr<x>_load error mess','age file <x>'#010+
+  '**2Fr<x>_load error message file <x>'#010+
   '**2Fu<x>_adds <x> to unit path'#010+
   '**2FU<x>_set unit output path to <x>, overrides -FE'#010+
-  '*g1g_generate debugger information:'#010+
+  '*g1g_generate deb','ugger information:'#010+
   '*g2gc_generate checks for pointers'#010+
   '*g2gd_use dbx'#010+
   '*g2gg_use gsym'#010+
-  '*g2gh_use heap trace unit (for memory leak d','ebugging)'#010+
+  '*g2gh_use heap trace unit (for memory leak debugging)'#010+
   '*g2gl_use line info unit to show more info for backtraces'#010+
-  '*g2gv_generates programs traceable with valgrind'#010+
+  '*g2gv_generates programs traceable with valgr','ind'#010+
   '*g2gw_generate dwarf debugging info'#010+
   '**1i_information'#010+
   '**2iD_return compiler date'#010+
   '**2iV_return compiler version'#010+
-  '**2iSO_return',' compiler OS'#010+
+  '**2iSO_return compiler OS'#010+
   '**2iSP_return compiler processor'#010+
   '**2iTO_return target OS'#010+
   '**2iTP_return target processor'#010+
-  '**1I<x>_adds <x> to include path'#010+
+  '**1I<x>_adds',' <x> to include path'#010+
   '**1k<x>_Pass <x> to the linker'#010+
   '**1l_write logo'#010+
   '**1M<x>_set language mode to <x>'#010+
-  '**2Mfpc_free pascal dialec','t (default)'#010+
+  '**2Mfpc_free pascal dialect (default)'#010+
   '**2Mobjfpc_switch some Delphi 2 extensions on'#010+
   '**2Mdelphi_tries to be Delphi compatible'#010+
-  '**2Mtp_tries to be TP/BP 7.0 compatible'#010+
+  '**2Mtp_tries t','o be TP/BP 7.0 compatible'#010+
   '**2Mgpc_tries to be gpc compatible'#010+
-  '**2Mmacpas_tries to be compatible to the macintosh pascal dialects',#010+
+  '**2Mmacpas_tries to be compatible to the macintosh pascal dialects'#010+
   '**1n_don'#039't read the default config file'#010+
   '**1o<x>_change the name of the executable produced to <x>'#010+
-  '**1O<x>_optimizations:'#010+
+  '**1O<x>_optimi','zations:'#010+
   '3*2Oa_<type>=<values> set alignment'#010+
   '3*2Og_generate smaller code'#010+
   '3*2OG_generate faster code (default)'#010+
-  '**2Or_keep certai','n variables in registers'#010+
+  '**2Or_keep certain variables in registers'#010+
   '3*2Ou_enable uncertain optimizations (see docs)'#010+
-  '3*2O1_level 1 optimizations (quick optimizations)'#010+
+  '3*2O1_level 1 optimizations (quick optim','izations)'#010+
   '3*2O2_level 2 optimizations (-O1 + slower optimizations)'#010+
   '3*2O3_level 3 optimizations (-O2 repeatedly, max 5 times)'#010+
-  '3*','2Op<x>_target processor:'#010+
+  '3*2Op<x>_target processor:'#010+
   '3*3Op1_set target processor to 386/486'#010+
-  '3*3Op2_set target processor to Pentium/PentiumMMX (tm)'#010+
+  '3*3Op2_set target processor to Pentium/PentiumMMX',' (tm)'#010+
   '3*3Op3_set target processor to PPro/PII/c6x86/K6 (tm)'#010+
   '6*2Og_generate smaller code'#010+
   '6*2OG_generate faster code (default)'#010+
-  '6*','2Ox_optimize maximum (still BUGGY!!!)'#010+
+  '6*2Ox_optimize maximum (still BUGGY!!!)'#010+
   '6*2O0_set target processor to a MC68000'#010+
-  '6*2O2_set target processor to a MC68020+ (default)'#010+
+  '6*2O2_set target processor to a MC6','8020+ (default)'#010+
   '**1pg_generate profile code for gprof (defines FPC_PROFILE)'#010+
   '**1R<x>_assembler reading style:'#010+
-  '**2Rdefault_use de','fault assembler'#010+
+  '**2Rdefault_use default assembler'#010+
   '3*2Ratt_read AT&T style assembler'#010+
   '3*2Rintel_read Intel style assembler'#010+
-  '6*2RMOT_read motorola style assembler'#010+
+  '6*2RMOT_read motorola styl','e assembler'#010+
   '**1S<x>_syntax options:'#010+
   '**2S2_same as -Mobjfpc'#010+
   '**2Sc_supports operators like C (*=,+=,/= and -=)'#010+
-  '**2Sa_include asse','rtion code.'#010+
+  '**2Sa_include assertion code.'#010+
   '**2Sd_same as -Mdelphi'#010+
   '**2Se<x>_error options. <x> is a combination of the following:'#010+
-  '**3*_<n> : compiler stops after the <n> errors (default is 1)'#010+
+  '**3*_<n> : comp','iler stops after the <n> errors (default is 1)'#010+
   '**3*_w : compiler stops also after warnings'#010+
-  '**3*_n : compiler stops also after n','otes'#010+
+  '**3*_n : compiler stops also after notes'#010+
   '**3*_h : compiler stops also after hints'#010+
   '**2Sg_allow LABEL and GOTO'#010+
   '**2Sh_Use ansistrings'#010+
-  '**2Si_support C++ styled INLINE'#010+
+  '**2Si_support C++ ','styled INLINE'#010+
   '**2Sk_load fpcylix unit'#010+
   '**2SI<x>_set interface style to <x>'#010+
   '**3SIcom_COM compatible interface (default)'#010+
-  '**3SIcorb','a_CORBA compatible interface'#010+
+  '**3SIcorba_CORBA compatible interface'#010+
   '**2Sm_support macros like C (global)'#010+
   '**2So_same as -Mtp'#010+
   '**2Sp_same as -Mgpc'#010+
-  '**2Ss_constructor name must be init (destructor must be done)'#010+
+  '**2Ss_co','nstructor name must be init (destructor must be done)'#010+
   '**2St_allow static keyword in objects'#010+
-  '**1s_don'#039't call assembler and linke','r'#010+
+  '**1s_don'#039't call assembler and linker'#010+
   '**2sh_Generate script to link on host'#010+
   '**2st_Generate script to link on target'#010+
-  '**2sr_Skip register allocation phase (use with -alr)'#010+
+  '**2sr_Skip register allocation ph','ase (use with -alr)'#010+
   '**1T<x>_Target operating system:'#010+
   '3*2Temx_OS/2 via EMX (including EMX/RSX extender)'#010+
   '3*2Tfreebsd_FreeBSD'#010+
-  '3*2T','go32v2_Version 2 of DJ Delorie DOS extender'#010+
+  '3*2Tgo32v2_Version 2 of DJ Delorie DOS extender'#010+
   '3*2Tlinux_Linux'#010+
   '3*2Tnetbsd_NetBSD'#010+
-  '3*2Tnetware_Novell Netware Module (clib)'#010+
+  '3*2Tnetware_Novell Netware Module (','clib)'#010+
   '3*2Tnetwlibc_Novell Netware Module (libc)'#010+
   '3*2Topenbsd_OpenBSD'#010+
   '3*2Tos2_OS/2 / eComStation'#010+
   '3*2Tsunos_SunOS/Solaris'#010+
-  '3*2Twatc','om_Watcom compatible DOS extender'#010+
+  '3*2Twatcom_Watcom compatible DOS extender'#010+
   '3*2Twdosx_WDOSX DOS extender'#010+
   '3*2Twin32_Windows 32 Bit'#010+
   '4*2Tlinux_Linux'#010+
-  '6*2Tamiga_Commodore Amiga'#010+
+  '6*2Tamiga','_Commodore Amiga'#010+
   '6*2Tatari_Atari ST/STe/TT'#010+
   '6*2Tlinux_Linux-68k'#010+
   '6*2Tmacos_Macintosh m68k (not supported)'#010+
   '6*2Tpalmos_PalmOS'#010+
-  'A*2Tl','inux_Linux'#010+
+  'A*2Tlinux_Linux'#010+
   'P*2Tdarwin_Darwin and MacOS X on PowerPC'#010+
   'P*2Tlinux_Linux on PowerPC'#010+
-  'P*2Tmacos_MacOS (classic) on PowerPC'#010+
+  'P*2Tmacos_MacOS (classic) on Power','PC'#010+
   'P*2Tmorphos_MorphOS'#010+
   'S*2Tlinux_Linux'#010+
   '**1u<x>_undefines the symbol <x>'#010+
   '**1U_unit options:'#010+
   '**2Un_don'#039't check the unit name'#010+
-  '**2U','r_generate release unit files'#010+
+  '**2Ur_generate release unit files'#010+
   '**2Us_compile a system unit'#010+
-  '**1v<x>_Be verbose. <x> is a combination of the following letters:'#010+
+  '**1v<x>_Be verbose. <x> is a combination of the followi','ng letters:'#010+
   '**2*_e : Show errors (default)       0 : Show nothing (except errors)'#010+
-  '**2*_w : Show warnings               u : Show',' unit info'#010+
+  '**2*_w : Show warnings               u : Show unit info'#010+
   '**2*_n : Show notes                  t : Show tried/used files'#010+
-  '**2*_h : Show hints                  c : Show conditionals'#010+
+  '**2*_h : Show hints                  c ',': Show conditionals'#010+
   '**2*_i : Show general info           d : Show debug info'#010+
-  '**2*_l : Show linenumbers            r : Rhide/GCC',' compatibility mod'+
-  'e'#010+
+  '**2*_l : Show linenumbers            r : Rhide/GCC compatibility mode'#010+
   '**2*_a : Show everything             x : Executable info (Win32 only)'#010+
-  '**2*_b : Write file names messages with full path'#010+
+  '**2*_b : Write file nam','es messages with full path'#010+
   '**2*_v : write fpcdebug.txt with     p : Write tree.log with parse tre'+
   'e'#010+
-  '**2*_    lots of debugging i','nfo'#010+
+  '**2*_    lots of debugging info'#010+
   '3*1W<x>_Win32-like target options'#010+
   '3*2WB_Create a relocatable image'#010+
-  '3*2WB<x>_Set Image base to Hexadecimal <x> value'#010+
+  '3*2WB<x>_Set Image base to Hexadecimal <x>',' value'#010+
   '3*2WC_Specify console type application'#010+
   '3*2WD_Use DEFFILE to export functions of DLL or EXE'#010+
-  '3*2WF_Specify full-screen typ','e application (OS/2 only)'#010+
+  '3*2WF_Specify full-screen type application (OS/2 only)'#010+
   '3*2WG_Specify graphic type application'#010+
-  '3*2WN_Do not generate relocation code (necessary for debugging)'#010+
+  '3*2WN_Do not generate relocation code (necessary',' for debugging)'#010+
   '3*2WR_Generate relocation code'#010+
   'P*2WC_Specify console type application (MacOS only)'#010+
-  'P*2WG_Specify graphic type a','pplication (MacOS only)'#010+
+  'P*2WG_Specify graphic type application (MacOS only)'#010+
   'P*2WT_Specify tool type application (MPW tool, MacOS only)'#010+
   '**1X_executable options:'#010+
-  '**2Xc_pass --shared to the linker (Unix only)'#010+
+  '**2Xc','_pass --shared to the linker (Unix only)'#010+
   '**2Xd_don'#039't use standard library search path (needed for cross com'+
   'pile)'#010+
-  '**2XD_try to l','ink units dynamic          (defines FPC_LINK_DYNAMIC)'#010+
+  '**2XD_try to link units dynamic          (defines FPC_LINK_DYNAMIC)'#010+
   '**2Xm_generate link map'#010+
-  '**2XM<x>_set the name of the '#039'main'#039' program routine (default i'+
-  's '#039'main'#039')'#010+
+  '**2XM<x>_set the name of the '#039'main'#039,' program routine (default '+
+  'is '#039'main'#039')'#010+
   '**2XP<x>_prepend the binutils names with the prefix <x>'#010+
-  '**2Xr<x>_set library search path t','o <x> (needed for cross compile)'#010+
+  '**2Xr<x>_set library search path to <x> (needed for cross compile)'#010+
   '**2Xs_strip all symbols from executable'#010+
-  '**2XS_try to link units static (default) (defines FPC_LINK_STATIC)'#010+
+  '**2XS_try to link units static (default)',' (defines FPC_LINK_STATIC)'#010+
   '**2Xt_link with static libraries (-static is passed to linker)'#010+
-  '**2XX_try to link units smart        ','    (defines FPC_LINK_SMART)'#010+
+  '**2XX_try to link units smart            (defines FPC_LINK_SMART)'#010+
   '**1*_'#010+
   '**1?_shows this help'#010+
   '**1h_shows this help without waiting'#000

+ 2 - 2
compiler/nadd.pas

@@ -162,8 +162,8 @@ implementation
          resulttypepass(left);
          resulttypepass(right);
          { both left and right need to be valid }
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 

+ 103 - 38
compiler/ncal.pas

@@ -572,7 +572,7 @@ type
                    floatdef :
                      inserttypeconv(left,s64floattype);
                  end;
-                 set_varstate(left,vs_used,[vsf_must_be_valid]);
+                 set_varstate(left,vs_read,[vsf_must_be_valid]);
                  resulttype:=left.resulttype;
                  { also update parasym type to get the correct parameter location
                    for the new types }
@@ -581,7 +581,7 @@ type
              else
               if (vo_is_hidden_para in parasym.varoptions) then
                begin
-                 set_varstate(left,vs_used,[vsf_must_be_valid]);
+                 set_varstate(left,vs_read,[vsf_must_be_valid]);
                  resulttype:=left.resulttype;
                end
              else
@@ -682,12 +682,12 @@ type
                        vs_var,
                        vs_out :
                          begin
-                           if not valid_for_formal_var(left) then
+                           if not valid_for_formal_var(left,true) then
                             CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
                          end;
                        vs_const :
                          begin
-                           if not valid_for_formal_const(left) then
+                           if not valid_for_formal_const(left,true) then
                             CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
                          end;
                      end;
@@ -696,7 +696,7 @@ type
                    begin
                      { check if the argument is allowed }
                      if (parasym.varspez in [vs_out,vs_var]) then
-                       valid_for_var(left);
+                       valid_for_var(left,true);
                    end;
 
                  if parasym.varspez in [vs_var,vs_out] then
@@ -723,11 +723,11 @@ type
                   begin
                     case parasym.varspez of
                       vs_out :
-                        set_varstate(left,vs_used,[]);
+                        set_varstate(left,vs_written,[]);
                       vs_var :
-                        set_varstate(left,vs_used,[vsf_must_be_valid,vsf_use_hints]);
+                        set_varstate(left,vs_readwritten,[vsf_must_be_valid,vsf_use_hints]);
                       else
-                        set_varstate(left,vs_used,[vsf_must_be_valid]);
+                        set_varstate(left,vs_read,[vsf_must_be_valid]);
                     end;
                   end;
                  { must only be done after typeconv PM }
@@ -1619,7 +1619,7 @@ type
          { procedure variable ? }
          if assigned(right) then
            begin
-              set_varstate(right,vs_used,[vsf_must_be_valid]);
+              set_varstate(right,vs_read,[vsf_must_be_valid]);
               resulttypepass(right);
               if codegenerror then
                exit;
@@ -1929,14 +1929,15 @@ type
                     )
                    )
                   ) then
-                 set_varstate(methodpointer,vs_used,[])
+                 set_varstate(methodpointer,vs_read,[])
                else
-                 set_varstate(methodpointer,vs_used,[vsf_must_be_valid]);
+                 set_varstate(methodpointer,vs_read,[vsf_must_be_valid]);
 
                { The object is already used if it is called once }
                if (hpt.nodetype=loadn) and
                   (tloadnode(hpt).symtableentry.typ in [localvarsym,paravarsym,globalvarsym]) then
-                 tabstractvarsym(tloadnode(hpt).symtableentry).varstate:=vs_used;
+                 set_varstate(hpt,vs_read,[]);
+//                 tabstractvarsym(tloadnode(hpt).symtableentry).varstate:=vs_readwritten;
              end;
 
             { if we are calling the constructor check for abstract
@@ -2147,12 +2148,30 @@ type
       end;
 
 
+    function nonlocalvars(var n: tnode; arg: pointer): foreachnoderesult;
+      begin
+        result := fen_false;
+        { this is just to play it safe, there are more safe situations }
+        if (n.nodetype = derefn) or
+           ((n.nodetype = loadn) and
+            { globals and fields of (possibly global) objects could always be changed in the callee }
+            ((tloadnode(n).symtable.symtabletype in [globalsymtable,objectsymtable]) or
+            { statics can only be modified by functions in the same unit }
+             ((tloadnode(n).symtable.symtabletype = staticsymtable) and
+              (tloadnode(n).symtable = tsymtable(arg))))) or
+           ((n.nodetype = subscriptn) and
+            (tsubscriptnode(n).vs.owner.symtabletype = objectsymtable)) then
+          result := fen_norecurse_true;
+      end;
+
+
     procedure tcallnode.createinlineparas(var createstatement, deletestatement: tstatementnode);
       var
         para: tcallparanode;
         tempnode: ttempcreatenode;
         tempnodes: ttempnodes;
         n: tnode;
+        paracomplexity: longint;
       begin
         { parameters }
         para := tcallparanode(left);
@@ -2170,38 +2189,80 @@ type
                 n := para.left.getcopy;
                 para.left.free;
                 para.left := n;
+                firstpass(para.left);
 
                 { create temps for value parameters, function result and also for    }
                 { const parameters which are passed by value instead of by reference }
                 { we need to take care that we use the type of the defined parameter and not of the
                   passed parameter, because these can be different in case of a formaldef (PFV) }
+                paracomplexity := node_complexity(para.left);
+                { check if we have to create a temp, assign the parameter's }
+                { contents to that temp and then substitute the paramter    }
+                { with the temp everywhere in the function                  }
                 if
-                  (
-                   { the problem is that we can't take the address of a function result :( }
-                   (vo_is_funcret in tparavarsym(para.parasym).varoptions) or
-                   (para.parasym.varspez = vs_value) or
-                   ((para.parasym.varspez = vs_const) and
-                    (para.parasym.vartype.def.deftype<>formaldef) and
-                   { the compiler expects that it can take the address of parameters passed by reference in
-                     the case of const so we can't replace the node simply by a constant node
-                     When playing with this code, ensure that
-                     function f(const a,b  : longint) : longint;inline;
-                       begin
-                         result:=a*b;
-                       end;
-
-                     [...]
-                     ...:=f(10,20));
-                     [...]
+                  ((tparavarsym(para.parasym).varregable = vr_none) and
+                   not(para.left.expectloc in [LOC_REFERENCE,LOC_CREFERENCE]))  or
+                  { we can't assign to formaldef temps }
+                  ((para.parasym.vartype.def.deftype<>formaldef) and
+                   (
+                    { if paracomplexity > 1, we normally take the address of   }
+                    { the parameter expression, store it in a temp and         }
+                    { substitute the dereferenced temp in the inlined function }
+                    { We can't do this if we can't take the address of the     }
+                    { parameter expression, so in that case assign to a temp   }
+                    ((paracomplexity > 1) and
+                     (not valid_for_addr(para.left,false) or
+                      (para.left.nodetype = calln) or
+                      is_constnode(para.left))) or
+                    { the problem is that we can't take the address of a function result :( }
+                    (vo_is_funcret in tparavarsym(para.parasym).varoptions) or
+                    { we do not need to create a temp for value parameters }
+                    { which are not modified in the inlined function       }
+                    { const parameters can get vs_readwritten if their     }
+                    { address is taken                                     }
+                    ((((para.parasym.varspez = vs_value) and
+                       (para.parasym.varstate in [vs_initialised,vs_declared,vs_read])) or
+                      { in case of const, this is only necessary if the     }
+                      { variable would be passed by value normally, or if   }
+                      { there is such a variable somewhere in an expression }
+                       ((para.parasym.varspez = vs_const) and
+                        (not paramanager.push_addr_param(vs_const,para.parasym.vartype.def,procdefinition.proccalloption) or
+                         (paracomplexity > 1)))) and
+                     { however, if we pass a global variable, an object field or}
+                     { an expression containing a pointer dereference as        }
+                     { parameter, this value could be modified in other ways as }
+                     { well and in such cases create a temp to be on the safe   }
+                     { side                                                     }
+                     foreachnodestatic(para.left,@nonlocalvars,pointer(symtableproc))) or
+                    { value parameters of which we know they are modified by }
+                    { definition have to be copied to a temp                 }
+                    ((para.parasym.varspez = vs_value) and
+                     not(para.parasym.varstate in [vs_initialised,vs_declared,vs_read])) or
+                    { the compiler expects that it can take the address of parameters passed by reference in
+                      the case of const so we can't replace the node simply by a constant node
+                      When playing with this code, ensure that
+                      function f(const a,b  : longint) : longint;inline;
+                        begin
+                          result:=a*b;
+                        end;
 
-                     is still folded. (FK)
-                     }
-                    (
-                      { this must be a not ... of course }
-                      not(paramanager.push_addr_param(vs_const,para.parasym.vartype.def,procdefinition.proccalloption)) or
-                      (node_complexity(para.left) >= NODE_COMPLEXITY_INF)
-                    ))
-                   ) then
+                      [...]
+                      ...:=f(10,20));
+                      [...]
+
+                      is still folded. (FK)
+                      }
+                    ((para.parasym.varspez = vs_const) and
+                     { const para's can get vs_readwritten if their address }
+                     { is taken                                             }
+                     ((para.parasym.varstate = vs_readwritten) or
+                      { call-by-reference const's may need to be passed by }
+                      { reference to function called in the inlined code   }
+                      (paramanager.push_addr_param(vs_const,para.parasym.vartype.def,procdefinition.proccalloption) and
+                       (not valid_for_addr(para.left,false) or
+                        is_constnode(para.left)))))
+                   )
+                  ) then
                   begin
                     { in theory, this is always regable, but ncgcall can't }
                     { handle it yet in all situations (JM)                 }
@@ -2226,7 +2287,11 @@ type
                         addstatement(deletestatement,ctempdeletenode.create_normal_temp(tempnode));
                       end
                   end
-                else if (node_complexity(para.left) > 1) then
+                { otherwise if the parameter is "complex", take the address   }
+                { of the parameter expression, store it in a temp and replace }
+                { occurrences of the parameter with dereferencings of this    }
+                { temp                                                        }
+                else if (paracomplexity > 1) then
                   begin
                     tempnode := ctempcreatenode.create(voidpointertype,voidpointertype.def.size,tt_persistent,tparavarsym(para.parasym).varregable<>vr_none);
                     addstatement(createstatement,tempnode);

+ 6 - 6
compiler/ncnv.pas

@@ -371,11 +371,11 @@ implementation
                  p3:=nil;
                end;
               resulttypepass(p2);
-              set_varstate(p2,vs_used,[vsf_must_be_valid]);
+              set_varstate(p2,vs_read,[vsf_must_be_valid]);
               if assigned(p3) then
                 begin
                   resulttypepass(p3);
-                  set_varstate(p3,vs_used,[vsf_must_be_valid]);
+                  set_varstate(p3,vs_read,[vsf_must_be_valid]);
                 end;
               if codegenerror then
                break;
@@ -2503,8 +2503,8 @@ implementation
          resulttypepass(left);
          resulttypepass(right);
 
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
 
          if codegenerror then
            exit;
@@ -2615,8 +2615,8 @@ implementation
          resulttypepass(right);
          resulttypepass(left);
 
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
 
          if codegenerror then
            exit;

+ 10 - 7
compiler/nflw.pas

@@ -380,7 +380,7 @@ implementation
          { loop instruction }
          if assigned(right) then
            resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -558,7 +558,7 @@ implementation
          { else path }
          if assigned(t1) then
            resulttypepass(t1);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -819,7 +819,7 @@ implementation
                 cloadnode.create(current_procinfo.procdef.funcretsym,current_procinfo.procdef.funcretsym.owner),
                 left);
             resulttypepass(left);
-            set_varstate(left,vs_used,[vsf_must_be_valid]);
+            set_varstate(left,vs_read,[vsf_must_be_valid]);
           end;
         resulttype:=voidtype;
       end;
@@ -1160,7 +1160,7 @@ implementation
            begin
               { first para must be a _class_ }
               resulttypepass(left);
-              set_varstate(left,vs_used,[vsf_must_be_valid]);
+              set_varstate(left,vs_read,[vsf_must_be_valid]);
               if codegenerror then
                exit;
               if not(is_class(left.resulttype.def)) then
@@ -1289,16 +1289,19 @@ implementation
          resulttype:=voidtype;
 
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         // "try block" is "used"? (JM)
+         set_varstate(left,vs_readwritten,[vsf_must_be_valid]);
 
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         // "except block" is "used"? (JM)
+         set_varstate(right,vs_readwritten,[vsf_must_be_valid]);
 
          { special finally block only executed when there was an exception }
          if assigned(t1) then
            begin
              resulttypepass(t1);
-             set_varstate(t1,vs_used,[vsf_must_be_valid]);
+             // "finally block" is "used"? (JM)
+             set_varstate(t1,vs_readwritten,[vsf_must_be_valid]);
            end;
       end;
 

+ 34 - 34
compiler/ninl.pas

@@ -410,7 +410,7 @@ implementation
             left := filepara.right;
             filepara.right := nil;
             { the file para is a var parameter, but it must be valid already }
-            set_varstate(filepara.left,vs_used,[vsf_must_be_valid]);
+            set_varstate(filepara.left,vs_readwritten,[vsf_must_be_valid]);
             { check if we should make a temp to store the result of a complex }
             { expression (better heuristics, anyone?) (JM)                    }
             if (filepara.left.nodetype <> loadn) then
@@ -1334,7 +1334,7 @@ implementation
                      result:=hp;
                      goto myexit;
                    end;
-                  set_varstate(left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(left,vs_read,[vsf_must_be_valid]);
                   if not is_integer(left.resulttype.def) then
                     CGMessage1(type_e_integer_expr_expected,left.resulttype.def.typename);
                   case inlinenumber of
@@ -1353,7 +1353,7 @@ implementation
 
               in_sizeof_x:
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   if paramanager.push_high_param(vs_value,left.resulttype.def,current_procinfo.procdef.proccalloption) then
                    begin
                      hightree:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
@@ -1374,7 +1374,7 @@ implementation
 
               in_typeof_x:
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   resulttype:=voidpointertype;
                 end;
 
@@ -1387,7 +1387,7 @@ implementation
                       result:=hp;
                       goto myexit;
                     end;
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    case left.resulttype.def.deftype of
                      orddef :
                        begin
@@ -1451,7 +1451,7 @@ implementation
               in_chr_byte:
                 begin
                    { convert to explicit char() }
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    hp:=ctypeconvnode.create_internal(left,cchartype);
                    left:=nil;
                    result:=hp;
@@ -1459,7 +1459,7 @@ implementation
 
               in_length_x:
                 begin
-                  set_varstate(left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(left,vs_read,[vsf_must_be_valid]);
 
                   case left.resulttype.def.deftype of
                     variantdef:
@@ -1571,7 +1571,7 @@ implementation
 
               in_typeinfo_x:
                 begin
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    resulttype:=voidpointertype;
                 end;
 
@@ -1595,7 +1595,7 @@ implementation
                     end;
                   { otherwise handle separately, because there could be a procvar, which }
                   { is 2*sizeof(pointer), while we must only check the first pointer     }
-                  set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                  set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
                   resulttype:=booltype;
                 end;
 
@@ -1604,7 +1604,7 @@ implementation
 
               in_seg_x :
                 begin
-                  set_varstate(left,vs_used,[]);
+                  set_varstate(left,vs_read,[]);
                   result:=cordconstnode.create(0,s32inttype,false);
                   goto myexit;
                 end;
@@ -1612,7 +1612,7 @@ implementation
               in_pred_x,
               in_succ_x:
                 begin
-                   set_varstate(left,vs_used,[vsf_must_be_valid]);
+                   set_varstate(left,vs_read,[vsf_must_be_valid]);
                    resulttype:=left.resulttype;
                    if not is_ordinal(resulttype.def) then
                      CGMessage(type_e_ordinal_expr_expected)
@@ -1655,8 +1655,8 @@ implementation
                   if assigned(left) then
                     begin
                        { first param must be var }
-                       valid_for_var(tcallparanode(left).left);
-                       set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                       valid_for_var(tcallparanode(left).left,true);
+                       set_varstate(tcallparanode(left).left,vs_readwritten,[vsf_must_be_valid]);
 
                        if (left.resulttype.def.deftype in [enumdef,pointerdef]) or
                           is_ordinal(left.resulttype.def) or
@@ -1667,7 +1667,7 @@ implementation
                           { two paras ? }
                           if assigned(tcallparanode(left).right) then
                            begin
-                             set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                             set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                              inserttypeconv_internal(tcallparanode(tcallparanode(left).right).left,tcallparanode(left).left.resulttype);
                              if assigned(tcallparanode(tcallparanode(left).right).right) then
                                CGMessage(parser_e_illegal_expression);
@@ -1723,14 +1723,14 @@ implementation
                   { the parser already checks whether we have two (and exectly two) }
                   { parameters (JM)                                                 }
                   { first param must be var }
-                  valid_for_var(tcallparanode(left).left);
-                  set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                  valid_for_var(tcallparanode(left).left,true);
+                  set_varstate(tcallparanode(left).left,vs_readwritten,[vsf_must_be_valid]);
                   { check type }
                   if (left.resulttype.def.deftype=setdef) then
                     begin
                       { insert a type conversion       }
                       { to the type of the set elements  }
-                      set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(tcallparanode(tcallparanode(left).right).left,
                         tsetdef(left.resulttype.def).elementtype);
                     end
@@ -1771,13 +1771,13 @@ implementation
                            if is_open_array(left.resulttype.def) or
                               is_array_of_const(left.resulttype.def) then
                             begin
-                              set_varstate(left,vs_used,[vsf_must_be_valid]);
+                              set_varstate(left,vs_read,[vsf_must_be_valid]);
                               result:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
                             end
                            else
                             if is_dynamic_array(left.resulttype.def) then
                               begin
-                                set_varstate(left,vs_used,[vsf_must_be_valid]);
+                                set_varstate(left,vs_read,[vsf_must_be_valid]);
                                 { can't use inserttypeconv because we need }
                                 { an explicit type conversion (JM)         }
                                 hp := ccallparanode.create(ctypeconvnode.create_internal(left,voidpointertype),nil);
@@ -1803,7 +1803,7 @@ implementation
                          begin
                            if is_open_string(left.resulttype.def) then
 			     begin
-                               set_varstate(left,vs_used,[vsf_must_be_valid]);
+                               set_varstate(left,vs_read,[vsf_must_be_valid]);
                                result:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry))
 			     end
                            else
@@ -1830,7 +1830,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1851,7 +1851,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=s64inttype;
                     end;
@@ -1872,7 +1872,7 @@ implementation
                     end
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=s64inttype;
                     end;
@@ -1884,7 +1884,7 @@ implementation
                     setconstrealvalue(frac(getconstrealvalue))
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1896,7 +1896,7 @@ implementation
                     setconstrealvalue(int(getconstrealvalue))
                   else
                     begin
-                      set_varstate(left,vs_used,[vsf_must_be_valid]);
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                       inserttypeconv(left,pbestrealtype^);
                       resulttype:=pbestrealtype^;
                     end;
@@ -1916,7 +1916,7 @@ implementation
                    setconstrealvalue(cos(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1928,7 +1928,7 @@ implementation
                    setconstrealvalue(sin(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1940,7 +1940,7 @@ implementation
                    setconstrealvalue(arctan(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1952,7 +1952,7 @@ implementation
                    setconstrealvalue(abs(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -1964,7 +1964,7 @@ implementation
                    setconstrealvalue(sqr(getconstrealvalue))
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      setfloatresulttype;
                    end;
                 end;
@@ -1981,7 +1981,7 @@ implementation
                    end
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      setfloatresulttype;
                    end;
                 end;
@@ -1998,7 +1998,7 @@ implementation
                    end
                   else
                    begin
-                     set_varstate(left,vs_used,[vsf_must_be_valid]);
+                     set_varstate(left,vs_read,[vsf_must_be_valid]);
                      inserttypeconv(left,pbestrealtype^);
                      resulttype:=pbestrealtype^;
                    end;
@@ -2018,11 +2018,11 @@ implementation
                   resulttype:=voidtype;
                   if assigned(left) then
                     begin
-                       set_varstate(tcallparanode(left).left,vs_used,[vsf_must_be_valid]);
+                       set_varstate(tcallparanode(left).left,vs_read,[vsf_must_be_valid]);
                        { check type }
                        if is_boolean(left.resulttype.def) then
                          begin
-                            set_varstate(tcallparanode(tcallparanode(left).right).left,vs_used,[vsf_must_be_valid]);
+                            set_varstate(tcallparanode(tcallparanode(left).right).left,vs_read,[vsf_must_be_valid]);
                             { must always be a string }
                             inserttypeconv(tcallparanode(tcallparanode(left).right).left,cshortstringtype);
                          end

+ 6 - 6
compiler/nld.pas

@@ -576,8 +576,8 @@ implementation
           end;
 
         resulttypepass(right);
-        set_varstate(left,vs_assigned,[]);
-        set_varstate(right,vs_used,[vsf_must_be_valid]);
+        set_varstate(right,vs_read,[vsf_must_be_valid]);
+        set_varstate(left,vs_written,[]);
         if codegenerror then
           exit;
 
@@ -592,7 +592,7 @@ implementation
           CGMessage(type_e_operator_not_allowed);
 
         { test if node can be assigned, properties are allowed }
-        valid_for_assignment(left);
+        valid_for_assignment(left,true);
 
         { assigning nil to a dynamic array clears the array }
         if is_dynamic_array(left.resulttype.def) and
@@ -835,8 +835,8 @@ implementation
         result:=nil;
         resulttypepass(left);
         resulttypepass(right);
-        set_varstate(left,vs_used,[vsf_must_be_valid]);
-        set_varstate(right,vs_used,[vsf_must_be_valid]);
+        set_varstate(left,vs_read,[vsf_must_be_valid]);
+        set_varstate(right,vs_read,[vsf_must_be_valid]);
         if codegenerror then
          exit;
         resulttype:=left.resulttype;
@@ -900,7 +900,7 @@ implementation
            while assigned(hp) do
             begin
               resulttypepass(hp.left);
-              set_varstate(hp.left,vs_used,[vsf_must_be_valid]);
+              set_varstate(hp.left,vs_read,[vsf_must_be_valid]);
               if (htype.def=nil) then
                htype:=hp.left.resulttype
               else

+ 6 - 6
compiler/nmat.pas

@@ -105,8 +105,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -432,8 +432,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -541,7 +541,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -674,7 +674,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[]);
+         set_varstate(left,vs_read,[]);
          if codegenerror then
            exit;
 

+ 19 - 9
compiler/nmem.pas

@@ -430,7 +430,7 @@ implementation
             else
 {$endif i386}
               if (nf_internal in flags) or
-                 valid_for_addr(left) then
+                 valid_for_addr(left,true) then
                 begin
                   if not(nf_typedaddr in flags) then
                     resulttype:=voidpointertype
@@ -443,7 +443,12 @@ implementation
 
          { this is like the function addr }
          inc(parsing_para_level);
-         set_varstate(left,vs_used,[]);
+         { This is actually only "read", but treat it nevertheless as  }
+         { modified due to the possible use of pointers                }
+         { To avoid false positives regarding "uninitialised"          }
+         { warnings when using arrays, perform it in two steps         }
+         set_varstate(left,vs_written,[]);
+         set_varstate(left,vs_read,[]);
          dec(parsing_para_level);
       end;
 
@@ -482,7 +487,7 @@ implementation
       begin
          result:=nil;
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -647,12 +652,17 @@ implementation
            ansi/widestring needs to be valid }
          valid:=is_dynamic_array(left.resulttype.def) or
                 is_ansistring(left.resulttype.def) or
-                is_widestring(left.resulttype.def);
+                is_widestring(left.resulttype.def) or
+                { implicit pointer dereference -> pointer is read }
+                (left.resulttype.def.deftype = pointerdef);
          if valid then
-           set_varstate(left,vs_used,[vsf_must_be_valid])
-         else
-           set_varstate(left,vs_used,[]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+           set_varstate(left,vs_read,[vsf_must_be_valid]);
+{
+         A vecn is, just like a loadn, always part of an expression with its
+         own read/write and must_be_valid semantics. Therefore we don't have
+         to do anything else here, just like for loadn's
+}
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -893,7 +903,7 @@ implementation
         resulttype:=voidtype;
 
         resulttypepass(withrefnode);
-        set_varstate(withrefnode,vs_used,[vsf_must_be_valid]);
+        set_varstate(withrefnode,vs_read,[vsf_must_be_valid]);
         if codegenerror then
          exit;
 

+ 6 - 6
compiler/nset.pas

@@ -142,7 +142,7 @@ implementation
          resulttypepass(left);
          if assigned(right) then
           resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -211,7 +211,7 @@ implementation
          result:=nil;
          resulttype:=booltype;
          resulttypepass(right);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
           exit;
 
@@ -238,7 +238,7 @@ implementation
            end;
 
          resulttypepass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
 
@@ -344,8 +344,8 @@ implementation
          result:=nil;
          resulttypepass(left);
          resulttypepass(right);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
-         set_varstate(right,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
+         set_varstate(right,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
          { both types must be compatible }
@@ -595,7 +595,7 @@ implementation
          expectloc:=LOC_VOID;
          { evalutes the case expression }
          firstpass(left);
-         set_varstate(left,vs_used,[vsf_must_be_valid]);
+         set_varstate(left,vs_read,[vsf_must_be_valid]);
          if codegenerror then
            exit;
          registersint:=left.registersint;

+ 1 - 1
compiler/pdecvar.pas

@@ -656,7 +656,7 @@ implementation
               symtablestack.insert(tcsym);
               readtypedconst(tt,tcsym,false);
               { The variable has a value assigned }
-              vs.varstate:=vs_assigned;
+              vs.varstate:=vs_initialised;
             end
           else
             begin

+ 3 - 4
compiler/pexports.pas

@@ -1,5 +1,5 @@
 {
-    Copyright (c) 1998-2002 by Florian Klaempfl
+    Copyright (c) 1998-2005 by Florian Klaempfl
 
     This unit handles the exports parsing
 
@@ -28,8 +28,6 @@ interface
     { reads an exports statement in a library }
     procedure read_exports;
 
-    var
-      BinaryContainsExports: boolean = false;
 implementation
 
     uses
@@ -38,6 +36,7 @@ implementation
        { global }
        globals,tokens,verbose,
        systems,
+       ppu,fmodule,
        { symtable }
        symconst,symbase,symtype,symsym,
        { pass 1 }
@@ -78,7 +77,7 @@ implementation
         end;
 
       begin
-         BinaryContainsExports:=true;
+         current_module.flags:=current_module.flags or uf_has_exports;
          DefString:='';
          InternalProcName:='';
          consume(_EXPORTS);

+ 5 - 5
compiler/pinline.pas

@@ -79,9 +79,9 @@ implementation
         p:=comp_expr(true);
         { calc return type }
         if is_new then
-          set_varstate(p,vs_assigned,[])
+          set_varstate(p,vs_written,[])
         else
-          set_varstate(p,vs_used,[vsf_must_be_valid]);
+          set_varstate(p,vs_readwritten,[vsf_must_be_valid]);
         if (m_mac in aktmodeswitches) and
            is_class(p.resulttype.def) then
           begin
@@ -474,7 +474,7 @@ implementation
            ppn:=tcallparanode(paras);
            while assigned(ppn.right) do
             begin
-              set_varstate(ppn.left,vs_used,[vsf_must_be_valid]);
+              set_varstate(ppn.left,vs_read,[vsf_must_be_valid]);
               inserttypeconv(ppn.left,sinttype);
               inc(dims);
               ppn:=tcallparanode(ppn.right);
@@ -489,8 +489,8 @@ implementation
         { last param must be var }
         destppn:=ppn.left;
         inc(parsing_para_level);
-        valid_for_var(destppn);
-        set_varstate(destppn,vs_assigned,[]);
+        valid_for_var(destppn,true);
+        set_varstate(destppn,vs_written,[]);
         dec(parsing_para_level);
         { first param must be a string or dynamic array ...}
         isarray:=is_dynamic_array(destppn.resulttype.def);

+ 4 - 7
compiler/pmodules.pas

@@ -1548,7 +1548,7 @@ implementation
            DLL will include the edata section }
          if assigned(exportlib) and
             (target_info.system in [system_i386_win32,system_i386_wdosx]) and
-            BinaryContainsExports then
+            ((current_module.flags and uf_has_exports)<>0) then
            codesegment.concat(tai_const.create_sym(exportlib.edatalabel));
 
          If ResourceStrings.ResStrCount>0 then
@@ -1626,9 +1626,7 @@ implementation
          if current_module.uses_imports then
            importlib.generatelib;
 
-         if islibrary or
-            (target_info.system in [system_i386_WIN32,system_i386_wdosx]) or
-            (target_info.system=system_i386_NETWARE) then
+         if islibrary or (target_info.system in system_unit_program_exports) then
            exportlib.generatelib;
 
          { insert Tables and StackLength }
@@ -1680,10 +1678,9 @@ implementation
             if (not current_module.is_unit) then
              begin
                if DLLSource then
-                linker.MakeSharedLibrary
+                 linker.MakeSharedLibrary
                else
-                linker.MakeExecutable;
-               BinaryContainsExports:=false;
+                 linker.MakeExecutable;
              end;
           end;
       end;

+ 3 - 2
compiler/ppu.pas

@@ -152,8 +152,9 @@ const
   uf_local_symtable = $20000; { this unit has a local symtable stored }
   uf_uses_variants  = $40000; { this unit uses variants }
   uf_has_resourcefiles = $80000; { this unit has external resources (using $R directive)}
-  
-  
+  uf_has_exports = $100000;   { this module or a used unit has exports }
+
+
 type
   ppureal=extended;
 

+ 5 - 5
compiler/pstatmnt.pas

@@ -125,7 +125,7 @@ implementation
          caseexpr:=comp_expr(true);
          { determines result type }
          do_resulttypepass(caseexpr);
-         set_varstate(caseexpr,vs_used,[vsf_must_be_valid]);
+         set_varstate(caseexpr,vs_read,[vsf_must_be_valid]);
          casedeferror:=false;
          casedef:=caseexpr.resulttype.def;
          if (not assigned(casedef)) or
@@ -412,11 +412,11 @@ implementation
            needs to be done before the instruction block is
            parsed to have a valid hloopvar }
          resulttypepass(hfrom);
-         set_varstate(hfrom,vs_used,[vsf_must_be_valid]);
+         set_varstate(hfrom,vs_read,[vsf_must_be_valid]);
          resulttypepass(hto);
-         set_varstate(hto,vs_used,[vsf_must_be_valid]);
+         set_varstate(hto,vs_read,[vsf_must_be_valid]);
          resulttypepass(hloopvar);
-         set_varstate(hloopvar,vs_used,[]);
+         set_varstate(hloopvar,vs_readwritten,[]);
 
          { ... now the instruction block }
          hblock:=statement;
@@ -1170,7 +1170,7 @@ implementation
         }
         if assigned(current_procinfo.procdef.funcretsym) and
            (not paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption)) then
-          tabstractvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_assigned;
+          tabstractvarsym(current_procinfo.procdef.funcretsym).varstate:=vs_initialised;
 
         { because the END is already read we need to get the
           last_endtoken_filepos here (PFV) }

+ 1 - 1
compiler/rautils.pas

@@ -801,7 +801,7 @@ Begin
       begin
         { we always assume in asm statements that     }
         { that the variable is valid.                 }
-        tabstractvarsym(sym).varstate:=vs_used;
+        tabstractvarsym(sym).varstate:=vs_readwritten;
         inc(tabstractvarsym(sym).refs);
         { variable can't be placed in a register }
         tabstractvarsym(sym).varregable:=vr_none;

+ 1 - 1
compiler/symconst.pas

@@ -369,7 +369,7 @@ type
 
   { State of the variable, if it's declared, assigned or used }
   tvarstate=(vs_none,
-    vs_declared,vs_assigned,vs_used
+    vs_declared,vs_initialised,vs_read,vs_written,vs_readwritten
   );
 
   tvarspez = (vs_value,vs_const,vs_var,vs_out);

+ 1 - 1
compiler/symsym.pas

@@ -1313,7 +1313,7 @@ implementation
     constructor tabstractvarsym.ppuload(ppufile:tcompilerppufile);
       begin
          inherited ppuload(ppufile);
-         varstate:=vs_used;
+         varstate:=vs_readwritten;
          varspez:=tvarspez(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
          ppufile.gettype(_vartype);

+ 1 - 1
compiler/symtable.pas

@@ -737,7 +737,7 @@ implementation
                 else
                   MessagePos1(tsym(p).fileinfo,sym_n_local_identifier_not_used,tsym(p).realname);
              end
-           else if tabstractvarsym(p).varstate=vs_assigned then
+           else if tabstractvarsym(p).varstate in [vs_written,vs_initialised] then
              begin
                 if (tsym(p).owner.symtabletype=parasymtable) then
                   begin

+ 23 - 1
compiler/systems/t_linux.pas

@@ -228,7 +228,7 @@ begin
   with Info do
    begin
      ExeCmd[1]:='ld $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $RES';
-     DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
+     DllCmd[1]:='ld $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES -E';
      DllCmd[2]:='strip --strip-unneeded $EXE';
 {$ifdef m68k}
      libctype:=glibc2;
@@ -448,6 +448,23 @@ begin
 end;
 
 
+function contains_exports : boolean;
+  var
+    hp : tused_unit;
+  begin
+    result:=((current_module.flags and uf_has_exports)=uf_has_exports);
+    if not result then
+      begin
+      hp:=tused_unit(usedunits.first);
+      While Assigned(hp) and not result do
+        begin
+          result:=((hp.u.flags and uf_has_exports)=uf_has_exports);
+          hp:=tused_unit(hp.next);
+        end;
+      end;
+  end;
+
+
 function TLinkerLinux.MakeExecutable:boolean;
 var
   binstr : String;
@@ -495,6 +512,11 @@ begin
   Replace(cmdstr,'$STRIP',StripStr);
   Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
   Replace(cmdstr,'$DYNLINK',DynLinkStr);
+
+  { create dynamic symbol table? }
+  if contains_exports then
+    cmdstr:=cmdstr+' -E';
+
   success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
 
 { Remove ReponseFile }

+ 2 - 0
rtl/linux/i386/prt0.as

@@ -83,6 +83,8 @@ ___fpucw:
         .type   ___fpc_brk_addr,@object
 	.comm   ___fpc_brk_addr,4        /* heap management */
 
+        .type operatingsystem_parameters,@object
+        .size operatingsystem_parameters,12
 operatingsystem_parameters:
 	.skip 3*4
 

BIN
tests/test/cg/obj/linux/x86_64/tcext3.o


BIN
tests/test/cg/obj/linux/x86_64/tcext4.o


+ 43 - 0
tests/test/tinline6.pp

@@ -0,0 +1,43 @@
+{$inline on}
+{$mode objfpc}
+
+type
+  tc = class
+    lf: longint;
+    procedure t(l: longint); inline;
+  end;
+
+var
+  a: longint;
+
+procedure tc.t(l: longint); inline;
+begin
+  lf := 10;
+  if (l <> 5) then
+    begin
+      writeln('error class');
+      halt(1);
+    end;
+end;
+
+
+procedure t(l: longint); inline;
+begin
+  a := 10;
+  if (l <> 5) then
+    begin
+      writeln('error proc');
+      halt(1);
+    end;
+end;
+
+var
+  c: tc;
+
+begin
+  c := tc.create;
+  c.lf := 5;
+  c.t(c.lf);
+  a := 5;
+  t(a);
+end.