Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Generics    [ Add a report in this area ]  
Report #:  118417   Status: Closed
Compiler fails to prevent compilation of "type1 is/as type2" when type1 is parameterized
Project:  Delphi Build #:  XE3, XE4
Version:    18.1 Submitted By:   Asbjørn Heid
Report Type:  Crash / Data loss / Total failure Date Reported:  8/29/2013 4:43:38 AM
Severity:    Infrequently encountered problem Last Updated: 4/15/2014 6:41:39 PM
Platform:    All platforms Internal Tracking #:   42819
Resolution: Fixed (Resolution Comments) Resolved in Build: : XE6
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: 10
Description
The operators "is" and "as" requires that the first parameter is an instance, and the compiler produces an error if this is not the case.

However if the first parameter is a parameterized type, the compiler fails to raise the error, and instead compiles the code. The resulting code produces and Access Violation at runtime.

The attached code should not compile, instead it should generate the error message "E2015 Operator not applicable to this operand type".

While the attached sample only uses "is", the same issue is present with the "as" operator.

Note that "TObject is T", ie when the second parameter is a parameterized type, it correctly reports the error.
Steps to Reproduce:
Compile and run the attached project.

If the bug is present, the compiler will not produce an error, and the program will produce an Access Violation at runtime.

-----------------
program Project1;
{$APPTYPE CONSOLE}

uses
  Classes;

type
  TRec1<S, T: class> = record
    class procedure X(); static;
  end;

{ TRec1<S, T> }
class procedure TRec1<S, T>.X;
begin
  if S is T then // <<<---------- Access Vioaltion here
    WriteLn('1');
end;

type
  TRec2 = record
    class procedure Y<S, T: class>(); static;
  end;

{ TRec2 }
class procedure TRec2.Y<S, T>;
begin
  if S is T then
    WriteLn('2');
end;

begin
  TRec1<TObject,TPersistent>.X();
  TRec2.Y<TObject, TPersistent>();
end.
-----------------
Workarounds
None
Attachment
Project1.zip
Comments

None

Server Response from: ETNACODE01