Ver Fonte

* Changed code generation for variant assignments to typecast arguments to TVarData instead of using pointers. Fixes one (probably the ugliest one) case of non-disposed temp variables:
When arguments are temps, they are supposed to be released by tcgcallnode.release_para_temps. However, taking address with taddrnode effectively changes original location of temp to some LOC_REGISTER, tcgcallnode.release_para_temps no longer sees the original location and therefore does not free such temps.

git-svn-id: trunk@19959 -

sergei há 13 anos atrás
pai
commit
49700e675c
4 ficheiros alterados com 29 adições e 3 exclusões
  1. 8 3
      compiler/nld.pas
  2. 1 0
      compiler/options.pas
  3. 5 0
      rtl/inc/compproc.inc
  4. 15 0
      rtl/inc/variant.inc

+ 8 - 3
compiler/nld.pas

@@ -163,7 +163,7 @@ implementation
 
     uses
       cutils,verbose,globtype,globals,systems,
-      symnot,
+      symnot,symtable,
       defutil,defcmp,
       htypechk,pass_1,procinfo,paramgr,
       cpuinfo,
@@ -696,6 +696,7 @@ implementation
       var
         hp: tnode;
         oldassignmentnode : tassignmentnode;
+        hdef: tdef;
       begin
          result:=nil;
          expectloc:=LOC_VOID;
@@ -769,10 +770,14 @@ implementation
           vararrays which must be really copied }
         else if left.resultdef.typ=variantdef then
          begin
+           { remove property flag to avoid errors, see comments for }
+           { tf_winlikewidestring assignments below                 }
+           exclude(left.flags,nf_isproperty);
+           hdef:=search_system_type('TVARDATA').typedef;
            hp:=ccallparanode.create(ctypeconvnode.create_internal(
-                 caddrnode.create_internal(right),voidpointertype),
+                 right,hdef),
                ccallparanode.create(ctypeconvnode.create_internal(
-                 caddrnode.create_internal(left),voidpointertype),
+                 left,hdef),
                nil));
            result:=ccallnode.createintern('fpc_variant_copy',hp);
            firstpass(result);

+ 1 - 0
compiler/options.pas

@@ -2504,6 +2504,7 @@ begin
   def_system_macro('FPC_HAS_OPERATOR_ENUMERATOR');
   def_system_macro('FPC_HAS_CONSTREF');
   def_system_macro('FPC_STATICRIPFIXED');
+  def_system_macro('FPC_VARIANTCOPY_FIXED');
 {$if defined(x86) or defined(powerpc) or defined(powerpc64)}
   def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
 {$endif}

+ 5 - 0
rtl/inc/compproc.inc

@@ -438,8 +438,13 @@ function fpc_SetupReadStr_Widestr(const s: widestring): PText; compilerproc;
 {$ifdef FPC_HAS_FEATURE_VARIANTS}
 procedure fpc_variant_init(var v: tvardata);compilerproc;
 procedure fpc_variant_clear(var v: tvardata);compilerproc;
+{$ifdef FPC_VARIANTCOPY_FIXED}
+procedure fpc_variant_copy(var d: tvardata; const s : tvardata);compilerproc;
+procedure fpc_variant_copy_overwrite(const source: tvardata; var dest : tvardata);compilerproc;
+{$else FPC_VARIANTCOPY_FIXED}
 procedure fpc_variant_copy(d,s : pointer);compilerproc;
 procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc;
+{$endif FPC_VARIANTCOPY_FIXED}
 procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); compilerproc;
 function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
 function fpc_dynarray_to_variant(dynarr : pointer;typeinfo : pointer) : variant;compilerproc;

+ 15 - 0
rtl/inc/variant.inc

@@ -45,6 +45,20 @@ procedure variant_addref(var v : tvardata);[Public,Alias:'FPC_VARIANT_ADDREF'];
       VarAddRefProc(v);
   end;
 
+{$ifdef FPC_VARIANTCOPY_FIXED}
+procedure fpc_variant_copy(var d: tvardata; const s : tvardata);[Public,Alias:'FPC_VARIANT_COPY']; compilerproc;
+  begin
+    if assigned(VarCopyProc) then
+      VarCopyProc(d,s);
+  end;
+
+procedure fpc_variant_copy_overwrite(const source: tvardata; var dest : tvardata);[Public,Alias:'FPC_VARIANT_COPY_OVERWRITE']; compilerproc;
+  begin
+    dest.VType := varEmpty;
+    if assigned(VarCopyProc) then
+      VarCopyProc(dest,source);
+  end;
+{$else FPC_VARIANTCOPY_FIXED}
 { using pointers as argument here makes life for the compiler easier }
 procedure fpc_variant_copy(d,s : pointer);[Public,Alias:'FPC_VARIANT_COPY']; compilerproc;
   begin
@@ -59,6 +73,7 @@ procedure fpc_variant_copy_overwrite(source, dest : pointer);[Public,Alias:'FPC_
     if assigned(VarCopyProc) then
       VarCopyProc(tvardata(dest^),tvardata(source^));
   end;
+{$endif FPC_VARIANTCOPY_FIXED}
 
 Procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); iocheck; [Public,Alias:'FPC_WRITE_TEXT_VARIANT']; compilerproc;
   begin