Ver código fonte

* Managed types passed to out formal parameters must be completely cleaned (decrementing refcount is not enough) at caller side, because callee side doesn't know their actual type and cannot initialize them. Resolves #20962.

git-svn-id: trunk@19956 -
sergei 13 anos atrás
pai
commit
b1cbf30a94
3 arquivos alterados com 37 adições e 0 exclusões
  1. 1 0
      .gitattributes
  2. 4 0
      compiler/ncgcal.pas
  3. 32 0
      tests/webtbs/tw20962.pp

+ 1 - 0
.gitattributes

@@ -12052,6 +12052,7 @@ tests/webtbs/tw20872c.pp svneol=native#text/pascal
 tests/webtbs/tw20874a.pp svneol=native#text/pascal
 tests/webtbs/tw20874b.pp svneol=native#text/pascal
 tests/webtbs/tw20889.pp svneol=native#text/pascal
+tests/webtbs/tw20962.pp svneol=native#text/plain
 tests/webtbs/tw20995a.pp svneol=native#text/pascal
 tests/webtbs/tw20995b.pp svneol=native#text/pascal
 tests/webtbs/tw2109.pp svneol=native#text/plain

+ 4 - 0
compiler/ncgcal.pas

@@ -180,6 +180,10 @@ implementation
                            href,third.location,'FPC_DECREF_ARRAY');
                        end;
                    end
+                 else if (resultdef.typ=formaldef) then
+                   { stuff being passed to formal parameter has to be completely cleaned,
+                     because it cannot be initialized at callee side (bug #20962) }
+                   cg.g_finalize(current_asmdata.CurrAsmList,left.resultdef,href)
                  else
                    cg.g_decrrefcount(current_asmdata.CurrAsmList,left.resultdef,href);
                end;

+ 32 - 0
tests/webtbs/tw20962.pp

@@ -0,0 +1,32 @@
+{ %opt=-gh }
+
+program outpar;
+{$ifdef FPC}{$mode objfpc}{$h+}{$endif}
+{$ifdef mswindows}{$apptype console}{$endif}
+uses
+ {$ifdef FPC}{$ifdef linux}cthreads,cwstring,{$endif}{$endif}
+ sysutils;
+{$ifndef FPC}
+type
+ sizeint = integer;
+{$endif}
+type 
+ pinteger = ^integer;
+procedure testproc(out str);
+begin
+ ansistring(str):= '';
+end;
+
+var
+ str1,str2: ansistring;
+
+begin
+ setlength(str1,5);
+ move('abcde',str1[1],5);
+ str2:= str1;
+ testproc(str2);
+ if pinteger(pchar(pointer(str1))-2*sizeof(sizeint))^ <> 1 then
+   Halt(1);
+ if str1<>'abcde' then
+   Halt(2);  
+end.