Jelajahi Sumber

* Fix handling of Windows WideString typed constants, resolves #15842 and completes the related #14308:
* Do not initialize unused symbols, because finalization code is not generated for them either.
* Always initialize/finalize such constants, even if they are declared in {$J-} state and cannot be modified by user code.

git-svn-id: trunk@18121 -

sergei 14 tahun lalu
induk
melakukan
fec5dde5b6

+ 8 - 2
compiler/ncgutil.pas

@@ -1510,7 +1510,10 @@ implementation
         include(current_procinfo.flags,pi_needs_implicit_finally);
         OldAsmList:=current_asmdata.CurrAsmList;
         current_asmdata.CurrAsmList:=asmlist;
-        hp:=finalize_data_node(cloadnode.create(sym,sym.owner));
+        hp:=cloadnode.create(sym,sym.owner);
+        if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
+          include(hp.flags,nf_isinternal_ignoreconst);
+        hp:=finalize_data_node(hp);
         firstpass(hp);
         secondpass(hp);
         hp.free;
@@ -1548,7 +1551,10 @@ implementation
                     they may also be used in another unit
                   }
                   (tstaticvarsym(p).owner.symtabletype=globalsymtable)) and
-                 (tstaticvarsym(p).varspez<>vs_const) and
+                  (
+                    (tstaticvarsym(p).varspez<>vs_const) or
+                    (vo_force_finalize in tstaticvarsym(p).varoptions)
+                  ) and
                  not(vo_is_funcret in tstaticvarsym(p).varoptions) and
                  not(vo_is_external in tstaticvarsym(p).varoptions) and
                  is_managed_type(tstaticvarsym(p).vardef) then

+ 8 - 4
compiler/pmodules.pas

@@ -243,10 +243,14 @@ implementation
         new_section(current_asmdata.asmlists[al_globals],sec_data,s,sizeof(pint));
         current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global(s,AT_DATA,0));
         repeat
-          { address to initialize }
-          current_asmdata.asmlists[al_globals].concat(Tai_const.createname(item.sym.mangledname, item.offset));
-          { value with which to initialize }
-          current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(item.datalabel));
+          { optimize away unused local/static symbols }
+          if (item.sym.refs>0) or (item.sym.owner.symtabletype=globalsymtable) then
+            begin
+              { address to initialize }
+              current_asmdata.asmlists[al_globals].concat(Tai_const.createname(item.sym.mangledname, item.offset));
+              { value with which to initialize }
+              current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(item.datalabel));
+            end;
           item:=TTCInitItem(item.Next);
         until item=nil;
         { end-of-list marker }

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 133;
+  CurrentPPUVersion = 134;
 
 { buffer sizes }
   maxentrysize = 1024;

+ 8 - 2
compiler/ptconst.pas

@@ -172,6 +172,7 @@ implementation
         list   : tasmlist;
         origsym: tstaticvarsym;
         offset:  asizeint;
+        origblock: tblock_type;
       end;
 
     { this procedure reads typed constants }
@@ -748,13 +749,17 @@ implementation
                               strval,
                               winlike);
 
-                       { collect global Windows widestrings }
-                       if winlike and (hr.origsym.owner.symtablelevel <= main_program_level) then
+                       { Collect Windows widestrings that need initialization at startup.
+                         Local initialized vars are excluded because they are initialized
+                         at function entry instead. }
+                       if winlike and ((hr.origsym.owner.symtablelevel <= main_program_level) or
+                         (hr.origblock=bt_const)) then
                        begin
                          current_asmdata.WideInits.Concat(
                             TTCInitItem.Create(hr.origsym, hr.offset, ll)
                          );
                          ll := nil;
+                         Include(hr.origsym.varoptions, vo_force_finalize);
                        end;
                      end;
                      hr.list.concat(Tai_const.Create_sym(ll));
@@ -1457,6 +1462,7 @@ implementation
         hrec.list:=tasmlist.create;
         hrec.origsym:=sym;
         hrec.offset:=0;
+        hrec.origblock:=block_type;
         read_typed_const_data(hrec,sym.vardef);
 
         { Parse hints }

+ 4 - 1
compiler/symconst.pas

@@ -433,7 +433,10 @@ type
     { first field of variant part of a record }
     vo_is_first_field,
     vo_volatile,
-    vo_has_section
+    vo_has_section,
+    { variable contains a winlike WideString which should be finalized
+      even in $J- state }
+    vo_force_finalize
   );
   tvaroptions=set of tvaroption;
 

+ 2 - 1
compiler/utils/ppudump.pp

@@ -1232,7 +1232,8 @@ const
      (mask:vo_is_weak_external;str:'WeakExternal'),
      (mask:vo_is_first_field;str:'IsFirstField'),
      (mask:vo_volatile;str:'Volatile'),
-     (mask:vo_has_section;str:'HasSection')
+     (mask:vo_has_section;str:'HasSection'),
+     (mask:vo_force_finalize;str:'ForceFinalize')
   );
 var
   i : longint;