Procházet zdrojové kódy

* check callerside if calleeside isn't available in is_ecx_used. Based on the
patch by Do-wan Kim, mantis #25269.

git-svn-id: trunk@26101 -

nickysn před 11 roky
rodič
revize
fbca7ee2cb
3 změnil soubory, kde provedl 41 přidání a 1 odebrání
  1. 1 0
      .gitattributes
  2. 9 1
      compiler/i386/cgcpu.pas
  3. 31 0
      tests/webtbs/tw25269.pp

+ 1 - 0
.gitattributes

@@ -13646,6 +13646,7 @@ tests/webtbs/tw2514.pp svneol=native#text/plain
 tests/webtbs/tw25198.pp svneol=native#text/plain
 tests/webtbs/tw25210.pp svneol=native#text/pascal
 tests/webtbs/tw2525.pp svneol=native#text/plain
+tests/webtbs/tw25269.pp svneol=native#text/pascal
 tests/webtbs/tw2536.pp svneol=native#text/plain
 tests/webtbs/tw2540.pp svneol=native#text/plain
 tests/webtbs/tw2561.pp svneol=native#text/plain

+ 9 - 1
compiler/i386/cgcpu.pas

@@ -648,13 +648,21 @@ unit cgcpu;
           i: Integer;
           hp: tparavarsym;
           paraloc: PCGParaLocation;
+          side: tcallercallee;
         begin
           if not (RS_ECX in paramanager.get_volatile_registers_int(procdef.proccalloption)) then
             exit(true);
           for i:=0 to procdef.paras.count-1 do
            begin
              hp:=tparavarsym(procdef.paras[i]);
-             paraloc:=hp.paraloc[calleeside].Location;
+             if procdef.has_paraloc_info in [calleeside,callbothsides] then
+               side:=calleeside
+             { in the case of virtual abstract methods, we only have callerside }
+             else if procdef.has_paraloc_info=callerside then
+               side:=callerside
+             else
+               internalerror(2013111601);
+             paraloc:=hp.paraloc[side].Location;
              while paraloc<>nil do
                begin
                  if (paraloc^.Loc=LOC_REGISTER) and (getsupreg(paraloc^.register)=RS_ECX) then

+ 31 - 0
tests/webtbs/tw25269.pp

@@ -0,0 +1,31 @@
+{$MODE objfpc}
+
+type
+  IMyInterface = interface
+    procedure Test(a, b: Integer);
+  end;
+  TMyBaseClass = class(TInterfacedObject, IMyInterface)
+    procedure Test(a, b: Integer); virtual; abstract;
+  end;
+  TDescendent = class(TMyBaseClass)
+    procedure Test(a, b: Integer); override;
+  end;
+
+var
+  global_a, global_b: Integer;
+
+procedure TDescendent.Test(a, b: Integer);
+begin
+  global_a := a;
+  global_b := b;
+end;
+
+var
+  q: IMyInterface;
+begin
+  q := TDescendent.Create;
+  q.Test(18, 42);
+  if (global_a <> 18) or (global_b <> 42) then
+    halt(1);
+  Writeln('Ok!');
+end.