Lazarus

Programming => General => Topic started by: tomitomy on April 09, 2021, 02:23:25 am

Title: For S in [...] bug of FPC 3.2.0
Post by: tomitomy on April 09, 2021, 02:23:25 am
I found a bug in fpc 3.2.0, I don't know if it fixed in fpc 3.2.2, so  I report it here.

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. // Arch Linux,  Lazarus 2.0.12,  FPC 3.2.0
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7. var
  8.   S: String;
  9. begin
  10.   for S in ['1234567', '12345678', '123456', '12345678'] do begin
  11.     WriteLn(S);  // Result: 1234567 1234567 123456 1234567 (missing character 8)
  12.   end;
  13.  
  14.   for S in ['12345678', '12345678', '12345678', '12345678'] do begin
  15.     WriteLn(S);  // Result: 12345678 12345678 12345678 12345678 (all is right)
  16.   end;
  17. end.
Title: Re: A bug of FPC 3.2.0
Post by: Martin_fr on April 09, 2021, 02:42:18 am
It is still present in the 3.2.2 rc (tested on Win 10 / 64 bit)

Please report on the bugtracker.
Title: Re: A bug of FPC 3.2.0
Post by: jamie on April 09, 2021, 02:46:09 am
that was discovered wall back, I remember when Laz was first released with 3.2.0 that bug was brought up..

It uses the length of the first element for the rest of the elements
Title: Re: A bug of FPC 3.2.0
Post by: engkin on April 09, 2021, 03:17:11 am
It is present in revision 49028 - Win32

As mentioned by jamie, it takes the length of the first string.
Title: Re: A bug of FPC 3.2.0
Post by: tomitomy on April 09, 2021, 03:22:57 am
I submitted a bug report:

https://bugs.freepascal.org/view.php?id=38732
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: engkin on April 12, 2021, 01:51:27 pm
The strings formed in this bug are not compatible with Pascal strings, as they don't accept #$00:
Code: Pascal  [Select][+][-]
  1.  for S in ['ABC'#$00'DEF','1234567890'] do begin
  2.     WriteLn(S);
  3.   end;

gives:
Quote
ABC
1234567

instead of:
Quote
ABC DEF
1234567890

The length of the first string became 3, instead of 7
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: trev on April 12, 2021, 02:20:39 pm
Code: Pascal  [Select][+][-]
  1. Program test;
  2.  
  3. var
  4.  S: String;
  5.  
  6. begin
  7.   for S in ['ABC'+#$00+'DEF','1234567890'] do
  8.     begin
  9.       WriteLn(S);
  10.     end;
  11. end.

Output:

Quote
ABCDEF
234567890??@??
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: engkin on April 12, 2021, 03:57:18 pm
Forgot to mention, I used FPC 3.2.0 and r49028 both Win32.

@Trev, your code gave "Runtime error 216" on my side using both mentioned compilers.

[Edit by Trev: FPC 3.3.1 r49035, macOS 10.14.6, Xcode 11.3.1]
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: lucamar on April 12, 2021, 06:02:11 pm
Trev's code compiled in Linux with the normal fpc 3.2.0 (from Lazarus 2.0.12 distro):
Code: [Select]
Free Pascal Compiler version 3.2.0 [2020/07/07] for x86_64gives the same output he shows.

Because it's rather curious I'm attaching the file generated by:
Code: Bash  [Select][+][-]
  1. ./test > test_out.txt
. Look at it with an hex viewer; it has quite some non-printable chars :-\
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: engkin on April 12, 2021, 06:16:39 pm
@lucamar,
It seems the compiler used the first character 'A' or $41 as the length of the string.

Edit:
I am wrong, the text is $3A bytes long.

2nd Edit:
It explains "Runtime error 216" on my side.
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: Yiyuan on April 12, 2021, 06:23:25 pm
I think short string is a fixed-size type so after initialization by the first value, its size will remain. If the later value is shorter than the size, the remaining position should be occupied by empty chars which can not be displayed by writeln but can be shown by length.
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: lucamar on April 12, 2021, 06:31:31 pm
@lucamar,
It seems the compiler used the first character 'A' or $41 as the length of the string.

Not really; first, the whole output is just 57 ($39) bytes long and, second, the string starts with 'ABC' as it should. What it looks like is like the first #00 is confusing it and making it loose the count somehow, or there is an overflow somewhere.

If instead you do:
Code: Pascal  [Select][+][-]
  1. program test;
  2.  
  3. const
  4.   sv: array[0..1] of string =
  5.     ('ABC'+#00+'DEF',
  6.      '1234567890');
  7. var
  8.   s: String;
  9.  
  10. begin
  11.   for s in sv do
  12.     writeln(s);
  13. end.
then all is as it should and the display (and a text file with redirected output, which includes the #00) shows:
Code: Bash  [Select][+][-]
  1. lucamar@Diana:~/SoftDev/Test/temp$ ./test
  2. ABCDEF
  3. 1234567890
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: engkin on April 12, 2021, 07:14:15 pm
@lucamar,
Yes, you are right.

@Yiyuan,
Maybe the compiler creates a [temporary] short string, gives it the length of the first string for the bug in the first post by @tomitomy, or some random(?) length as in the bug pointed out by @trev.
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: ASerge on April 12, 2021, 08:17:48 pm
Maybe the compiler creates a [temporary] short string, gives it the length of the first string for the bug in the first post by @tomitomy, or some random(?) length as in the bug pointed out by @trev.
Test (Win x64):
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3. {$LONGSTRINGS ON}
  4.  
  5. procedure Test;
  6. var
  7.   S: string;
  8. begin
  9.   for S in [('ABC'+'D'+'EFGH'), ('12345678')] do
  10.     WriteLn(S);
  11. end;
  12.  
  13. begin
  14.   Test;
  15.   Readln;
  16. end.
Something is wrong with defining the types of constants. From the assembler:
Code: ASM  [Select][+][-]
  1. .section .rodata.n_.Ld1,"d"
  2.         .balign 8
  3. .Ld1$strlab:
  4.         .short  0,1
  5.         .long   0
  6.         .quad   -1,8
  7. .Ld1:
  8.         .ascii  "ABCDEFGH\000"
  9.  
  10. .section .rodata.n__$PROGRAM$_Ld2,"d"
  11.         .balign 8
  12. .globl  _$PROGRAM$_Ld2
  13. _$PROGRAM$_Ld2:
  14.         .ascii  "12345678\000"
  15. # End asmlist al_typedconsts
  16. # Begin asmlist al_rtti
  17.  
  18. .section .rodata.n_RTTI_$P$PROGRAM_$$_def00000002,"d"
  19.         .balign 8
  20. .globl  RTTI_$P$PROGRAM_$$_def00000002
  21. RTTI_$P$PROGRAM_$$_def00000002:
  22.         .byte   12,0
  23.         .quad   16,2
  24.         .quad   RTTI_$SYSTEM_$$_ANSISTRING$indirect
  25.         .byte   1
  26.         .quad   RTTI_$SYSTEM_$$_LONGINT$indirect
  27. # End asmlist al_rtti
  28. # Begin asmlist al_indirectglobals
  29.  
As we can see the second constant (PROGRAM$_Ld2) is defined as just PChar and the program crashes with SIGSEGV.

If explicitly specify that these are strings, everything goes well:
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3. {$LONGSTRINGS ON}
  4.  
  5. procedure Test;
  6. var
  7.   S: string;
  8. begin
  9.   for S in [string('ABC'+'D'+'EFGH'), string('12345678')] do
  10.     WriteLn(S);
  11. end;
  12.  
  13. begin
  14.   Test;
  15.   Readln;
  16. end.
Code: ASM  [Select][+][-]
  1. .section .rodata.n_.Ld1,"d"
  2.         .balign 8
  3. .Ld1$strlab:
  4.         .short  0,1
  5.         .long   0
  6.         .quad   -1,8
  7. .Ld1:
  8.         .ascii  "ABCDEFGH\000"
  9.  
  10. .section .rodata.n_.Ld2,"d"
  11.         .balign 8
  12. .Ld2$strlab:
  13.         .short  0,1
  14.         .long   0
  15.         .quad   -1,8
  16. .Ld2:
  17.         .ascii  "12345678\000"
  18. # End asmlist al_typedconsts
  19. # Begin asmlist al_rtti
  20.  
  21. .section .rodata.n_RTTI_$P$PROGRAM_$$_def00000002,"d"
  22.         .balign 8
  23. .globl  RTTI_$P$PROGRAM_$$_def00000002
  24. RTTI_$P$PROGRAM_$$_def00000002:
  25.         .byte   12,0
  26.         .quad   16,2
  27.         .quad   RTTI_$SYSTEM_$$_ANSISTRING$indirect
  28.         .byte   1
  29.         .quad   RTTI_$SYSTEM_$$_LONGINT$indirect
  30. # End asmlist al_rtti
  31. # Begin asmlist al_indirectglobals
  32.  
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: Yiyuan on April 13, 2021, 07:40:26 am
Maybe the compiler creates a [temporary] short string, gives it the length of the first string for the bug in the first post by @tomitomy, or some random(?) length as in the bug pointed out by @trev.
Test (Win x64):
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3. {$LONGSTRINGS ON}
  4.  
  5. procedure Test;
  6. var
  7.   S: string;
  8. begin
  9.   for S in [('ABC'+'D'+'EFGH'), ('12345678')] do
  10.     WriteLn(S);
  11. end;
  12.  
  13. begin
  14.   Test;
  15.   Readln;
  16. end.

As we can see the second constant (PROGRAM$_Ld2) is defined as just PChar and the program crashes with SIGSEGV.

Under the longstring mode and without a length specifier, string type equals to ansistring instead of shortstring. So add the {$H-} or change string to string[8] will remove the exception.
Title: Re: For S in [...] bug of FPC 3.2.0
Post by: ASerge on April 13, 2021, 06:32:59 pm
So add the {$H-} or change string to string[8] will remove the exception.
Actually, I was not looking for workarounds, but tried to show where and what the problem is.
TinyPortal © 2005-2018