Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Генерирует неправильную программу для (function: record).f1 #974

Closed
SunSerega opened this issue Jul 14, 2018 · 1 comment
Labels

Comments

@SunSerega
Copy link
Contributor

SunSerega commented Jul 14, 2018

type
  
  r1 = record
    
    public X, Y: Single;
    
    public constructor create(X, Y: Single);
    begin
      self.X := X;
      self.Y := Y;
    end;
    
    public function f1 := self.X;
    
    class function GetR1 := new r1(3,4);
    
  end;
  
function GetR1 := new r1(1,2);

begin
  
  writeln( GetR1.f1 );//Выводит мусор
  writeln( r1.GetR1.f1 );//Выводит мусор
  
end.

Эта issue из серии #901, #910, #974 и #978. Снова ломается только для записи, и снова ошибка в том, что загружает адрес переменной, вместо её значения.

В C# виде:

    public static void \u0024Main()
    {
      r1 r1_1 = Program.GetR1();
      // ISSUE: explicit reference operation
      PABCSystem.PABCSystem.Writeln((object) ((r1) @r1_1).f1());

      r1 r1_2 = r1.GetR1();
      // ISSUE: explicit reference operation
      PABCSystem.PABCSystem.Writeln((object) ((r1) @r1_2).f1());
    }

В IL виде:

  .method public static void 
    $Main() cil managed 
  {
    .maxstack 1
    .locals init (
      [0] valuetype '0.r1' r1_1,
      [1] valuetype '0.r1' V_1,
      [2] valuetype '0.r1' r1_2,
      [3] valuetype '0.r1' V_3
    )

    IL_0000: nop          

    // [36 7 - 36 32]
    IL_0001: call         valuetype '0.r1' '0.Program'::GetR1() //Глобальная функция
    IL_0006: stloc.0      // r1_1

    // [38 7 - 38 64]
    IL_0007: ldloca.s     r1_1     //загружает адрес результата GetR1, и это не правильно
    IL_0009: stloc.1      // V_1   //сохраняет в V_1
    IL_000a: ldloca.s     V_1      //в итоге "0.r1::f1" выполняется для указателя вместо r1
    IL_000c: call         instance float32 '0.r1'::f1()
    IL_0011: box          [mscorlib]System.Single
    IL_0016: call         void PABCSystem.PABCSystem::Writeln(object)
    IL_001b: nop          

    // [39 7 - 39 27]
    IL_001c: call         valuetype '0.r1' '0.r1'::GetR1()  //И для статичной функции так же. Ну и правильно, на самом деле они обе статичные
    IL_0021: stloc.2      // r1_2

    // [41 7 - 41 64]
    IL_0022: ldloca.s     r1_2
    IL_0024: stloc.3      // V_3
    IL_0025: ldloca.s     V_3
    IL_0027: call         instance float32 '0.r1'::f1()
    IL_002c: box          [mscorlib]System.Single
    IL_0031: call         void PABCSystem.PABCSystem::Writeln(object)
    IL_0036: nop          
    IL_0037: ret          

  } // end of method Program::$Main

Как и в предыдущих issue из этой серии - если разнести это на 2 строчки:

  var a:=GetR1;
  writeln(a.f1);

то ошибка пропадает.

@SunSerega
Copy link
Contributor Author

@ibond84 так а что с #978 всё же?

ibond84 added a commit that referenced this issue Jul 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants