Recent

Author Topic: static array [0..0] now fail at run time  (Read 916 times)

rossh_lz

  • New Member
  • *
  • Posts: 14
Re: static array [0..0] now fail at run time
« Reply #15 on: November 22, 2020, 03:46:53 pm »
The underlying problem I have is this error below.  It shows at most places that the compiler has to do indexing of underlying array pointers.   As I said before this code is many years old, and runs fine in all versions prior to the current 3.2.0.

I started modify the code to replace code like   p^.data^[j].something , where data is a pointer to a static array.  I changed this to a wrapper function that does the pointer incrementing:  inc(data_ptr, j).  Of course this is the compilers job.   The fix works, to force the code to be more specific.  But this project is too big to be fiddled with, so I'm going back a version of the FPC and see how that works.

I can't give you a simple example to test - simple examples don't crash.   But a complex app with large mem usage is another story.

The 3.2.0 notes talk about changes to array type parameter passing.  My instinct says it seems to be some error here that is conflicting.


*****

"Project xyz raised exception class 'ERangeError' with message with message range check error.  address 1000013FA0.


'/usr/local/bin/fpc'  -MDelphi -Scghi -O1 -gw3 -gl -k-framework -kCocoa -l -vewnhibq -Filib/x86_64-darwin -Fu../codeadd -Fu../codeadd/registry -Fu../codeadd/Abbrevia_5.2/source -Fu../codeadd/synapse_tcp-ip_209 -Fu../../.lazarus/lib/Printer4Lazarus/lib/x86_64-darwin/cocoa -Fu../../.lazarus/lib/ImagesForLazarus/lib/x86_64-darwin/cocoa -Fu../../.lazarus/lib/cairocanvas_pkg/lib/x86_64-darwin/cocoa -Fu../../.lazarus/lib/units/x86_64-darwin/cocoa -Fu../../.lazarus/lib/LCLBase/units/x86_64-darwin -Fu/Library/Lazarus/components/lazutils/lib/x86_64-darwin -Fu/Library/Lazarus/packager/units/x86_64-darwin -Fu. -FElib/x86_64-darwin -olib/x86_64-darwin/xyz -dLCL -dLCLcocoa -dCURSOR_ERROR -dUseCThreads -dDEBUG

nanobit

  • Jr. Member
  • **
  • Posts: 93
Re: static array [0..0] now fail at run time
« Reply #16 on: November 22, 2020, 05:53:24 pm »
Take your old code and just change your static-array type (used only by array pointer)
from array[0..0] to array[0..max]. Max (some constant) will suppress range-check errors
if max is large enough to hold all actual index values.

Thaddy

  • Hero Member
  • *****
  • Posts: 10602
Re: static array [0..0] now fail at run time
« Reply #17 on: November 22, 2020, 06:03:15 pm »
range checks are local, so this will also hide the error
Code: Pascal  [Select][+][-]
  1. program untitled;
  2.  {$mode delphi}{$rangechecks on}{$pointermath on}
  3. var
  4. {$push}{$rangechecks off}
  5.   arr:array[0..0] of byte;
  6. {$pop} // restore on.
  7. begin
  8. end.
Now the arr variable will never be range checked. Basically it restores the old, less restrictive behavior.
« Last Edit: November 22, 2020, 06:07:14 pm by Thaddy »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 805
Re: static array [0..0] now fail at run time
« Reply #18 on: November 22, 2020, 06:07:16 pm »
range checks are local, so this will also hide the error
Code: Pascal  [Select][+][-]
  1. program untitled;
  2.  {$mode delphi}{$rangechecks on}{$pointermath on}
  3. var
  4. {$push}{$rangechecks off}
  5.   arr:array[0..0] of byte;
  6. {$pop} // restore on.
  7. begin
  8. end.
Now the arr variable will never be range checked.
That is completely wrong.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2433
  • Compiler Developer
Re: static array [0..0] now fail at run time
« Reply #19 on: November 22, 2020, 06:08:25 pm »
I can't give you a simple example to test - simple examples don't crash.   But a complex app with large mem usage is another story.

Without an example we can't help much.

Thaddy

  • Hero Member
  • *****
  • Posts: 10602
Re: static array [0..0] now fail at run time
« Reply #20 on: November 22, 2020, 06:14:04 pm »
That is completely wrong.
I saw it was wrong after testing. IMO it should work.

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 805
Re: static array [0..0] now fail at run time
« Reply #21 on: November 22, 2020, 06:16:23 pm »
That is completely wrong.
I saw it was wrong after testing. IMO it should work.
Range checking is a setting that applies to code, not to data.

rossh_lz

  • New Member
  • *
  • Posts: 14
Re: static array [0..0] now fail at run time
« Reply #22 on: November 23, 2020, 12:42:34 pm »
Without an example we can't help much.

Yes, understood.   Here is the issue in assembler.  Code is made with O1., range check off.   The code is doing unwanted range checking on the array size.  Hence the fatal failure.


