Discussion:
[fpc-devel] Simple cast compiled as AS with -CR
Ondrej Pokorny
2016-12-30 09:45:53 UTC
Permalink
Hello,

I have the following code

program FPCcast;

type
TMyClass1 = class
end;
TMyClass2 = class(TMyClass1);

var
O: TMyClass1;
begin
O := TMyClass1.Create;
TMyClass2(O).Free; // << 219-runtime error if compiled with -CR
end.

If I compile it with "-CR", I get a 219-runtime error when casting O to
TMyClass2. Is this wanted/documented? I see that {$OBJECTCHECKS OFF}
fixes it.

The documentation seems not to give any information about cast check:
http://www.freepascal.org/docs-html/3.0.0/prog/progsu57.html#x64-630001.2.57
http://www.freepascal.org/docs-html/3.0.0/user/userap1.html
"Verify object method call validity" is not exact description -> the
Free method is available both in TMyClass1 and TMyClass2, so I don't
expect a runtime error here.

Why I ask: this hack is used in the LCL to access protected methods -
i.e. the LCL doesn't work correctly with -CR.

Ondrej

_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Jonas Maebe
2016-12-30 10:27:44 UTC
Permalink
Post by Ondrej Pokorny
var
O: TMyClass1;
begin
O := TMyClass1.Create;
TMyClass2(O).Free; // << 219-runtime error if compiled with -CR
end.
If I compile it with "-CR", I get a 219-runtime error when casting O
to TMyClass2. Is this wanted/documented? I see that {$OBJECTCHECKS
OFF} fixes it.
Yes, this is by design. The above code is invalid and relies on
implementation details to work. E.g. with a JVM or CIL backend, the code
would be rejected by the bytecode verifier too.
Post by Ondrej Pokorny
Why I ask: this hack is used in the LCL to access protected methods -
i.e. the LCL doesn't work correctly with -CR.
Class crackers are an unsupported hack. In case you access fields, it
can also cause other problems:
http://wiki.freepascal.org/FPC_New_Features_3.0#Class_field_reordering .
In the future, more such situations may arise.

The compiler is supposed to be able to rely on the fact that the type
hierarchy you declare is in fact the real type hierarchy, and not just a
collection of statements that you use like a macro-assembler with the
expectation of ending up with a particular memory layout.


Jonas
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Ondrej Pokorny
2017-01-02 16:50:15 UTC
Permalink
Post by Jonas Maebe
Yes, this is by design. The above code is invalid and relies on
implementation details to work. E.g. with a JVM or CIL backend, the
code would be rejected by the bytecode verifier too.
Thank you Jonas for clarification. It may be worth to document it -
neither {$OBJECTCHECKS } nor -CR tell about cast checking.

http://www.freepascal.org/docs-html/3.0.0/prog/progsu57.html#x64-630001.2.57

http://www.freepascal.org/docs-html/3.0.0/user/userap1.html

Ondrej
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Sven Barth
2016-12-31 08:38:17 UTC
Permalink
Post by Ondrej Pokorny
Why I ask: this hack is used in the LCL to access protected methods -
i.e. the LCL doesn't work correctly with -CR.

In addition to what Jonas wrote: use class helpers to access protected
methods as they are a supported way for that (and they already work since
2.6).

Regards,
Sven
Loading...