FreeBASIC 1.10.1 Release Discussion

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

fxm wrote: Dec 31, 2022 15:19 Good news.
So I can assume that the second case below will also be fixed ?
Yes, it will also be fixed. Was there any open bug report or feature request about this?

Also, explicit CAST() does what it should:

Code: Select all

    type t1:            as integer i: end type
    type t2 extends t1: as integer j: end type
    type t3 extends t2: as integer k: end type

'' up-cast with explicit CAST()
scope
    dim x3 as T3 = (1,2,3)
    dim p as T1 ptr = new T2(cast(T1,x3))

    ''                              fbc 1.10.0  1.09.0
    print p->i                  ''         1       1
    print cast(T2 ptr, p)->j    ''         0       0
end scope
And all intializers should be normalized work the same.
I haven't fully tested all forms but (INIT), TYPE(), BASE(), NEW(), etc, should all work the same.

Just one example using (INIT). In this case I try to show how initializer lists would change if user was to go back and add new fields to the base types:

Code: Select all

scope
    type t1          :  as integer i: end type
    type t2 extends t1: as integer j: end type
    type t3 extends t2: as integer k: end type
    
    dim x1 as T1 = (10)
    dim x2 as T2 = (x1,20)
    dim x3 as T3 = (x2,30)

    ''                 fbc 1.10.0  1.09.0
    print x3.i    ''         10      10
    print x3.j    ''         20      30 
    print x3.k    ''         30      0
end scope

print

scope
    type t1           : as integer i,a: end type
    type t2 extends t1: as integer j,b: end type
    type t3 extends t2: as integer k,c: end type

    dim x1 as T1 = (10,11)
    dim x2 as T2 = (x1,20,21)
    dim x3 as T3 = (x2,30,31)

    ''                 fbc 1.10.0  1.09.0
    print x3.i   ''         10      10
    print x3.a   ''         11      11
    print x3.j   ''         20      30 
    print x3.b   ''         21      31
    print x3.k   ''         30      0
    print x3.c   ''         31      0
end scope
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Dec 31, 2022 15:55 Was there any open bug report or feature request about this?
Not to my knowledge, apart the #968 which came close.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

Last change:
fbc: normalize initializer up-casting
Bravo Jeff !
Looks good to me now.

Happy New Year to all users, especially Jeff and SARG !
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

Some weird syntaxes with 'Type()' not supported ?

1) Compilation warnings:

Code: Select all

Type T1
    Dim As Integer i
End Type
Type T2 Extends T1
    Dim As Integer j
End Type
Type T3 Extends T2
    Dim As Integer k
End Type
Type T4 Extends T3
    Dim As Integer l
End Type

Dim As T4 x4 = (1, 2, 3, 4)

Dim As T3 w3 = Type<T4>(x4)
Print w3.i, w3.j, w3.k
Dim As T2 w2 = Type<T4>(x4)
Print w2.i, w2.j
Dim As T1 w1 = Type<T4>(x4)
Print w1.i
Print

Sleep

Code: Select all

C:\Users\fxmam\OneDrive\Documents\Mes Outils Personnels\FBIde0.4.6r4-FreeBASIC1.10.0.win64+win32-gcc\FBIDETEMP.c: In function 'main':
C:\Users\fxmam\OneDrive\Documents\Mes Outils Personnels\FBIde0.4.6r4-FreeBASIC1.10.0.win64+win32-gcc\FBIDETEMP.c:59:2: warning: '__builtin_memcpy' writing 32 bytes into a region of size 24 overflows the destination 
   59 |  __builtin_memcpy( (struct $2T4*)&W3$0, &X4$0, 32 );
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\fxmam\OneDrive\Documents\Mes Outils Personnels\FBIde0.4.6r4-FreeBASIC1.10.0.win64+win32-gcc\FBIDETEMP.c:64:2: warning: '__builtin_memcpy' writing 32 bytes into a region of size 16 overflows the destination 
   64 |  __builtin_memcpy( (struct $2T4*)&W2$0, &X4$0, 32 );
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\fxmam\OneDrive\Documents\Mes Outils Personnels\FBIde0.4.6r4-FreeBASIC1.10.0.win64+win32-gcc\FBIDETEMP.c:68:2: warning: '__builtin_memcpy' writing 32 bytes into a region of size 8 overflows the destination 
   68 |  __builtin_memcpy( (struct $2T4*)&W1$0, &X4$0, 32 );
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2) Crash:

Code: Select all

Type T1
    Dim As Integer i
End Type
Type T2 Extends T1
    Dim As Integer j
End Type
Type T3 Extends T2
    Dim As Integer k
End Type
Type T4 Extends T3
    Dim As Integer l
End Type

Dim As T4 x4 = (1, 2, 3, 4)

Dim As T3 Ptr q33 = New T3(Type<T4>(x4))
Print q33->i, q33->j, q33->k
Dim As T2 Ptr q23 = New T3(Type<T4>(x4))
Print q23->i, q23->j, Cptr(T3 Ptr, q23)->k
Dim As T1 Ptr q13 = New T3(Type<T4>(x4))
Print q13->i, Cptr(T3 Ptr, q13)->j, Cptr(T3 Ptr, q13)->k
Dim As T2 Ptr q22 = New T2(Type<T4>(x4))
Print q22->i, q22->j
Dim As T1 Ptr q12 = New T2(Type<T4>(x4))
Print q12->i, Cptr(T2 Ptr, q12)->j
Dim As T1 Ptr q11 = New T1(Type<T4>(x4))
Print q11->i

Sleep

But these without 'Type()' seem to work:

Code: Select all

Type T1
    Dim As Integer i
End Type
Type T2 Extends T1
    Dim As Integer j
End Type
Type T3 Extends T2
    Dim As Integer k
End Type
Type T4 Extends T3
    Dim As Integer l
End Type

Dim As T4 x4 = (1, 2, 3, 4)

Dim As T3 u3 = x4
Print u3.i, u3.j, u3.k
Dim As T2 u2 = x4
Print u2.i, u2.j
Dim As T1 u1 = x4
Print u1.i
Print

Dim As T3 v3 = (x4)
Print v3.i, v3.j, v3.k
Dim As T2 v2 = (x4)
Print v2.i, v2.j
Dim As T1 v1 = (x4)
Print v1.i
Print

Dim As T3 Ptr p33 = New T3(x4)
Print p33->i, p33->j, p33->k
Dim As T2 Ptr p23 = New T3(x4)
Print p23->i, p23->j, Cptr(T3 Ptr, p23)->k
Dim As T1 Ptr p13 = New T3(x4)
Print p13->i, Cptr(T3 Ptr, p13)->j, Cptr(T3 Ptr, p13)->k
Dim As T2 Ptr p22 = New T2(x4)
Print p22->i, p22->j
Dim As T1 Ptr p12 = New T2(x4)
Print p12->i, Cptr(T2 Ptr, p12)->j
Dim As T1 Ptr p11 = New T1(x4)
Print p11->i
Print

Sleep
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

happy new year
fxm wrote: Jan 01, 2023 16:35 Some syntaxes not supported with 'Type()' ?

1) Compilation warnings:

Code: Select all

'__builtin_memcpy' writing 32 bytes into a region of size 24 overflows the destination 
   59 |  __builtin_memcpy( (struct $2T4*)&W3$0, &X4$0, 32 );
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I just noticed today also. But was from a change a few days ago.

I'm fairly certain it has to do with initializers (and padding too) that must be discarded. The logic doesn't catch all the cases.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Jan 01, 2023 16:48 I just noticed today also. But was from a change a few days ago.

I'm fairly certain it has to do with initializers (and padding too) that must be discarded. The logic doesn't catch all the cases.
Yes, I had noticed this before, but I waited a bit for after the fix for 'New()'.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

