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

Генерирует неправильную подпрограмму для record при преобразовании object -> T #1160

Closed
MrSpecular opened this issue Sep 6, 2018 · 3 comments
Labels

Comments

@MrSpecular
Copy link

MrSpecular commented Sep 6, 2018

type
  TSome = record
    fX: integer := 1;
    
    function GetX() := fX;
  end;

function CastTo<T>(reference: object) := T(reference); // Если T заменить на TSome, то все нормально.

begin
  Writeln('Без CastTo<T>:');
  Writeln((new TSome()).GetX());
  
  var a1 := new TSome();
  Writeln(a1.GetX());
  
  Writeln((new TSome()).fX);
  
  var a2 := new TSome();
  Writeln(a2.fX);
  
  Writeln('С CastTo<T>:');
  Writeln(CastTo&<TSome>(new TSome()).GetX()); // 0, вместо 1.
  
  var a3 := CastTo&<TSome>(new TSome());
  Writeln(a3.GetX());
  
  Writeln(CastTo&<TSome>(new TSome()).fX);
  
  var a4 := CastTo&<TSome>(new TSome());
  Writeln(a4.fX);
end.

Минимизированный пример:

type
  TSome = record 
    fX: integer := 1;
    
    function Method()  := fX; 
  end;

function CastTo<T>(reference: object) := T(reference); 

begin
  Writeln(CastTo&<TSome>(new TSome()).Method()); // 0, вместо 1.
end.
@SunSerega
Copy link
Contributor

Нет. Та серия характеризуется не только выводом мусора при работе с записями. Там всегда создавался лишний указатель, и использовался вместо значения. А тут что то другое, скорее всего с box связанное... Сейчас разберусь.

@SunSerega
Copy link
Contributor

А, нашёл.

Правильный вариант:

    IL_001b: call         !!0/*valuetype Program2.TSome*/ Program2.Program::CastTo<valuetype Program2.TSome>(object)
    IL_0020: stloc.0      // V_0
    IL_0021: ldloca.s     V_0
    IL_0023: call         instance int32 Program2.TSome::Method()

Что происходит, если писать всё вместе, на одной строчке:

    IL_0014: call         !!0/*valuetype Program1.TSome*/ Program1.Program::CastTo<valuetype Program1.TSome>(object)
    IL_0019: call         instance int32 Program1.TSome::Method()

То есть, если писать всё на одной строчке - компилятор забывает создать указатель на полученное из CastTo значение, и выполняет Method для значения вместо указателя, отсюда мусор.

@MrSpecular это новый тип ошибки, он не связан с той древней цепочкой.

@ibond84 ibond84 added the bug label Sep 6, 2018
@MrSpecular
Copy link
Author

Поправил.

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

3 participants