Recent

Author Topic: Any traces of «if» statement disappeared  (Read 5029 times)

Avinash

  • Full Member
  • ***
  • Posts: 117
Any traces of «if» statement disappeared
« on: January 20, 2020, 10:58:56 am »
I re-saved the file, try recompile with -B and with -O-, but...

Code: Pascal  [Select][+][-]
  1. function SysFindFirst(Path: PChar; Attr: Longint; var F: TOSSearchRec; IsPChar: Boolean): Longint;
  2. begin
  3.   F.ExcludeAttr := Attr;
  4.   F.Handle := FindFirstFile(Path, F.FindData);
  5.   if F.Handle <> invalid_Handle_Value then
  6.     begin
  7.       Result := DoFindFile(F, IsPChar);
  8.       if Result <> 0 then
  9.         begin
  10.           FindClose(F.Handle);
  11.           F.Handle := invalid_Handle_Value;
  12.         end;
  13.     end
  14.   else
  15.     Result := GetLastError;
  16. end;

fpc -Anasmwin32 -al -O- -Mtp -Rintel vpsyslow.pas
oops!

Code: Pascal  [Select][+][-]
  1. SECTION .text
  2.     ALIGN 16
  3.     GLOBAL VPSYSLOW_$$_SYSFINDFIRST$PCHAR$LONGINT$TOSSEARCHREC$BOOLEAN$$LONGINT
  4. VPSYSLOW_$$_SYSFINDFIRST$PCHAR$LONGINT$TOSSEARCHREC$BOOLEAN$$LONGINT:
  5. ; [1038] begin
  6.         push    ebp
  7.         mov ebp,esp
  8.         lea esp,[esp-16]
  9. ; Var Path located at ebp-4, size=OS_32
  10. ; Var Attr located at ebp-8, size=OS_S32
  11. ; Var F located at ebp-12, size=OS_32
  12. ; Var IsPChar located at ebp+8, size=OS_8
  13. ; Var $result located at ebp-16, size=OS_S32
  14.         mov dword [ebp-4],eax
  15.         mov dword [ebp-8],edx
  16.         mov dword [ebp-12],ecx
  17. ; [1039] F.ExcludeAttr := Attr;
  18.         mov eax,dword [ebp-12]
  19.         mov edx,dword [ebp-8]
  20.         mov dword [eax+277],edx
  21. ; [1040] F.Handle := FindFirstFile(Path, F.FindData);
  22.         mov eax,dword [ebp-12]
  23.         lea eax,[eax+281]
  24.         push    eax
  25.         push    dword [ebp-4]
  26.         call    _$dll$kernel32$FindFirstFileA
  27.         mov edx,dword [ebp-12]
  28.         mov dword [edx],eax
  29. ; [1043] Result := DoFindFile(F, IsPChar);
  30.         mov eax,dword [ebp-12]
  31.         mov dl,byte [ebp+8]
  32.         call    VPSYSLOW_$$_DOFINDFILE$TOSSEARCHREC$BOOLEAN$$LONGINT
  33.         mov dword [ebp-16],eax
  34. ; [1044] if Result <> 0 then
  35.         cmp dword [ebp-16],0
  36.         jne ..@j1550
  37.         jmp ..@j1551
  38. ..@j1550:
  39. ; [1046] FindClose(F.Handle);
  40.         mov eax,dword [ebp-12]
  41.         push    dword [eax]
  42.         call    _$dll$kernel32$FindClose
  43. ; [1047] F.Handle := invalid_Handle_Value;
  44.         mov eax,dword [ebp-12]
  45.         mov dword [eax],-1
  46. ..@j1551:
  47. ; [1052] end;
  48.         mov eax,dword [ebp-16]
  49.         leave
  50.         ret 4

Where if F.Handle <> invalid_Handle_Value then / else ?

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Any traces of «if» statement disappeared
« Reply #1 on: January 20, 2020, 11:05:39 am »
Do both sides of the IF have the same type?

