Recent

Author Topic: Incorrect compiler warning message. [SOLVED]  (Read 694 times)

jcdammeyer

  • Jr. Member
  • **
  • Posts: 85
  • Embedded System Developer
    • Automation Artisans Inc.
Incorrect compiler warning message. [SOLVED]
« on: September 19, 2020, 08:08:37 am »
From Socketsh.inc there is this definition:

function htons( host : word):word; inline;

Used in a socket communications example the function is supposed to reverse the byte order fro little endian to big endian:
  SockAddr.sin_port := htons(8008);

The variable is of type word.

The warning: Range check error while evaluating constants (2050079 must be between 0 and 65535)
shows up.

The byte reordered output of 8008 is 18463 which produces the same Warning.
  SockAddr.sin_port := 18463; // htons(8008);

Force it to be a word and the warning goes away
  SockAddr.sin_port := word(18463); // htons(8008);

So you'd think that doing this would also fix it but it doesn't.
  SockAddr.sin_port := word(htons(8008));

And when you dive into the code the value 8008 is in hex 0x1F48 and the htons() function is supposed to change that to 0x481F.
The assembler which for some reason can't be copied to the clipboard is as follows so the code is correct.
movw $0x481F,0x20574(%rip)

Why the Warning message?
« Last Edit: September 19, 2020, 07:39:02 pm by jcdammeyer »

Blaazen

  • Hero Member
  • *****
  • Posts: 2994
  • POKE 54296,15
    • Eye-Candy Controls
Re: Incorrect compiler warning message.
« Reply #1 on: September 19, 2020, 01:06:32 pm »
Did you try opposite?
Code: Pascal  [Select][+][-]
  1.   SockAddr.sin_port := htons(word(8008));
Because numbers like 8008 are Integers from compiler's point of view.
Lazarus 2.1.0 r64115 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6713
  • Debugger - SynEdit - and more
    • wiki
Re: Incorrect compiler warning message.
« Reply #2 on: September 19, 2020, 01:29:25 pm »
Because numbers like 8008 are Integers from compiler's point of view.
But the value is constant, so it should not violate the range checking.

Take the value from the error message 2050079. That is $1F481F

So the violation comes from the "result" of htons.
Or rather maybe a "wrong intermediate result"?

On Windows (fpc 304) htons eventually resolves to (may depend on fpc version)
Code: Pascal  [Select][+][-]
  1. Result := Word((AValue shr 8) or (AValue shl 8));
Parts of this operation may indeed be performed using longword. But the extra bits should be silently cut.

I am assuming the compiler (3.3.1) evaluates that during compilation?

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Incorrect compiler warning message.
« Reply #3 on: September 19, 2020, 03:53:59 pm »
Because numbers like 8008 are Integers from compiler's point of view.
But the value is constant, so it should not violate the range checking.

Constant values are not Integers, instead how their size is determined is described here: Language Reference Guide section 3.1.1 Ordinal types:

Quote
Remark The compiler decides on the type of an integer constant based on the value: An integer constant gets the smallest possible signed type. The first match in table (3.3) is used.

That said the range error is indeed strange, because the resulting assembly code contains the correct value:

Code: ASM  [Select][+][-]
  1. # [23] v := htons(8008);
  2.         movw    $18463,%ax
  3.         movw    %ax,U_$P$TCONST_$$_V(%rip)
« Last Edit: September 19, 2020, 07:05:33 pm by PascalDragon »

Thaddy

  • Hero Member
  • *****
  • Posts: 10576
Re: Incorrect compiler warning message.
« Reply #4 on: September 19, 2020, 06:56:53 pm »
Ordinal types, not ordinary.
(Ordinal types have a natural order, ordinary types do not necessarily have a natural order)

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Incorrect compiler warning message.
« Reply #5 on: September 19, 2020, 07:06:48 pm »
Ordinal types, not ordinary.

Eh, right. That's from not using Copy & Paste. :-[

Anyway, I've fixed the problem in 46897 and will request to have that merged to 3.2.1. :)

jcdammeyer

  • Jr. Member
  • **
  • Posts: 85
  • Embedded System Developer
    • Automation Artisans Inc.
Re: Incorrect compiler warning message.
« Reply #6 on: September 19, 2020, 07:11:00 pm »
Thanks everyone.
For my work-work I often have to dive in and look at what the compiler generates.  It's often amazing how just changing the high level language style can make code faster or smaller. 

Or in the case of a M9S12 paged processor where the compiler forgot to set the page properly I had to insert some inline assembler to fix it.

So yes I tried all the variations to tell the compiler that it should do what I want.  I don't know where the library is for that inline code.   What I did try is using a variable instead of a constant.
Code: Pascal  [Select][+][-]
  1.  
  2.   TargetPort := 8008;
  3.   SockAddr.sin_port := htons(TargetPort);
  4.  

Now it does not complain and the code generated in assembler is about what you'd expect.  So this appears to be a compiler problem in dealing with this inline function when a constant is provided rather than a variable.  it's using the 8008 as an address initially and then recovering and using it as a literal.  That would explain the range check error.

FPC version is 3.20, Lazarus is version 2.0.10. Target in this case is PC with win32/64.

John


jcdammeyer

  • Jr. Member
  • **
  • Posts: 85
  • Embedded System Developer
    • Automation Artisans Inc.
Re: Incorrect compiler warning message.
« Reply #7 on: September 19, 2020, 07:15:41 pm »
Ordinal types, not ordinary.

Eh, right. That's from not using Copy & Paste. :-[

Anyway, I've fixed the problem in 46897 and will request to have that merged to 3.2.1. :)

