Recent

Author Topic: [SOLVED] FPC trunk: Existing code is broken about constant enumerations  (Read 5381 times)

abouchez

  • Full Member
  • ***
  • Posts: 137
    • Synopse
The new FPC trunk feature "Range checking for enumeration constants in Delphi mode" breaks existing code.
https://wiki.freepascal.org/User_Changes_Trunk#Range_checking_for_enumeration_constants_in_Delphi_mode

For instance, this code:
Code: Pascal  [Select][+][-]
  1. const
  2.   /// value stored into a TLanguages enumerate to mark no language selected yet
  3.   LANGUAGE_NONE = TLanguages(255);
did work forever, and is broken by this new FPC trunk "feature".

The description in FPC user change list states that it is required in Delphi mode.
But this is untrue: above code compiles and work since Delphi 1 up to latest Delphi 11.1 with no troubles.
This is clearly a backward compatibility break, and avoid to run code working on Delphi and FPC since ever.
Where do I need to discuss and ask for removal of this "feature"?

I know forcing a value of an enumeration outside of its declared values is not beautiful, and should be avoided.
But it worked since forever, and compiles to fine code: 255 is just a byte, and the asm has no trouble with it.

See https://synopse.info/forum/viewtopic.php?id=6190
« Last Edit: April 04, 2022, 08:32:21 am by abouchez »