This sometimes happen with broken code that compares a variable of an unsigned type to a signed (and negative) constant.

Maybe it finds some VP definition that doesn't typecast the rhs to thandle. Unit Windows is correct and has

Code: Pascal  [Select][+][-]
  1. const   INVALID_HANDLE_VALUE = HANDLE(-1);
  2.  

A unsigned value is of course never negative, so it gets optimized away.
« Last Edit: January 20, 2020, 11:15:52 am by marcov »

Avinash

  • Full Member
  • ***
  • Posts: 117
Re: Any traces of «if» statement disappeared
« Reply #2 on: January 20, 2020, 11:23:21 am »
TOSSearchRec.Handle: Longint;

Code: Pascal  [Select][+][-]
  1. type
  2.   TOSSearchRec = packed record
  3.     Handle: Longint;
  4.     NameLStr: Pointer;
  5.     Attr: Byte;
  6.     Time: Longint;
  7.     Size: Longint;
  8.     Name: ShortString;
  9.     Filler: array[0..3] of Char;
  10. {$IFDEF WIN32}
  11.     ExcludeAttr: Longint;
  12.     FindData:    TWin32FindData;
  13. {$ENDIF}
  14. {$IFDEF DPMI32}
  15.     attr_must:byte;
  16.     dos_dta:
  17.       record
  18.         Fill: array[1..21] of Byte;
  19.         Attr: Byte;
  20.         Time: Longint;
  21.         Size: Longint;
  22.         Name: array[0..12] of Char;
  23.       end;
  24. {$ENDIF}
  25. {$IFDEF LINUX}
  26.     FindDir:  array[0..255] of Char;
  27.     FindName: ShortString;
  28.     FindAttr: LongInt;
  29. {$ENDIF}
  30.   end;

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Any traces of «if» statement disappeared
« Reply #3 on: January 20, 2020, 11:33:36 am »
Cool! Then FPC can even track that handle is assigned using findfirstfile and propagates the fact that findfirstfile returns an unsigned value, thus .handle can't be negative!

More advanced then I thought!

Try changing handle to unsigned, or maybe typecasting the result of the windows api FIND* functions if you want them to return deviant types.

If that doesn't work, make a small compilable example to test with.
« Last Edit: January 20, 2020, 11:47:01 am by marcov »

Avinash

  • Full Member
  • ***
  • Posts: 117
Re: Any traces of «if» statement disappeared
« Reply #4 on: January 20, 2020, 12:02:16 pm »
Try changing handle to unsigned, or maybe typecasting the result of the windows api FIND* functions if you want them to return deviant types.

with no success

I attached files, compiled by
fpc -Anasmwin32 -al -O- -Mtp -Rintel -MRESULT vpsyslow.pas

Avinash

  • Full Member
  • ***
  • Posts: 117
Re: Any traces of «if» statement disappeared
« Reply #5 on: January 20, 2020, 12:23:27 pm »
if F.Handle <> LongInt(invalid_Handle_Value)
helps, thanks

but this does not feel like advanced feature

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Any traces of «if» statement disappeared
« Reply #6 on: January 20, 2020, 01:24:05 pm »
Well, Windows handles are unsigned. So logically you'd keep everything unsigned. That you don't introduces the problems.

Note that the optimization doesn't matter. In any Delphi like that has int64, a integer<>cardinal comparison or addition will be upscaled, and this comparison will always fail because   int64(-1) <>  int64(cardinal(4294967295)).

In FPC and Delphi after 4, this generally got cleaned up, but if you are recycling ancient code this might trip you.
« Last Edit: January 20, 2020, 04:23:24 pm by marcov »

Avinash

  • Full Member
  • ***
  • Posts: 117
