Recent

Author Topic: Q about subverting type compatibility  (Read 870 times)

440bx

  • Hero Member
  • *****
  • Posts: 4686
Q about subverting type compatibility
« on: October 10, 2024, 05:12:13 am »
Hello,

Consider the following program:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. program _dword_qword;
  4.  
  5. function Va32(InAddress : DWORD) : DWORD;
  6. begin
  7.   result := InAddress + 1;
  8. end;
  9.  
  10. function Va64(InAddress : qword) : qword;
  11. begin
  12.   result := InAddress + 1;
  13. end;
  14.  
  15. var
  16.   TestVar : qword;
  17.  
  18. begin
  19.   writeln;
  20.  
  21.   TestVar := (high(qword) shr 32) shl 32;
  22.  
  23.   writeln(Va32(TestVar));  { is there a way to make this fail ? }
  24.   writeln(Va64(TestVar));
  25.  
  26.   writeln('press enter/return to end this program');
  27.   readln;
  28. end.                          
The call to Va32 is being passed a qword which is automatically truncated by the compiler to a dword.  Is there a way to tell FPC to emit an error in this case ?  IOW, is it possible to have FPC reject an argument that needs to be truncated to fit the parameter size ?

Thank you for your help.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #1 on: October 10, 2024, 06:05:50 am »
Range checks on....
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}{$mode objfpc} {$R+}
  2. program _dword_qword;
  3.  
  4. function Va32(InAddress : DWORD) : DWORD;
  5. begin
  6.   result := InAddress + 1;
  7. end;
  8.  
  9. function Va64(InAddress : qword) : qword;
  10. begin
  11.   result := InAddress + 1;
  12. end;
  13.  
  14. var
  15.   TestVar : qword;
  16.  
  17. begin
  18.   writeln;
  19.  
  20.   TestVar := (high(qword) shr 32) shl 32;
  21.  
  22.   writeln(Va32(TestVar));  { is there a way to make this fail ? }
  23.   writeln(Va64(TestVar));
  24.  
  25.   writeln('press enter/return to end this program');
  26.   readln;
  27. end.
It is the compiler, not me...
Code: Bash  [Select][+][-]
  1. (24,23) Error: Range check error while evaluating constants (18446744069414584320 must be between 0 and 4294967295)
Now say 'duh' a couple of times.. :D
Editor is Geany.
Btw, range checks are local, so with push/pop you can protect a specific bit of code if required.
« Last Edit: October 10, 2024, 06:16:33 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Khrys

  • Full Member
  • ***
  • Posts: 102
Re: Q about subverting type compatibility
« Reply #2 on: October 10, 2024, 07:00:31 am »
Range checks on....

This works at runtime, but is there a way to make FPC throw a compile-time error on implicit integer-integer conversions?
For example, Rust is extremely strict when it comes to this, so the following won't compile unless an explicit cast or conversion is added:
Code: C  [Select][+][-]
  1. fn triple(x: i64) -> i32 {
  2.     x * 3
  3. }

440bx

  • Hero Member
  • *****
  • Posts: 4686
Re: Q about subverting type compatibility
« Reply #3 on: October 10, 2024, 07:43:33 am »
As Khrys mentioned, that only works at runtime which is NOT what the question is about.

The question is about having the compiler reject the qword parameter in the first call... duh !!!
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #4 on: October 10, 2024, 01:30:06 pm »
No, in this case it works at compile time, duh. see screenshot.
That is the code that you provided.
(did not care to test it, did you)
The red line is in Geany that jumps to the compiler error as I pointed out.
In the case of your code it is a compile time error, but in other scenario's range checks can be runtime errors.
Here that is not the case. Better check your eyes. :P

More in general, the compiler - almost - always issues a warning or hint and you can promote that warning to error.
That will catch most truncations at compile time.
some of these related to range checks but not all of them are e.g.
Code: Pascal  [Select][+][-]
  1. {$warn 3036 error}
  2. {$warn 3353 error}
  3. {$warn 4036 error}
  4. {$warn 4048 error}
  5. {$warn 4109 error}
  6. {$warn 4110 error}//your case, the compiler told you so, but a compile time error in{$R+} mode
You can add to these when you encounter them.
Or the crude way: -Sewh  :D
Duh.. 8-)
I really should write a wiki entry for that, sometime.
(Although I must say there are possible - rare - exceptions to the above where the compiler misses it)
« Last Edit: October 11, 2024, 08:50:41 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Kays

  • Hero Member
  • *****
  • Posts: 608
  • Whasup!?
    • KaiBurghardt.de
Re: question about subverting type compatibility
« Reply #5 on: October 10, 2024, 02:50:16 pm »
No, compile-time range checks work only with constant expressions. If you have a dynamic value, a variable, the range‑check error can only be triggered at run‑time.
Code: Delphi  [Select][+][-]
  1.         const
  2.                 bigValue = (high(qword) shr 32) shl 32;
  3.         begin
  4.                 writeln(va32(bigValue)); { fails during compile-time }