nanobit

  • Full Member
  • ***
  • Posts: 192
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #1 on: April 01, 2022, 03:41:09 pm »
Many FPC users are not aware of a limitation (or bug) here.
What you see is supposed to prevent outer values and resultant undefined behavior in FPC apps (Delphi apps don't have this UB problem). See "enum cutoff implementation" in the notes

Thaddy

  • Hero Member
  • *****
  • Posts: 19273
  • Glad to be alive.
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #2 on: April 01, 2022, 03:46:23 pm »
It is a regression, and therefor a bug. 3.0.4 is fine, in trunk it is broken.
objects are fine constructs. You can even initialize them with constructors.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6398
  • Compiler Developer
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #3 on: April 01, 2022, 03:52:55 pm »
Please provide a full, self contained example that demonstrates the issue. The following code compiles in both FPC 3.2.2 and main and only triggers a warning:

Code: Pascal  [Select][+][-]
  1. program tenum;
  2.  
  3. {$mode objfpc}
  4.  
  5. type
  6.   TLanguages = (
  7.     lOne,
  8.     lTwo,
  9.     lThree,
  10.     lFour
  11.   );
  12.  
  13. const
  14.   LANGUAGE_NONE = TLanguages(255);
  15.  
  16. begin
  17.  
  18. end.

Bart

  • Hero Member
  • *****
  • Posts: 5731
    • Bart en Mariska's Webstek
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #4 on: April 01, 2022, 04:13:40 pm »
This won't (fpc 3.2.2 on win32):
Code: Pascal  [Select][+][-]
  1. type
  2.   TLanguages = (
  3.     lOne,
  4.     lTwo,
  5.     lThree,
  6.     lFour
  7.   );
  8.  
  9. const
  10.   LANGUAGE_NONE = TLanguages(255);
  11. var
  12.   Lang: TLanguages;
  13.  
  14. begin
  15.  Lang := LANGUAGE_NONE;  //line 20
  16. end.
Code: [Select]
C:\Users\Bart\LazarusProjecten\ConsoleProjecten\test.pas
Bart

abouchez

  • Full Member
  • ***
  • Posts: 137
    • Synopse
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #5 on: April 01, 2022, 06:41:59 pm »
Thanks for the feedback.

It happens in Delphi mode, as I wrote in my initial post - and clearly stated by the trunk "User change" documentation entry.
The documentation entry is wrong by the way: Delphi has no trouble with such code.

Isn't there any compiler local directive to switch this behavior off?

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1071
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #6 on: April 01, 2022, 09:09:05 pm »
The change you linked is about the fix for https://gitlab.com/freepascal.org/fpc/source/-/issues/35671, which according to multiple reporters is in fact rejected by Delphi. It is possible the change also caused the error you are seeing at the same time, but that was not the purpose of that change.

There is, however, also the fact mentioned by nanobit that assigning out-of-range values to enums is not and never has been supported by FPC, because if it were valid then we could never perform any analyses based on the declared type of any ordinal variable (only based on their size). I know what you posted works with Delphi's code generator and that there is a bunch of code that relies on this, but it's a rather fundamental design issue (and philosophy) that cannot be addressed by just disabling one or two random optimisations in FPC (as gets suggested from time to time).

That said, Sven's program compiles for me on main without even a warning when it's changed to Delphi mode (unlike in 3.2.2, where it does print a warning about the out-of-range constant; that seems like a regression). So, like they asked: please (always) post a full example that can be used to reproduce the problem you're reporting.
« Last Edit: April 01, 2022, 10:58:31 pm by Jonas Maebe »

korba812

  • Sr. Member
  • ****
  • Posts: 483
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #7 on: April 02, 2022, 12:12:56 am »
This won't (fpc 3.2.2 on win32):
Code: Pascal  [Select][+][-]
  1. type
  2.   TLanguages = (
  3.     lOne,
  4.     lTwo,
  5.     lThree,
  6.     lFour
  7.   );
  8.  
  9. const
  10.   LANGUAGE_NONE = TLanguages(255);
  11. var
  12.   Lang: TLanguages;
  13.  
  14. begin
  15.  Lang := LANGUAGE_NONE;  //line 20
  16. end.
Code: [Select]
C:\Users\Bart\LazarusProjecten\ConsoleProjecten\test.pas
Bart
But this one does.
Code: Pascal  [Select][+][-]
  1. ...
  2. var
  3.   Lang: TLanguages;
  4.  
  5. begin
  6.  Lang := TLanguages(255);
  7. end.
What is the difference between a named constant and an anonymous one?

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1071
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #8 on: April 02, 2022, 01:27:55 pm »
Ah, sorry, I missed that reply. The difference comes from the fact that when we create an ordinal constant node from a constsym (like LANGUAGE_NODE), we always enable range checking for that ordinal node. I fixed that bug in 3da54dcf9f87336887f592c98c0088372da876e6 on main.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1071
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #9 on: April 02, 2022, 02:38:39 pm »
This won't (fpc 3.2.2 on win32):
The change was indeed already in 3.2.0. I've moved it there.

CC

  • Full Member
  • ***
  • Posts: 149
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #10 on: April 02, 2022, 08:23:34 pm »
Ah, sorry, I missed that reply. The difference comes from the fact that when we create an ordinal constant node from a constsym (like LANGUAGE_NODE), we always enable range checking for that ordinal node. I fixed that bug in 3da54dcf9f87336887f592c98c0088372da876e6 on main.

Thanks for the quick reaction!

I have applied your fix locally to the fixes branch.

Code: Pascal  [Select][+][-]
  1.  CurrentLanguage: TLanguage = (
  2.     Index:    LANGUAGE_NONE;  <--- line 324
  3.     CharSet:  DEFAULT_CHARSET;
  4.     CodePage: CODEPAGE_US;
  5.     LCID:     LCID_US
  6.   );     <--- line 328    

mORMoti18n.pas(324,15) Warning: range check error while evaluating constants (255 must be between 0 and 59)
mORMoti18n.pas(324,28) Error: range check error while evaluating constants (255 must be between 0 and 59)

Maybe it requires change at some other points in the source as well.
« Last Edit: April 02, 2022, 08:25:05 pm by CC »

PascalDragon

  • Hero Member
  • *****
  • Posts: 6398
  • Compiler Developer
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #11 on: April 02, 2022, 08:40:22 pm »
Maybe it requires change at some other points in the source as well.

Then please provide a full example that demonstrates this and not snippets where we need to guess what the full code is.

AlexTP

  • Hero Member
  • *****
  • Posts: 2715
    • UVviewsoft
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #12 on: April 02, 2022, 08:58:13 pm »
My guess (but I didn't test on latest)
Code: Pascal  [Select][+][-]
  1. type
  2.   TLang = (op1, op2, op3);
  3. const
  4.   cMyLang = TLang(255);
  5.  
  6. type
  7.   TRec = record
  8.     l: TLang;
  9.     v: integer;
  10.   end;
  11. const
  12.   cMyRec: TRec = (l: cMyLang; v: 10);
  13.  
  14. begin
  15.   writeln(cMyRec.l);
  16.  
  17. end.  

CC

  • Full Member
  • ***
  • Posts: 149
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #13 on: April 02, 2022, 10:19:33 pm »
Maybe it requires change at some other points in the source as well.

Then please provide a full example that demonstrates this and not snippets where we need to guess what the full code is.

Code: Pascal  [Select][+][-]
  1. program T001;
  2. //{$mode objfpc}{$H+}
  3. {$MODE DELPHI}
  4. {$R-}
  5. type
  6.   TLanguages = (
  7.     lOne,
  8.     lTwo,
  9.     lThree,
  10.     lFour
  11.   );
  12.  
  13. const
  14.   LANGUAGE_NONE = TLanguages(255);
  15.  
  16. type
  17.  TLanguage = record
  18.    Index : TLanguages;
  19.  end;
  20.  
  21. var
  22.   Lang: TLanguages;
  23.   CurrentLanguage: TLanguage = (
  24.     Index:  LANGUAGE_NONE
  25.   );
  26.  
  27. begin
  28.   Lang := LANGUAGE_NONE;
  29. end.
  30.  

Verbose: Compiling T001.lpr
T001.lpr(14,19) Warning: range check error while evaluating constants (255 must be between 0 and 3)
T001.lpr(24,13) Warning: range check error while evaluating constants (255 must be between 0 and 3)
T001.lpr(24,26) Error: range check error while evaluating constants (255 must be between 0 and 3)
T001.lpr(28,11) Warning: range check error while evaluating constants (255 must be between 0 and 3)

This error occures in both modes objfpc & DELPHI.
« Last Edit: April 02, 2022, 10:21:58 pm by CC »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1071
Re: FPC trunk: Existing code is broken about constant enumerations
« Reply #14 on: April 03, 2022, 11:20:58 am »
This case is now fixed as well.

 

TinyPortal © 2005-2018