Re: Any traces of «if» statement disappeared
« Reply #7 on: January 20, 2020, 03:15:32 pm »
Yes you are right. My dissatisfaction was caused by the fact that when I changed the type of TOSSearchRec.Handle to DWord, nothing changed, but this turned out to be because somewhere there was a type definition of DWord = LongInt. And so everything in FPC is correct.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: Any traces of «if» statement disappeared
« Reply #8 on: January 20, 2020, 03:26:29 pm »
Yes you are right. My dissatisfaction was caused by the fact that when I changed the type of TOSSearchRec.Handle to DWord, nothing changed, but this turned out to be because somewhere there was a type definition of DWord = LongInt. And so everything in FPC is correct.

Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.

Handles are a very real problem, since at least in unix-derived OSes there's a convention that a -ve handle represents an error. Unfortunately a handle might also represent a memory address, even though it should be treated as an opaque type about which an application programmer should assume nothing. There quite simply isn't an answer which can satisfy everybody across all platforms.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #9 on: January 20, 2020, 10:50:03 pm »
Yes you are right. My dissatisfaction was caused by the fact that when I changed the type of TOSSearchRec.Handle to DWord, nothing changed, but this turned out to be because somewhere there was a type definition of DWord = LongInt. And so everything in FPC is correct.

Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.
This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: Any traces of «if» statement disappeared
« Reply #10 on: January 20, 2020, 11:04:43 pm »
Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.
This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.

My apologies. I meant to say that QWord is implemented internally as a signed 64-bit.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jamie

  • Hero Member
  • *****
  • Posts: 6077
Re: Any traces of «if» statement disappeared
« Reply #11 on: January 21, 2020, 12:13:45 am »
In 3.0.2 64, QWORD is a intrinsic type and Uint64 = QWORD

I am sure it's the same for the 32 bit verison/.
That looks correct to me.
The only true wisdom is knowing you know nothing

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: Any traces of «if» statement disappeared
« Reply #12 on: January 21, 2020, 09:23:04 am »
In 3.0.2 64, QWORD is a intrinsic type and Uint64 = QWORD

I am sure it's the same for the 32 bit verison/.
That looks correct to me.

Code: [Select]
0 1>markMLl@desktop:~$ cat test.pas
program test;

var
  x, y, z: qword;

begin
  x := $7fffffffffffffff;
  y := $ffffffffffffffff;
  z := $8000000000000000
end.

0 1>markMLl@desktop:~$ fpc test
Free Pascal Compiler version 3.0.4 [2018/07/03] for x86_64
Copyright (c) 1993-2017 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling test.pas
test.pas(8,8) Warning: range check error while evaluating constants (-1 must be between 0 and 18446744073709551615)
test.pas(9,8) Warning: range check error while evaluating constants (-9223372036854775808 must be between 0 and 18446744073709551615)
test.pas(4,3) Note: Local variable "x" is assigned but never used
test.pas(4,6) Note: Local variable "y" is assigned but never used
test.pas(4,9) Note: Local variable "z" is assigned but never used
Linking test
/usr/bin/ld: warning: link.res contains output sections; did you forget -T?
11 lines compiled, 0.1 sec
2 warning(s) issued
3 note(s) issued

Note warnings in line 8 & 9.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Any traces of «if» statement disappeared
« Reply #13 on: January 21, 2020, 10:00:41 am »
Also note that QWord is defined as signed, so defining large unsigned 64-bit numbers needs a cast. Unfortunate... and in fairness I have to say that when I queried that a year or so ago it was described to me as a compiler design choice. So it's not entirely a library coding issue.
This is incorrect. QWord is an unsigned type. However untyped 64-bit constants are always considered signed unless they are cast to QWord.

My apologies. I meant to say that QWord is implemented internally as a signed 64-bit.
That is also not true. Where did you get that idea?

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: Any traces of «if» statement disappeared
« Reply #14 on: January 21, 2020, 10:15:54 am »
That is also not true. Where did you get that idea?

Jonas, although since it was on the ML I'd rather not try to find out how I'm misquoting him :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018