Skip to content

Commit 5efd77a

Browse files
authored
Merge pull request #274 from jayrm/git203
fbc: github # 203: allow casts of addresses on static initializers
2 parents 48d91ca + af8cda6 commit 5efd77a

File tree

3 files changed

+102
-16
lines changed

3 files changed

+102
-16
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Version 1.08.0
3030
- sf.net #927: PUT custom method expects function(ulong,ulong,any pr) as ulong callback function
3131
- fbc: double the minimum and default stacksize on 64-bit to 64Kb and 2048Kb respectively.
3232
- fbc: internal changes to optimize away unused call results
33+
- github #203: allow casts of addresses on static initializers
3334

3435
[added]
3536
- extern "rtlib": respects the parent namespace, uses default fb calling convention and C style name mangling

src/compiler/ast-node-typeini.bas

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -544,22 +544,40 @@ private sub hFlushExprStatic( byval n as ASTNODE ptr, byval basesym as FBSYMBOL
544544

545545
'' not a literal string?
546546
if( litsym = NULL ) then
547-
'' offset?
547+
'' offset?
548548
if( astIsOFFSET( expr ) ) then
549549
irEmitVARINIOFS( sym, astGetSymbol( expr ), expr->ofs.ofs )
550+
550551
'' anything else
551552
else
552-
'' different types?
553-
if( edtype <> sdtype ) then
554-
expr = astNewCONV( sfulldtype, symbGetSubtype( sym ), expr, AST_CONVOPT_DONTCHKPTR )
555-
assert( expr <> NULL )
556-
end if
553+
'' Explicit cast of an address? We can discard the cast if it's an offset.
554+
scope
555+
var lexpr = expr->l
556+
while( lexpr )
557+
if( astIsOFFSET( lexpr ) ) then
558+
irEmitVARINIOFS( sym, astGetSymbol( lexpr ), lexpr->ofs.ofs )
559+
expr = NULL
560+
exit while
561+
end if
562+
lexpr = lexpr->l
563+
wend
564+
end scope
565+
566+
if( expr ) then
567+
'' must be a constant
568+
assert( astIsCONST( expr ) )
569+
570+
'' different types? and there was no explicit cast?
571+
if( edtype <> sdtype ) then
572+
expr = astNewCONV( sfulldtype, symbGetSubtype( sym ), expr, AST_CONVOPT_DONTCHKPTR )
573+
assert( expr <> NULL )
574+
end if
557575

558-
assert( astIsCONST( expr ) )
559-
if( typeGetClass( sdtype ) = FB_DATACLASS_FPOINT ) then
560-
irEmitVARINIf( sym, astConstGetFloat( expr ) )
561-
else
562-
irEmitVARINIi( sym, astConstGetInt( expr ) )
576+
if( typeGetClass( sdtype ) = FB_DATACLASS_FPOINT ) then
577+
irEmitVARINIf( sym, astConstGetFloat( expr ) )
578+
else
579+
irEmitVARINIi( sym, astConstGetInt( expr ) )
580+
end if
563581
end if
564582
end if
565583
'' literal string..
@@ -646,18 +664,38 @@ private function hExprIsConst( byval n as ASTNODE ptr ) as integer
646664
end if
647665
end if
648666

649-
var rexpr = n->l
667+
var expr = n->l
668+
669+
'' Expression must be:
670+
'' - constant, or
671+
'' - address-of global, or
672+
'' - conversion of address of global
673+
'' to be usable in global initializer.
674+
'' we should not need to worry about conversions / castings of contants
675+
'' because they should have been constant folded by now.
650676

651-
'' Expression must be constant or address-of global to be usable in global initializer
652-
select case( rexpr->class )
677+
select case( expr->class )
653678
case AST_NODECLASS_OFFSET, AST_NODECLASS_CONST
654679
return TRUE
680+
case AST_NODECLASS_CONV
681+
'' allow conversion of OFFSET's
682+
while( expr )
683+
select case( expr->class )
684+
case AST_NODECLASS_CONV
685+
case AST_NODECLASS_OFFSET
686+
return TRUE
687+
case else
688+
exit while
689+
end select
690+
expr = expr->l
691+
wend
692+
return FALSE
655693
end select
656694

657695
'' Or a string literal, for a global string.
658-
select case( astGetDataType( rexpr ) )
696+
select case( astGetDataType( expr ) )
659697
case FB_DATATYPE_CHAR, FB_DATATYPE_WCHAR
660-
if( astGetStrLitSymbol( rexpr ) ) then
698+
if( astGetStrLitSymbol( expr ) ) then
661699
return TRUE
662700
end if
663701
end select

tests/dim/static-const-init.bas

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# include "fbcunit.bi"
2+
3+
SUITE( fbc_tests.dim_.static_const_init )
4+
5+
sub s()
6+
end sub
7+
8+
function f1() as any ptr
9+
static f as any ptr = @s
10+
return f
11+
end function
12+
13+
function f2() as any ptr
14+
static f as any ptr = procptr( s )
15+
return f
16+
end function
17+
18+
function f3() as any ptr
19+
static f as any ptr = cptr( any ptr, @s )
20+
return f
21+
end function
22+
23+
function f4() as any ptr
24+
static f as any ptr = cptr( sub() ptr, @s )
25+
return f
26+
end function
27+
28+
function f5() as uinteger
29+
'' must be same size as sizeof(any ptr)
30+
static f as uinteger = cptr( uinteger, @s )
31+
return f
32+
end function
33+
34+
TEST( PROCPTR_ )
35+
var f = @s
36+
37+
'' CUNSG() returns a uinteger and will preserve size of pointers
38+
39+
CU_ASSERT( cunsg( f ) = cunsg( f1() ) )
40+
CU_ASSERT( cunsg( f ) = cunsg( f2() ) )
41+
CU_ASSERT( cunsg( f ) = cunsg( f3() ) )
42+
CU_ASSERT( cunsg( f ) = cunsg( f4() ) )
43+
CU_ASSERT( cunsg( f ) = cunsg( f5() ) )
44+
45+
END_TEST
46+
47+
END_SUITE

0 commit comments

Comments
 (0)