Kryvich 165 Posted January 24, 2019 Hi, I try to adopt outstanding and free Pas2js transpiler to Delphi language. My main development IDE is Delphi CE Rio, so I decided to try a new Delphi syntax: generic collections and inline variables. And stumbled upon a runtime error. The code (simplified): program TestInlineVarForDictionary; {$APPTYPE CONSOLE} {$R *.res} uses SysUtils, Generics.Collections; procedure TestDictErr; var Dict: TDictionary<string,TObject>; begin Dict := TDictionary<string,TObject>.Create; for var item in Dict do Writeln('Key = ', item.Key, 'Name = ', item.Value.ClassName); end; procedure TestDictOK; var Dict: TDictionary<string,TObject>; item: TPair<string,TObject>; begin Dict := TDictionary<string,TObject>.Create; for item in Dict do Writeln('Key = ', item.Key, 'Name = ', item.Value.ClassName); end; begin try //!!TestDictOK; TestDictErr; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); Write('Press Enter to continue...'); Readln; end; end; end. This program causes Exception class $C0000005 with message 'access violation at 0x0040a86e: write of address 0x0040a29e'. Can you confirm it? Is it a bug in the compiler or/and RTL, or am I misusing the new syntax? It's interesting: if you uncomment TestDictOK that does enumeration in old-style, the exception will disappear! Share this post Link to post
Kryvich 165 Posted January 25, 2019 (edited) Another observation. The exception occurs only if the dictionary has the key and/or value of the string type. If I change it to Integer - the exception disappears. procedure TestDictErr_IntegerKey_OK; var Dict: TDictionary<Integer,TObject>; begin Dict := TDictionary<Integer,TObject>.Create; for var item in Dict do Writeln('Key = ', item.Key, 'Name = ', item.Value.ClassName); end; Well, I just found it. For procedure TestDictOK the compiler generates a pair of calls: call @InitializeRecord call @FinalizeRecord But for procedure TestDictErr it generates only call @FinalizeRecord Program tries to finalize not initialized record and falls. P.S. Is there a bug bounty program for Delphi? :) https://quality.embarcadero.com/browse/RSP-23417 Edited January 25, 2019 by Kryvich Share this post Link to post
Kryvich 165 Posted January 25, 2019 OK I have a workaround for this issue. Try to specify a type of the inline variable. procedure TestDictErr_WorkAround; var Dict: TDictionary<string,TObject>; begin Dict := TDictionary<string,TObject>.Create; for var item: TPair<string,TObject> in Dict do Writeln('Key = ', item.Key, ' Name = ', item.Value.ClassName); end; I cannot guarantee that this code will be correctly compiled. But at least there is no the runtime error anymore. Share this post Link to post
Stefan Glienke 2002 Posted January 25, 2019 This bug has already been reported before but since QP is not responding right now I cannot look for it. 1 Share this post Link to post