Bugs

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
erik
Posts: 39
Joined: Dec 28, 2020 17:27
Location: Krasnoyarsk
Contact:

Re: Bugs

Post by erik »

Very large numbers in the compiler source code produce strange intermediate code.

In the file "symb.bi" on line 333 we have the constant FB_ARRAYDIM_UNKNOWN:

Code: Select all

'' Special value to represent the case where '...' ellipsis was given as ubound
const FB_ARRAYDIM_UNKNOWN = &h8000000000000000ll
In the file "ast-helper.bas" a constant is used on line 1019:

Code: Select all

'' Ellipsis ubound? can happen if ubound() is used in
'' an array initializer, when the ubound isn't fully
'' known yet, e.g. in this case:
''    dim array(0 to ...) as integer = { 1, ubound( array ), 3 }
if( bound = FB_ARRAYDIM_UNKNOWN ) then
	exit function
end if
At the output we have an intermediate C-code:

Code: Select all

if( (bound != -9223372036854775808ull) ) goto label$270;
{
	goto label$250;
}
The constant -9223372036854775808ull is unsigned, to which the negation operation is applied. This is strange. GCC produces a warning:

Code: Select all

SRC\COMPILER\AST-HELPER.BAS: In function 'hConstBound':
SRC\COMPILER\AST-HELPER.BAS:1019:36: error: comparison of integer expressions of different signedness: 'int64' {aka 'long long 
int'} and 'long long unsigned int' [-Werror=sign-compare]
Temporary solution:

Code: Select all

const FB_ARRAYDIM_UNKNOWN = &h8000000000000000ll - 1ll
marcov
Posts: 3483
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Bugs

Post by marcov »

Maybe define the loopvar as unsigned ?
SARG
Posts: 1821
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Bugs

Post by SARG »

I don't get the error on Windows with GNU C17 (MinGW-W64 x86_64-posix-sjlj, built by Brecht Sanders) version 9.3.0 (x86_64-w64-mingw32)

What OS ? (Win or Linux)
What version of Gcc ?
erik
Posts: 39
Joined: Dec 28, 2020 17:27
Location: Krasnoyarsk
Contact:

Re: Bugs

Post by erik »

For GCC the "-Wall -Wextra" or "-Wsign-compare" options must be enabled.

However, even without these options, the number &h8000000000000000ll turns into -9223372036854775808ull. Comparing signed and unsigned numbers can be undefined behavior or turn into a potential problem in the future.
TeeEmCee
Posts: 375
Joined: Jul 22, 2006 0:54
Location: Auckland

Re: Bugs

Post by TeeEmCee »

It turns out that emitting -9223372036854775808ull is intentional. From hEmitInt in the C emitter:

Code: Select all

	if( typeIsSigned( dtype ) ) then
		s = str( value )

		'' Prevent GCC warnings for INT_MIN/LLONG_MIN:
		'' The '-' minus sign doesn't count as part of the number
		'' literal, and 2147483648 is too big for a 32bit integer,
		'' so it must be marked as unsigned.
		if( typeGetSize( dtype ) = 8 ) then
			if( value = -9223372036854775808ull ) then
				s += "u"
			end if
			s += "ll"
		else
			if( value = -2147483648u ) then
				s += "u"
			end if
		end if
(Regarding the warning in the comment: interestingly, the literal 9223372036854775808ll is an unsigned value in C and GCC prints "warning: integer constant is so large that it is unsigned", and while 0x8000000000000000ll is exactly the same value GCC prints no warning for it, hex constants are treated differently (which would be an alternative to adding "u").)

Anyway, the fix for this warning is https://github.com/rversteegen/fbc/comm ... 7ff1c8e366

But when I compile fbc with -gen gcc -Wc -Wall,-Wextra with GCC 12.2.0 I get an enormous amount of other spammed warnings (mostly -Wmissing-field-initializers), so I'm taking a look at those too.
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Bugs

Post by dodicat »

Can somebody explain this in fb 1.10

Code: Select all


sub test(byref s as integer ptr) 
    print __function__,s
    dim as integer k
    s=@k
end sub

dim as integer g=2024
dim as integer ptr p=@g
print " Original pointer value "; p
test(p)
print "Pointer value after sub "; p
p=@g
print "________________________"
print
print " Original pointer value "; p
test(byval p)
print "Pointer value after sub "; p
sleep 
SARG
Posts: 1821
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Bugs

Post by SARG »

First call address of P
Second call address of g

Code: Select all

sub test(byref s as integer ptr) 
    print __function__,s
    dim as integer k
    s=@k
end sub

dim as integer g=2024
dim as integer ptr p=@g
print " Original pointer value "; p,g
test(p)
print "Pointer value after sub "; p,g
p=@g
print "________________________"
print
print " Original pointer value "; p,g
test(byval p)
print "Pointer value after sub "; p,g
srvaldez
Posts: 3505
Joined: Sep 25, 2005 21:54

Re: Bugs

Post by srvaldez »

dodicat, the reason for your test puzzles me, surely you know that the variable k will be out of scope after calling test, but FB doesn't warn or complain however gcc-13.2 and up give this warning warning: storing the address of local variable 'K$1' in '*S$1' [-Wdangling-pointer=]
fxm
Moderator
Posts: 12346
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Bugs

Post by fxm »

By specifying the 'Byval' keyword in front of an argument to a 'ByRef' parameter (or in front of a function result returned 'Byref'), a value usually stored in a pointer, can be passed directly as-is as an address, forcing the 'Byref' parameter (or 'Byref' function result) to reference the memory location that this address points to.

One interest of this is when a variable is only declared/defined through a pointer (as for example for a dynamic memory allocation), this avoid an explicit dereferencing, with the right type, of this pointer to pass by reference the pointed variable:
'Byval p' equivalent to '*p' at best, or to '*Cptr(type Ptr, p)'.

But in that case, as the value passed as-is directly forces the expected address, there is not exhaustive compatibility check of the provided 'Byval' variable type with respect to the expected parameter type (or result type).
=> danger, or only for hacking !

Working but purely academic example:

Code: Select all

Function upperCaseZstringCopy(Byref passedZstring As Zstring, Byref toCopyString As String) Byref As Zstring
    passedZstring = Ucase(toCopyString)
    Return passedZstring
End Function

Function getNewZstring (Byval size As Integer) Byref As Zstring
    ' instead of:
        ' Return *Cptr(Zstring Ptr, Callocate(size + 1))
    ' one can do:
        Return Byval Callocate(size + 1)
End Function

Dim As String s


s = "FreeBASIC"
' instead of:
    ' Dim Byref As Zstring rz1 = upperCaseZstringCopy(*Cast(Zstring Ptr, Callocate(Len(s) + 1)), s)
' one can do:
    Dim Byref As Zstring rz1 = upperCaseZstringCopy(Byval Callocate(Len(s) + 1), s)
Print "'" & s & "'", "'" & rz1 & "'"
Deallocate(@rz1)


s = "Version"
Dim Byref As Zstring rz2 = getNewZstring(Len(s))
rz2 = Ucase(s)
Print "'" & s & "'", "'" & rz2 & "'"
Deallocate(@rz2)

Sleep
fxm
Moderator
Posts: 12346
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Bugs

Post by fxm »

I updated the bug report dedicated of that 'Byval' use, but for a 'Byval' parameter:
#830 Byval placed before a passed variable for a Byval parameter induces an incomplete copy construction
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Bugs

Post by dodicat »

Thank you all for looking into this byval.
Yes srvaldez, static in the sub would have been the proper way.
The last thing I would have thought of was passing a value byval to a procedure, I came across it by accident.
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Bugs

Post by dodicat »

Could somebody explain this, pressing the left mouse button??

Code: Select all

function mousepress(k as long) as boolean
if k=1 then return true
return false
end function
windowtitle "PRESS THE LEFT MOUSE BUTTON"
dim as long mx,my,mb
screen 19,32
do
    getmouse mx,my,,mb
    screenlock
    cls
draw string(10,50),"Button Pressed", mousepress(mb)
screenunlock
sleep 20
loop until len(inkey)

 
fxm
Moderator
Posts: 12346
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Bugs

Post by fxm »

The 'color' parameter of Draw String is expecting an ULong, so the 'mousepress()' return value is implicitly converted to an ULong (if conversion is possible):

- Conversion from Boolean to Integer :
False => 0
True => -1

- Conversion from Integer to Ulong:
0 => 0
-1 => &hFFFFFFFF

Code example:

Code: Select all

Function convert(Byval b As Boolean) As Ulong
    Return b  '' implicit conversion is possible
End Function

Print "Boolean  -->  ULong"
Print "False", Hex(convert(False))
Print "True", Hex(convert(True))

Sleep
dodicat
Posts: 8137
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Bugs

Post by dodicat »

Thanks fxm.
No bug at all.
The comma separates colour from text, for some reason I put in the comma and didn't notice it.
I should have put in & instead of comma.
Post Reply