tw34605.pp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. {%OPT=-CR}
  2. { This test checks that correct code is generated
  3. when typecasting a class reference type variable with a descendent class }
  4. {$mode objfpc}
  5. uses
  6. sysutils;
  7. type
  8. TBaseClass = class
  9. constructor Create;
  10. class var x : longint;
  11. var loc : longint;
  12. class procedure check; virtual;
  13. end;
  14. TDerClass = class(TBaseClass)
  15. var der : longint;
  16. end;
  17. TDer1Class = class(TDerClass)
  18. constructor Create;
  19. class var y : longint;
  20. var loc1 : longint;
  21. class procedure check; override;
  22. end;
  23. TDer2Class = class(TDerClass)
  24. constructor Create;
  25. class var z : longint;
  26. var loc2 : longint;
  27. class procedure check; override;
  28. end;
  29. constructor TBaseClass.Create;
  30. begin
  31. Inherited Create;
  32. x:=1;
  33. end;
  34. constructor TDer1Class.Create;
  35. begin
  36. Inherited Create;
  37. y:=1;
  38. end;
  39. constructor TDer2Class.Create;
  40. begin
  41. Inherited Create;
  42. z:=1;
  43. end;
  44. class procedure TBaseClass.check;
  45. begin
  46. writeln('TBaseClass.check called');
  47. end;
  48. class procedure TDer1Class.check;
  49. begin
  50. writeln('TDer1Class.check called');
  51. end;
  52. class procedure TDer2Class.check;
  53. begin
  54. writeln('TDer2Class.check called');
  55. end;
  56. type
  57. TBaseClassRef = class of TBaseClass;
  58. TDerClassRef = class of TDerClass;
  59. var
  60. c : TBaseClass;
  61. cc : TBaseClassRef;
  62. dcc : TDerClassRef;
  63. exception_generated : boolean;
  64. begin
  65. exception_generated:=false;
  66. c:=TBaseClass.Create;
  67. inc(c.x);
  68. c.check;
  69. c.free;
  70. c:=TDer1Class.Create;
  71. inc(c.x);
  72. inc(TDer1Class(c).y);
  73. c.check;
  74. c.free;
  75. c:=TDer2Class.Create;
  76. inc(c.x);
  77. inc(TDer2Class(c).z);
  78. c.check;
  79. c.free;
  80. cc:=TbaseClass;
  81. inc(cc.x);
  82. cc.check;
  83. cc:=TDer1Class;
  84. inc(cc.x);
  85. cc.check;
  86. cc:=TDer2Class;
  87. inc(cc.x);
  88. cc.check;
  89. TDerClassRef(cc).check;
  90. TDerClass(cc).check;
  91. dcc:=TDerClass;
  92. dcc.check;
  93. try
  94. //inc (TDer1Class(cc).y);
  95. TDer1Class(cc).check;
  96. except
  97. writeln('Exception generated');
  98. exception_generated:=true;
  99. end;
  100. writeln('TBaseClass: x=',TBaseClass.x);
  101. writeln('TDer1Class: x=',TDer1Class.x,', y=',TDer1Class.y);
  102. writeln('TDer2Class: x=',TDer2Class.x,', z=',TDer2Class.z);
  103. if not exception_generated then
  104. begin
  105. writeln('No exception generated on wrong typecast of class reference variable');
  106. halt(1);
  107. end;
  108. end.