Forum > FPC development
[SOLVED] FPC trunk: Existing code is broken about explicit class casting
abouchez:
Sometimes, we have a class defined as such in an unit:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TSomeClass = classprotected procedure SomeProtectedMethod;end; TChildClass = class(TSomeClass);and in another unit, we want to run the SomeProtectedMethod.
What we could do for ever is to create a local "hook" class:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TSomeClassHook = class(TSomeClass);... if obj is TSomeClass then TSomeClassHook(obj).SomeProtectedMethod;
It worked well, because of the forced typecast.
But if obj is of type TChildClass, now FPC trunk complains at runtime.
So I suspect, the trunk compiler add a runtime check to ensure that TSomeClassHook(obj) is actually a TSomeClassHook - which is not the case of course.
In practice, now above code seems to be compiled as:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TSomeClassHook = class(TSomeClass);... if obj is TSomeClass then (obj as TSomeClassHook).SomeProtectedMethod;which is breaking existing code.
What should I do?
abouchez:
See https://synopse.info/forum/viewtopic.php?pid=37009#p37009 as the problem description in the wild.
And https://github.com/synopse/mORMot2/commit/aa341c64 as current workaround.
abouchez:
I guess the following won't help:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---TSomeClassHook = class(TSomeClass);... if obj is TSomeClass then TSomeClassHook(pointer(obj)).SomeProtectedMethod;
PascalDragon:
Please provide a full, self contained example that demonstrates the issue. The following code works correctly in both FPC 3.2.2 and main and will only trigger the mentioned error when object checks (parameter -CR or directive $ObjectChecks) are enabled (as that is its purpose):
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program thook; {$mode objfpc} uses sysutils, uhook; type TSomeClassHook = class(TSomeClass); var obj: TObject;begin obj := TChildClass.Create; try if obj is TSomeClass then TSomeClassHook(obj).SomeProtectedMethod; finally obj.Free; end;end.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit uhook; {$mode objfpc}{$H+} interface type TSomeClass = class protected procedure SomeProtectedMethod; end; TChildClass = class(TSomeClass); implementation procedure TSomeClass.SomeProtectedMethod;begin Writeln('I''m protected');end; end.
abouchez:
It was in Delphi mode, in only a single computer... perhaps the user enabled object checks in the project options.
I didn't know about {$OBJECTCHECKS ON}.
I will force {$OBJECTCHECKS OFF} in all units of the framework, and wait for report.
Navigation
[0] Message Index
[#] Next page