Yours Sincerely
Kai Burghardt

440bx

  • Hero Member
  • *****
  • Posts: 4686
Re: Q about subverting type compatibility
« Reply #6 on: October 10, 2024, 03:01:37 pm »
@Thaddy,

Starved for attention much ?  As usual, working on increasing your post count, you'll post anything.

The code you posted does not emit a compile time error (not even a warning for that matter.)

Attached is a screenshot of compiling the code you posted.  No warnings, no errors, no nothing.

Not only you waste my time, you mislead forum members with your junk.


(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #7 on: October 10, 2024, 03:06:24 pm »
What is this then? I really do not understand, I simply explained what you asked and more...
Or are you suppressing warnings on purpose? My code simply does not compile in {$R+} mode, and it is not my code but your code except I added {$R+}
I am not starved for attention and you do not pay it.
« Last Edit: October 10, 2024, 03:09:06 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #8 on: October 10, 2024, 03:13:09 pm »
Can you please mention your editor and check that editor's settings, because you are definitely wrong in this case.
My particular command line as shown in attachment. Not even a debug setup.
« Last Edit: October 10, 2024, 03:24:26 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

Khrys

  • Full Member
  • ***
  • Posts: 102
Re: Q about subverting type compatibility
« Reply #9 on: October 10, 2024, 03:35:12 pm »
Better check your eyes. :P

I'll do that if you promise to read more carefully  :)

IOW, is it possible to have FPC reject an argument that needs to be truncated to fit the parameter size ?

Constants aren't even mentioned in the original question, just arguments in general. The range check error you're getting (which I agree 440bx should also be getting) is explicitly about constants.

Code: Bash  [Select][+][-]
  1. (24,23) Error: Range check error while evaluating constants (18446744069414584320 must be between 0 and 4294967295)

Yes, range checks on constants also work statically. But the question was about checking all arguments, not just constants. Try getting the compiler to emit an error on this:
Code: Pascal  [Select][+][-]
  1. procedure PrintInt32(X: Int32);
  2. begin
  3.   WriteLn(X);
  4. end;
  5.  
  6. procedure Test(Y: Int64);
  7. begin
  8.   PrintInt32(Y); // <--- Implicit narrowing conversion - value may not fit. Throws at runtime with {$R+}, but raises no compiler warning/error.
  9. end;

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #10 on: October 10, 2024, 03:37:45 pm »
There is something else going on. I sent a private message to 440bx to show that. Will report back later.
It seems we both are right, depending on the compile settings.
In the mean time look at this and shiver:
If I smell bad code it usually is bad code and that includes my own code.

440bx

  • Hero Member
  • *****
  • Posts: 4686
Re: Q about subverting type compatibility
« Reply #11 on: October 10, 2024, 03:42:57 pm »
@Thaddy,

run of the mill stuff...

Lazarus v3.2 using FPC v3.2.2, compiling for 64bit, tried all debug levels, 0, 1, 2, 3 and 4. 

Using YOUR code from post #1, no warning, no error, no nothing.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #12 on: October 10, 2024, 03:51:43 pm »
I filed a bug report with all available documentation against trunk.

#40944

It is definitely a bug and caused this whole confusion.
The strange thing is that in this case the highest optimization level handles the code correct and throws the correct error, whereas in lower optimization levels the - correct - error is hidden... Go figure.. :'(  : '( O:-)
I have seen strange things, but this one ranks very high.
@440bx I used your code in the bug report without permission.. (and my {$R+}) Hope you don't mind.

The strange case of optimized error reporting?
« Last Edit: October 10, 2024, 04:23:18 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

440bx

  • Hero Member
  • *****
  • Posts: 4686
Re: Q about subverting type compatibility
« Reply #13 on: October 10, 2024, 04:24:20 pm »
@440bx I used your code in the bug report without permission.. (and my {$R+}) Hope you don't mind.
I don't mind at all.  The code is public.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 16018
  • Censorship about opinions does not belong here.
Re: Q about subverting type compatibility
« Reply #14 on: October 11, 2024, 06:00:51 am »
Thanks to J. Gareth "Kit" Moreton we now know what happens:
My result can also be achieved by compiling with  -O2 -OoCONSTPROP
Constant propagation is able to catch the error at hand at compile time.
So 440bx and I were both right, but now it is easier to replicate for those who could not.

Nice feature! -OoCONSTPROP but initially confusing.
Anyway: it demonstrates the strength of constant propagation.
It also solves the original question.
This feature is available from version 3.0.0 and active from optimization level -O3
https://wiki.freepascal.org/FPC_New_Features_3.0.0#Constant_propagation

As per the comments on the bug tracker it may still be regarded as a bug that the success of the compiler depends on optimization mode.
« Last Edit: October 11, 2024, 08:44:29 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

 

TinyPortal © 2005-2018