Speaking of copy/paste.  Is it possible to turn on 'copy' for the Lazarus debug assembler window?
Thanks
John

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Incorrect compiler warning message.
« Reply #8 on: September 19, 2020, 07:16:41 pm »
I don't know where the library is for that inline code.

Using Ctrl + Click together with Ctrl + Shift + Down in Lazarus usually solves that question. ;)

So this appears to be a compiler problem in dealing with this inline function when a constant is provided rather than a variable.  it's using the 8008 as an address initially and then recovering and using it as a literal.  That would explain the range check error.

No, I've asked on the core mailing list and Jonas Maebe replied the following:

Quote
SwapEndian is defined as

Code: Pascal  [Select][+][-]
  1. function SwapEndian(const AValue: Word): Word;{$ifdef
  2. SYSTEMINLINE}inline;{$endif}
  3.   begin
  4.     Result := Word((AValue shr 8) or (AValue shl 8));
  5.   end;

I.e., this is a typecast of $1F481F to word, and bits are getting lost
by that typecast. The warning can be silenced by adding an "and $ffff"
before (or instead of) the typecast to word.

The warning was mainly added to catch typos like longint($dffffffff)
(there's 8 f's instead of 7).

Due to the value being a constant the compiler can check it. By using a variable the compiler can't check it that way.

Blaazen

  • Hero Member
  • *****
  • Posts: 2994
  • POKE 54296,15
    • Eye-Candy Controls
Re: Incorrect compiler warning message.
« Reply #9 on: September 19, 2020, 07:21:03 pm »
@ jcdammeyer

Note: copying from Assembler windows must be done via right-click and Copy to Clipboard. CTRL+C does not work there.
Lazarus 2.1.0 r64115 FPC 3.3.1 r40507 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

jcdammeyer

  • Jr. Member
  • **
  • Posts: 85
  • Embedded System Developer
    • Automation Artisans Inc.
Re: Incorrect compiler warning message.
« Reply #10 on: September 19, 2020, 07:28:49 pm »
@ jcdammeyer

Note: copying from Assembler windows must be done via right-click and Copy to Clipboard. CTRL+C does not work there.

OK.  Tried that and it works.  Totally non-intuitive since ctrl+C does work in the edit window.  Not fond of inconsistencies.  I guess it may have been done that way because you can't paste with ctrl+V in the assembler window.

I will try and remember that.
Thanks
John

jcdammeyer

  • Jr. Member
  • **
  • Posts: 85
  • Embedded System Developer
    • Automation Artisans Inc.
Re: Incorrect compiler warning message.
« Reply #11 on: September 19, 2020, 07:38:26 pm »
I don't know where the library is for that inline code.

Using Ctrl + Click together with Ctrl + Shift + Down in Lazarus usually solves that question. ;)

Quote
SwapEndian is defined as

Code: Pascal  [Select][+][-]
  1. function SwapEndian(const AValue: Word): Word;{$ifdef
  2. SYSTEMINLINE}inline;{$endif}
  3.   begin
  4.     Result := Word((AValue shr 8) or (AValue shl 8));
  5.   end;

I.e., this is a typecast of $1F481F to word, and bits are getting lost
by that typecast. The warning can be silenced by adding an "and $ffff"
before (or instead of) the typecast to word.

The warning was mainly added to catch typos like longint($dffffffff)
(there's 8 f's instead of 7).

Due to the value being a constant the compiler can check it. By using a variable the compiler can't check it that way.

Then word(8008) should deliver the correct result and it doesn't.  Just tried ($ffff AND 8008)  and it throws the same warning.

And the ctrl click took me to socketsh.inc file where it's defined as an inline.  From there to winsock2.pp
Code: Pascal  [Select][+][-]
  1. function htons(hostshort: u_short): u_short; stdcall;external WINSOCK2_DLL name 'htons';
  2.  
And at that point I got lost...  But I think as it turns out it wouldn't have picked up on the compiler optimizing the code for a literal anyway.

Thanks for all the responses on this.
John

jamie

  • Hero Member
  • *****
  • Posts: 3796
Re: Incorrect compiler warning message. [SOLVED]
« Reply #12 on: September 19, 2020, 07:43:11 pm »
Must be a compiler version issue because I just tried that using 3.0.4 in 64 bit windows and there is no warning.
 8-)
The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 2418
  • Compiler Developer
Re: Incorrect compiler warning message.
« Reply #13 on: September 19, 2020, 07:56:56 pm »
Due to the value being a constant the compiler can check it. By using a variable the compiler can't check it that way.

Then word(8008) should deliver the correct result and it doesn't.  Just tried ($ffff AND 8008)  and it throws the same warning.[/quote]

No, that will not matter. If you use Word(8008) or ($ffff AND 8008) then the compiler will expand the function to (using the first one as an example):

Code: Pascal  [Select][+][-]
  1. Result := Word((Word(8008) shr 8) or (Word(8008) shl 8));

The shifts will still result in 32-bit values that are then truncated by the typecast to Word.

And the ctrl click took me to socketsh.inc file where it's defined as an inline.  From there to winsock2.pp
Code: Pascal  [Select][+][-]
  1. function htons(hostshort: u_short): u_short; stdcall;external WINSOCK2_DLL name 'htons';
  2.  
And at that point I got lost...  But I think as it turns out it wouldn't have picked up on the compiler optimizing the code for a literal anyway.

When you're at the declaration of a function (in this case the one in socketsh.inc) you need to use Ctrl + Shift + Down to get to the implementation (in this case in sockets.inc). Why Lazarus brings you to the next identifier with the same name if you use Ctrl + Click again, I don't know right now.

Must be a compiler version issue because I just tried that using 3.0.4 in 64 bit windows and there is no warning.
 8-)

It's an addition of 3.2.0 (revisions 42272 and 42275).

 

TinyPortal © 2005-2018