With 'New(Placement)', we can check write overflow when 'Type()' is used as initializer of 'New()':

Code: Select all

Type T1            : Dim As Integer i : End Type
Type T2 Extends T1 : Dim As Integer j : End Type
Type T3 Extends T2 : Dim As Integer k : End Type
Type T4 Extends T3 : Dim As Integer l : End Type
Dim As T4 x4 = (1, 2, 3, 4)

Dim As Any Ptr p1 = Callocate(Sizeof(T4))
Dim As T4 Ptr p14 = Cptr(T4 Ptr, New(p1) T2(x4))
Print p14->i, p14->j, p14->k, p14->l

Dim As Any Ptr p2 = Callocate(Sizeof(T4))
Dim As T4 Ptr p24 = Cptr(T4 Ptr, New(p2) T2(Type<T4>(x4)))
Print p24->i, p24->j, p24->k, p24->l

Sleep

Code: Select all

 1             2             0             0
 1             2             3             4

Same problem when 'Type()' is used as initializer of 'Dim':

Code: Select all

Type T1            : Dim As Integer i : End Type
Type T2 Extends T1 : Dim As Integer j : End Type
Type T3 Extends T2 : Dim As Integer k : End Type
Type T4 Extends T3 : Dim As Integer l : End Type
Dim As T4 x4 = (1, 2, 3, 4)

Dim As T2 u21(0 To 1) = {x4}
Print u21(0).i, u21(0).j, u21(1).i, u21(1).j

Dim As T2 u22(0 To 1) = {Type<T4>(x4)}
Print u22(0).i, u22(0).j, u22(1).i, u22(1).j

Sleep

Code: Select all

 1             2             0             0
 1             2             3             4
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: FreeBASIC 1.10.0 Development

Post by SARG »

@fxm
Thanks. Happy New Year also to you and everyone, happy coding :D

As I said to Jeff "Type , etc never ending story" :wink:
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

fxm wrote: Jan 01, 2023 16:35 Some weird syntaxes with 'Type()' not supported ?
I committed a change that should fix this by using temporary variables to manage the initializers and up-casting.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

coderJeff wrote: Jan 02, 2023 4:46 I committed a change that should fix this by using temporary variables to manage the initializers and up-casting.
With this last change, it looks very good to me now.
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: FreeBASIC 1.10.0 Development

Post by coderJeff »

It was late when I finished up yesterday, so my description of the change was terse. Here's a some information about what is happening under the hood with the backend code generated.

Using this example:

Code: Select all

type t1            : dim as integer i : end type
type t2 extends t1 : dim as integer j : end type
type t3 extends t2 : dim as integer k : end type
type t4 extends t3 : dim as integer l : end type
1) direct initializer assignment, this looks OK.

Code: Select all

dim as t4 x4 = (1, 2, 3, 4)

backend code generated:
x.i = 1 '' initialize
x.j = 2 '' initialize
x.k = 3 '' initialize
x.l = 4 '' initialize
2) Up-cast directly - shallow copy, this looks OK:

Code: Select all

dim as t2 x2 = x4

backend code generated:
memcpy( @x2, @x4, sizeof(t2) )
3) Initialization through TYPE()? It now creates a temporary copy - I think previously it was supposed to be optimized out but handled badly. In an earlier attempt I tried to only discard initializers instead and added "-w upcast" warning.

Code: Select all

dim as t2 x2 = type<t4>(1,2,3,4)

backend code generated:
var tmp = type<t4>(1,2,3,4)
memcpy( @x2, @tmp, sizeof(t2) )
4) same with TYPE() up-casted to array element, creates a temporary instance

Code: Select all

dim as t2 u22(0 to 1) = {type<t4>x4}

backend code generated:
var tmp = x4
memcpy( @u22(0), @tmp, sizeof(t2) )
memset( @u22(1),    0, sizeof(t2) )
5) but also with direct up-cast to array element, creates a temporary:

Code: Select all

dim as t2 u22(0 to 1) = {x4}

backend code generated:
var tmp = x4
memcpy( @u22(0), @tmp, sizeof(t2) )
memset( @u22(1),    0, sizeof(t2) )
In the cases 3,4 & 5 above where temporary variables are used:
- we shouldn't overwrite past the bounds of variables
- but temporary variables created as a work-around

There's probably plenty more to improve, but hopefully it at least works correctly even if the current code generation is a little bloated.

My concern for right now:
If we are not up-casting, then no temporary variables should be created.
- but will have to check for that by analyzing the backend code.
- Also, due to temporary variables, the warning about up-cast initializers being discarded won't trigger.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

type<t4>x4
I did not know this shortened syntax (without parentheses) !
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

There are as many temporary variables created as elementary up-casts through TYPE():

Code: Select all

type t1            : dim as integer i : declare destructor() : end type
type t2 extends t1 : dim as integer j : declare destructor() : end type
type t3 extends t2 : dim as integer k : declare destructor() : end type
type t4 extends t3 : dim as integer l : declare destructor() : end type
destructor t1() : print "      destructor t1()", @this : end destructor
destructor t2() : print "      destructor t2()", @this : end destructor
destructor t3() : print "      destructor t3()", @this : end destructor
destructor t4() : print "      destructor t4()", @this : end destructor

Print "'Dim As t3 u3 = Type<t3>(Type<t3>(Type<t3>(1, 2, 3)))':"
Scope
    Print "   Destruction of temporary variable(s):"
    Dim As t3 u3 = Type<t3>(Type<t3>(Type<t3>(1, 2, 3)))
    Print "   Destruction of local variable:":
End Scope
Print

Print "'Dim As t1 u1 = Type<t2>(Type<t3>(Type<t4>(1, 2, 3, 4)))':"
Scope
    Print "   Destruction of temporary variable(s):"
    Dim As t1 u1 = Type<t2>(Type<t3>(Type<t4>(1, 2, 3, 4)))
    Print "   Destruction of local variable:":
End Scope

Sleep

Code: Select all

'Dim As t3 u3 = Type<t3>(Type<t3>(Type<t3>(1, 2, 3)))':
   Destruction of temporary variable(s):
   Destruction of local variable:
      destructor t3()       6421936
      destructor t2()       6421936
      destructor t1()       6421936

'Dim As t1 u1 = Type<t2>(Type<t3>(Type<t4>(1, 2, 3, 4)))':
   Destruction of temporary variable(s):
      destructor t4()       6421840
      destructor t3()       6421840
      destructor t2()       6421840
      destructor t1()       6421840
      destructor t3()       6421888
      destructor t2()       6421888
      destructor t1()       6421888
      destructor t2()       6421920
      destructor t1()       6421920
   Destruction of local variable:
      destructor t1()       6421880
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: FreeBASIC 1.10.0 Development

Post by SARG »

Looking at the generated code
Dim As t3 u3 = Type<t3>(Type<t3>(Type<t3>(1, 2, 3))) is equivalent to Dim As t3 u3 = Type<t3>(1, 2, 3) so values 1,2,3 can be directly assigned.
And after nested destructors.

Not the same with Dim As t1 u1 = Type<t2>(Type<t3>(Type<t4>(1, 2, 3, 4))) where each type is constructed and partially copied then needed to be destructed at each level of nesting.
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: FreeBASIC 1.10.0 Development

Post by fxm »

My above example:
'Dim As t1 u1 = Type<t2>(Type<t3>(Type<t4>(1, 2, 3, 4)))'
is a pure school example, because the coder naturally would rather use:
'Dim As t1 u1 = Type<t4>(1, 2, 3, 4)'
or even simpler, so no change to add (no internal simplification) and the existing (raw coding of the user expression) at least has the merit of being robust.
Post Reply