Code: Pascal  [Select][+][-]
  1.  
  2.   PTData = ^TData;
  3.   TData = packed record
  4.     Info: TDataInfo;
  5.     Segment: array [0..0] of TDataSeg;
  6.   end;
  7.  
  8. var
  9.   Data: PTData;
  10.  
  11.  
  12. /Users/rossh/Lazarus/Datalog/Utils.pas:1017  i := 2;
  13. 00000001003082CA                          : c7 85 6c ff ff ff 02 00 00 00     movl   $0x2, -0x94(%rbp)
  14. /Users/rossh/Lazarus/Datalog/Utils.pas:1018  if Data^.Segment[i].First = $CC then
  15. 00000001003082D4                          : 48 8b 5d a8                       movq   -0x58(%rbp), %rbx
  16. 00000001003082D8                          : 8b 85 6c ff ff ff                 movl   -0x94(%rbp), %eax
  17. 00000001003082DE                          : 85 c0                             testl  %eax, %eax
  18. 00000001003082E0                          : 76 05                             jbe    0x1003082e7               ; <+6719> at Utils.pas:1018:17
  19. 00000001003082E2                          : e8 89 e6 d0 ff                    callq  0x100016970               ; FPC_RANGEERROR
  20. 00000001003082E7                          : 8b 85 6c ff ff ff                 movl   -0x94(%rbp), %eax
  21. 00000001003082ED                          : 48 6b c0 5c                       imulq  $0x5c, %rax, %rax
  22. 00000001003082F1                          : 81 bc 03 b9 01 00 00 cc 00 00 00  cmpl   $0xcc, 0x1b9(%rbx,%rax)
  23. 00000001003082FC                          : 0f 84 bf 1c 00 00                 je     0x100309fc1               ; <+14105> at Utils.pas
  24.  
  25.  
  26.  
  27.     Segment: array [0..$FFFF] of TDataSeg;
  28.  
  29.  
  30. /Users/rossh/Lazarus/Datalog/Utils.pas:1017  i := 2;
  31. 00000001003081DA                          : c7 85 6c ff ff ff 02 00 00 00     movl   $0x2, -0x94(%rbp)
  32. /Users/rossh/Lazarus/Datalog/Utils.pas:1018  if Data^.Segment[i].First = $CC then
  33. 00000001003081E4                          : 48 8b 5d a8                       movq   -0x58(%rbp), %rbx
  34. 00000001003081E8                          : 8b 85 6c ff ff ff                 movl   -0x94(%rbp), %eax
  35. 00000001003081EE                          : 3d ff ff 00 00                    cmpl   $0xffff, %eax             ; imm = 0xFFFF
  36. 00000001003081F3                          : 76 05                             jbe    0x1003081fa               ; <+6722> at Utils.pas:1018:17
  37. 00000001003081F5                          : e8 86 e6 d0 ff                    callq  0x100016880               ; FPC_RANGEERROR
  38. 00000001003081FA                          : 8b 85 6c ff ff ff                 movl   -0x94(%rbp), %eax
  39. 0000000100308200                          : 48 6b c0 5c                       imulq  $0x5c, %rax, %rax
  40. 0000000100308204                          : 81 bc 03 b9 01 00 00 cc 00 00 00  cmpl   $0xcc, 0x1b9(%rbx,%rax)
  41. 000000010030820F                          : 0f 84 c0 1c 00 00                 je     0x100309ed5               ; <+14109> at Utils.pas
  42.  

nanobit

  • Jr. Member
  • **
  • Posts: 93
Re: static array [0..0] now fail at run time
« Reply #23 on: November 23, 2020, 02:18:14 pm »
Such code works for me with {$R-}.
And your code is different from your previous descriptions.

rossh_lz

  • New Member
  • *
  • Posts: 14
Re: static array [0..0] now fail at run time
« Reply #24 on: November 23, 2020, 02:53:42 pm »
Such code works for me with {$R-}.
And your code is different from your previous descriptions.

Yes I have various different constructs in use, but all end up with the same error.

I thought $R- was the default?  Seemed to be so before.  You mean I have to force $R-, in every unit?


nanobit

  • Jr. Member
  • **
  • Posts: 93
Re: static array [0..0] now fail at run time
« Reply #25 on: November 23, 2020, 04:01:25 pm »
{$R-} before index-use would be needed technically, but {$R-} is not best practice.
And working under {$R+} would need changes in your types.

Here is one potential idea, but I cannot say which compilers support this efficiently:
This still uses the classic array type TDataSegs, because TDataSeg itself
might be array type and then pointermath has issues as said earlier.

type TDataSeg = record first, last: byte; end;
type TDataSegs = array[0..high(sizeInt) div sizeof(TDataSeg)-1] of TDataSeg;
type PDataSegs = ^TDataSegs; 

  PTData = ^TData;
  TData = packed record
    Info: TDataInfo;
    function Segment: PDataSegs; inline;
  end;

   function TData.Segment: PDataSegs; inline;
   begin result := PDataSegs(PByte(@self) + sizeof(Info)); end;
« Last Edit: November 23, 2020, 04:29:08 pm by nanobit »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2433
  • Compiler Developer
Re: static array [0..0] now fail at run time
« Reply #26 on: November 23, 2020, 04:29:08 pm »
I thought $R- was the default?  Seemed to be so before.  You mean I have to force $R-, in every unit?

$R- indeed is the default. Maybe something resulted in it being enabled? You can use {$ifopt R+}{$warning Range checks enabled}{$endif} to warn at compile time whether the option is enabled at a specific code point. Additionally you could check the compiler command line as well as the used fpc.cfg whether something passes -Cr while it shouldn't.

Almir.Bispo

  • Jr. Member
  • **
  • Posts: 91
  • CSV Comp DB is the Best NoSQL
    • CSV Comp DB (NoSQL)
Re: static array [0..0] now fail at run time
« Reply #27 on: November 23, 2020, 07:30:14 pm »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var  S :array  of byte;   //dynamic array declared as byte
  3.     i :integer;
  4. begin
  5. setlength(S,12); //dynamic dimension declared
  6.  for i:=0 to 10 do
  7.  begin
  8.    s[i]:=i;
  9.    showmessage('Test: '+inttostr(S[i]));  //test
  10.    showmessage('Test: '+inttostr( length(S)) );  //test
  11.  end;
  12.  
  13. end;    

Visit my Blog: http://adltecnologia.blogspot.com
CSV Comp DB Developer {Pascal Lover}

 

TinyPortal © 2005-2018