@@ -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
0 commit comments