Forum > FPC development

[SOLVED] FPC trunk: Existing code is broken about explicit class casting

(1/3) > >>

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

Go to full version