Skip to content

Commit dc958cb

Browse files
authored
Merge pull request #90 from jayrm/cast-conv-ptr
Casting, Conversions, Const Qualifiers, Byref Revision 145c13f to 8e8801b Fixes for: - https://sourceforge.net/p/fbc/bugs/642 Pointer casting allows constness dropping - https://sourceforge.net/p/fbc/bugs/886 Inconsistent error with BYREF and CAST on CONST variables - https://sourceforge.net/p/fbc/bugs/801 parser allows more constructs under -exx than without it - https://sourceforge.net/p/fbc/bugs/880 Overload binary operators do not support covariant arguments - https://sourceforge.net/p/fbc/bugs/727 RTL functions not checking Constness unless marked RTL_CONST
2 parents 056bc94 + 8e8801b commit dc958cb

File tree

112 files changed

+44674
-18366
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+44674
-18366
lines changed

changelog.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ Version 1.06.0
55
- test-suite uses libfbcunit for unit testing framework
66
- SELECT CASE AS CONST respects data type and will show overflow warnings on out-of-range constants
77
- boolean: don't allow NEG unary op '-' on boolean data types
8+
- All fb RTL functions are checked for CONSTness, CONST qualifiers added to fb rtlib built-in prototypes (sf.net #727)
9+
- WSTRING can be a return type, but only for prototypes (DECLARE) and function pointers, this allows getting PROCPTR() of all fb built-in run time functions
810

911
[added]
1012
- -noobjinfo option to disable the writing/reading of compile-time library and other linking options from/to .o and .a files. This also disables the use of fbextra.x (the supplemental linker script) for discarding the .fbctinf sections, which is useful when using the gold linker that doesn't support this kind of linker script.
@@ -15,6 +17,8 @@ Version 1.06.0
1517
- Updated bindings: SDL2 2.0.6, SDL2_image 2.0.1, SDL2_mixer 2.0.1, SDL2_net 2.0.1, SDL2_ttf 2.0.14
1618
- allow overload operator SQR()
1719
- allow [static] shared byref variables to be initialized with byref variable
20+
- warning '-w constness' to enable 'CONST qualifier discarded' warning on command line
21+
- #pragma constness to enable/disable 'CONST qualifier discarded' warning in source code
1822

1923
[fixed]
2024
- win/d3dx9.bi no longer has a hard-coded #inclib "d3dx9d". d3dx9d.dll is apparently not a generally valid choice. In practice programs have to be linked against d3dx9_33.dll or d3dx9_39.dll, etc.
@@ -65,6 +69,9 @@ Version 1.06.0
6569
- #822, #814, #842: Compiler crash when initializing static/shared reference (DIM SHARED/STATIC BYREF) with non-constant initializer (e.g. another reference, or dynamic array element)
6670
- ASM backend: Fix bad code generated for comparisons such as IF @globalvar = 0 THEN
6771
- #884: FORMATing dates can deadlock under Unix
72+
- #642, #886: CASTs involving CONST qualifiers solved out too early allowing invalid statements to be compiled
73+
- #801: *@(expr) solved to (expr) did not cleanly remove null ptr checks allowing invalid datatype assignment with -exx. *PTRCHK(@expr) solves to (expr).
74+
- #880: Overload binary operators now support covariant arguments, overloaded procedure resolution changed especially with respect to CONST and non-CONST parameters
6875

6976

7077
Version 1.05.0

src/compiler/ast-helper.bas

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,19 @@ function astBuildDerefAddrOf overload _
190190
n = astNewBOP( AST_OP_ADD, n, offsetexpr )
191191
end if
192192

193-
n = astNewCONV( typeAddrOf( dtype ), subtype, n, AST_CONVOPT_DONTCHKPTR )
193+
'' Don't warn on CONST qualifier changes, astBuildDerefAddrOf() is only
194+
'' called for internal expressions in:
195+
'' - astBuildVarField(),
196+
'' - hShallowCopy()
197+
'' - hCallCtorList()
198+
'' - cDynamicArrayIndex()
199+
'' - cVariableEx()
200+
'' - hAssignDynamicArray()
201+
'' Except:
202+
'' - astTypeIniFlush(), HOWEVER, astNewASSIGN() does it's own
203+
'' checks and calls astNewCONV()
204+
205+
n = astNewCONV( typeAddrOf( dtype ), subtype, n, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )
194206
n = astNewDEREF( n )
195207

196208
if( maybeafield ) then
@@ -998,7 +1010,8 @@ function astBuildStrPtr( byval lhs as ASTNODE ptr ) as ASTNODE ptr
9981010
dtype = typeSetIsConst( typeAddrOf( dtype ) )
9991011
dtype = typeAddrOf( dtype )
10001012

1001-
expr = astNewDEREF( astNewCONV( dtype, NULL, astNewADDROF( lhs ) ) )
1013+
'' Don't warn on CONST qualifier changes, we are explicitly forcing the conversion
1014+
expr = astNewDEREF( astNewCONV( dtype, NULL, astNewADDROF( lhs ), AST_CONVOPT_DONTWARNCONST ) )
10021015

10031016
return expr
10041017
end function

src/compiler/ast-misc.bas

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ function astIsEqualParamInit _
223223
'' symbols, but if they have the same signature they should still be
224224
'' treated equal here.
225225
if( typeGetDtOnly( l->dtype ) = FB_DATATYPE_FUNCTION ) then
226-
if( symbCalcProcMatch( l->subtype, r->subtype, 0 ) = 0 ) then
226+
if( symbCalcProcMatch( l->subtype, r->subtype, 0 ) = FB_OVLPROC_NO_MATCH ) then
227227
exit function
228228
end if
229229
else
@@ -665,7 +665,7 @@ function astPtrCheck _
665665
'' do this manually already (and if there is a CONSTness mismatch, they show an error,
666666
'' not just a warning, which is astPtrCheck()'s main purpose).
667667
function = (typeCalcMatch( typeGetDtAndPtrOnly( pdtype ), psubtype, pparammode, _
668-
typeGetDtAndPtrOnly( edtype ), expr->subtype ) > 0)
668+
typeGetDtAndPtrOnly( edtype ), expr->subtype ) > FB_OVLPROC_NO_MATCH)
669669
end function
670670

671671
'':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@@ -985,7 +985,7 @@ sub astDtorListDump( )
985985
print "-------------- dtorlist: ------------------"
986986
i = listGetTail( @ast.dtorlist )
987987
while( i )
988-
print " ";symbDump( i->sym );" cookie: ";i->cookie;" refcount: ";i->refcount;" has dtor? ";hHasDtor( i->sym )
988+
print " ";symbDumpToStr( i->sym );" cookie: ";i->cookie;" refcount: ";i->refcount;" has dtor? ";hHasDtor( i->sym )
989989
i = listGetPrev( i )
990990
wend
991991
end sub

src/compiler/ast-node-addr.bas

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ function astNewADDROF( byval l as ASTNODE ptr ) as ASTNODE ptr
217217
if( t <> l ) then
218218
astDelNode( l ) '' CONV that was skipped above
219219
end if
220-
return astNewCONV( dtype, subtype, n, AST_CONVOPT_DONTCHKPTR )
220+
'' Don't warn CONST changes, we should have already got the warnings on previous CONV node's
221+
return astNewCONV( dtype, subtype, n, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )
221222
end if
222223

223224
'' alloc new node

src/compiler/ast-node-arg.bas

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ private sub hStrArgToStrPtrParam _
249249
n->l = hAllocTmpString( parent, n->l, FALSE )
250250
end if
251251

252+
'' *cast( [const] zstring const ptr ptr, @expr )
253+
'' Don't worry about preserving CONST bits, astNewARG() should have checked.
252254
n->l = astBuildStrPtr( n->l )
253255

254256
case FB_DATATYPE_FIXSTR
@@ -273,7 +275,8 @@ end sub
273275

274276
sub hBuildByrefArg( byval param as FBSYMBOL ptr, byval n as ASTNODE ptr )
275277
n->l = astNewADDROF( astRemoveNoConvCAST( n->l ) )
276-
n->l = astNewCONV( typeAddrOf( symbGetFullType( param ) ), symbGetSubtype( param ), n->l )
278+
'' Don't warn on CONST qualifier changes, astNewARG() should have checked
279+
n->l = astNewCONV( typeAddrOf( symbGetFullType( param ) ), symbGetSubtype( param ), n->l, AST_CONVOPT_DONTWARNCONST )
277280
assert( n->l )
278281
n->arg.mode = FB_PARAMMODE_BYVAL
279282
end sub
@@ -1012,10 +1015,9 @@ function astNewARG _
10121015
'' a ctor that can't initialize the object would be useless, and after
10131016
'' dtors run the object is dead anyways, so modifications made by the
10141017
'' dtor don't matter)
1015-
if( ((symbGetIsRTL( sym ) = FALSE) or symbGetIsRTLConst( param )) and _
1016-
((not symbIsInstanceParam( param )) or _
1018+
if( ((not symbIsInstanceParam( param )) or _
10171019
((sym->attrib and FB_SYMBATTRIB_NOTHISCONSTNESS) = 0)) ) then
1018-
if( symbCheckConstAssign( symbGetFullType( param ), dtype, param->subtype, arg->subtype, symbGetParamMode( param ) ) = FALSE ) then
1020+
if( symbCheckConstAssignTopLevel( symbGetFullType( param ), dtype, param->subtype, arg->subtype, symbGetParamMode( param ) ) = FALSE ) then
10191021
if( symbIsInstanceParam( param ) ) then
10201022
errReportParam( parent->sym, 0, NULL, FB_ERRMSG_CONSTUDTTONONCONSTMETHOD )
10211023
else

src/compiler/ast-node-assign.bas

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ private function hCheckConstAndPointerOps _
200200
function = FALSE
201201

202202
'' lhs marked CONST? disallow the assignment then.
203-
if( symbCheckConstAssign( ldtype, rdtype, l->subtype, r->subtype ) = FALSE ) then
203+
if( symbCheckConstAssignTopLevel( ldtype, rdtype, l->subtype, r->subtype ) = FALSE ) then
204204
errReport( FB_ERRMSG_ILLEGALASSIGNMENT, TRUE )
205205
exit function
206206
end if
@@ -379,7 +379,7 @@ function astCheckByrefAssign _
379379
byval lsubtype as FBSYMBOL ptr, _
380380
byval r as ASTNODE ptr _
381381
) as integer
382-
function = (typeCalcMatch( ldtype, lsubtype, FB_PARAMMODE_BYREF, r->dtype, r->subtype ) > 0)
382+
function = (typeCalcMatch( ldtype, lsubtype, FB_PARAMMODE_BYREF, r->dtype, r->subtype ) > FB_OVLPROC_NO_MATCH)
383383
end function
384384

385385
private function hShallowCopy _

src/compiler/ast-node-call.bas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function astNewCALL _
5555
''
5656
if( ptrexpr ) then
5757
assert( astGetDataType( ptrexpr ) = typeAddrOf( FB_DATATYPE_FUNCTION ) )
58-
assert( (ptrexpr->subtype = sym) or (symbCalcProcMatch( ptrexpr->subtype, sym, 0 ) > 0) )
58+
assert( (ptrexpr->subtype = sym) or (symbCalcProcMatch( ptrexpr->subtype, sym, 0 ) > FB_OVLPROC_NO_MATCH) )
5959
sym = ptrexpr->subtype
6060
end if
6161

src/compiler/ast-node-conv.bas

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ function astNewCONV _
305305
) as ASTNODE ptr
306306

307307
dim as ASTNODE ptr n = any
308-
dim as integer ldclass = any, ldtype = any, errmsg = any, doconv = any
308+
dim as integer ldclass = any, ldtype = any, errmsg = any, wrnmsg = any, doconv = any
309309

310310
if( perrmsg ) then
311311
*perrmsg = FB_ERRMSG_OK
@@ -317,7 +317,7 @@ function astNewCONV _
317317
if( typeGetDtAndPtrOnly( ldtype ) = typeGetDtAndPtrOnly( to_dtype ) ) then
318318
if( l->subtype = to_subtype ) then
319319
'' Only CONST bits changed?
320-
if( ldtype <> to_dtype ) then
320+
if( typeGetConstMask( ldtype ) <> typeGetConstMask( to_dtype ) ) then
321321
'' CONST node? Evaluate at compile-time
322322
if( astIsCONST( l ) ) then
323323
astSetType( l, to_dtype, to_subtype )
@@ -327,8 +327,19 @@ function astNewCONV _
327327
'' to the expression parser
328328
n = astNewNode( AST_NODECLASS_CONV, to_dtype, to_subtype )
329329
n->l = l
330+
330331
n->cast.doconv = FALSE
331332
n->cast.do_convfd2fs = FALSE
333+
334+
'' data types and levels of pointer inderection are the same,
335+
'' always record this as const conversion
336+
n->cast.convconst = TRUE
337+
338+
if( (options and AST_CONVOPT_DONTWARNCONST) = 0 ) then
339+
if( fbPdCheckIsSet( FB_PDCHECK_CONSTNESS ) ) then
340+
errReportWarn( FB_WARNINGMSG_CONSTQUALIFIERDISCARDED )
341+
end if
342+
end if
332343
end if
333344
else
334345
n = l
@@ -472,6 +483,32 @@ function astNewCONV _
472483
n->l = l
473484
n->cast.doconv = doconv
474485
n->cast.do_convfd2fs = FALSE
486+
n->cast.convconst = FALSE
487+
488+
'' Discarding/changing const qualifier bits ?
489+
if( typeIsPtr( ldtype ) and typeIsPtr( to_dtype ) ) then
490+
491+
wrnmsg = 0
492+
493+
n->cast.convconst = ( symbCheckConstAssign( to_dtype, ldtype, to_subtype, l->subtype, , , wrnmsg ) = FALSE )
494+
495+
'' else check if const conversion
496+
if( n->cast.convconst ) then
497+
if( (options and AST_CONVOPT_DONTWARNCONST) = 0 ) then
498+
if( fbPdCheckIsSet( FB_PDCHECK_CONSTNESS ) ) then
499+
'' specific warning message takes priority over const warning
500+
if( wrnmsg = 0 ) then
501+
wrnmsg = FB_WARNINGMSG_CONSTQUALIFIERDISCARDED
502+
end if
503+
end if
504+
end if
505+
end if
506+
507+
'' warning? show it now
508+
if( wrnmsg <> 0 ) then
509+
errReportWarn( wrnmsg )
510+
end if
511+
end if
475512

476513
if( env.clopt.backend = FB_BACKEND_GAS ) then
477514
if( doconv ) then
@@ -560,6 +597,14 @@ function astLoadCONV _
560597

561598
vs = astLoad( l )
562599

600+
'' n->cast
601+
'' doconv convconst do_convfd2fs
602+
'' false false n/a same size
603+
'' false true n/a same size - different const qualifiers, doesn't matter now
604+
'' true false false different sizes
605+
'' true false true convert floating point double to single
606+
'' true true n/a different sizes - different const qualifiers, doesn't matter now
607+
563608
if( ast.doemit ) then
564609
vs->vector = n->vector
565610
if( n->cast.doconv ) then
@@ -593,7 +638,7 @@ end function
593638
function astSkipNoConvCAST( byval n as ASTNODE ptr ) as ASTNODE ptr
594639
function = n
595640
if( n->class = AST_NODECLASS_CONV ) then
596-
if( n->cast.doconv = FALSE ) then
641+
if( n->cast.doconv = FALSE and n->cast.convconst = FALSE ) then
597642
function = n->l
598643
end if
599644
end if
@@ -602,7 +647,7 @@ end function
602647
function astRemoveNoConvCAST( byval n as ASTNODE ptr ) as ASTNODE ptr
603648
function = n
604649
if( n->class = AST_NODECLASS_CONV ) then
605-
if( n->cast.doconv = FALSE ) then
650+
if( n->cast.doconv = FALSE and n->cast.convconst = FALSE ) then
606651
function = n->l
607652
n->l = NULL
608653
astDelTree( n )

src/compiler/ast-node-misc.bas

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ dim shared dbg_astNodeOpNames( 0 to AST_OPCODES - 1 ) as NameInfo = _
837837
( /' @"AST_OP_TOUNSIGNED" , '/ @"TOUNSIGNED" /' , 0 '/ ) _
838838
}
839839

840-
function astDumpOp( byval op as AST_OP ) as string
840+
function astDumpOpToStr( byval op as AST_OP ) as string
841841
if(( op > AST_OPCODES - 1 ) or ( op < 0 )) then
842842
return "OP:" + str(op)
843843
end if
@@ -881,10 +881,10 @@ private function hAstNodeToStr _
881881

882882
select case as const n->class
883883
case AST_NODECLASS_BOP
884-
return astDumpOp( n->op.op ) & " =-= " & hSymbToStr( n->op.ex )
884+
return astDumpOpToStr( n->op.op ) & " =-= " & hSymbToStr( n->op.ex )
885885

886886
case AST_NODECLASS_UOP
887-
return astDumpOp( n->op.op )
887+
return astDumpOpToStr( n->op.op )
888888

889889
case AST_NODECLASS_CONST
890890
if( typeGetClass( n->dtype ) = FB_DATACLASS_FPOINT ) then
@@ -911,7 +911,7 @@ private function hAstNodeToStr _
911911
return "LABEL: " & hSymbToStr( n->sym )
912912

913913
case AST_NODECLASS_BRANCH
914-
return "BRANCH: " & astDumpOp( n->op.op ) & " " & hSymbToStr( n->op.ex )
914+
return "BRANCH: " & astDumpOpToStr( n->op.op ) & " " & hSymbToStr( n->op.ex )
915915

916916
case AST_NODECLASS_SCOPEBEGIN
917917
return "SCOPEBEGIN: " & hSymbToStr( n->sym )
@@ -947,7 +947,7 @@ private sub astDumpTreeEx _
947947
's += "[" + hex( n, 8 ) + "] "
948948
s += hAstNodeToStr( n )
949949
#if __FB_DEBUG__
950-
s += " " + typeDump( n->dtype, n->subtype )
950+
s += " " + typeDumpToStr( n->dtype, n->subtype )
951951
#endif
952952
dbg_astOutput( s, col, just, depth )
953953

@@ -1010,7 +1010,7 @@ function astDumpInline( byval n as ASTNODE ptr ) as string
10101010
s = "<NULL>"
10111011
else
10121012
s += hAstNodeClassToStr( n->class )
1013-
's += typeDump( n->dtype, n->subtype )
1013+
's += typeDumpToStr( n->dtype, n->subtype )
10141014

10151015
var have_data = (n->sym <> NULL) or (n->l <> NULL) or (n->r <> NULL)
10161016
select case as const( n->class )
@@ -1024,7 +1024,7 @@ function astDumpInline( byval n as ASTNODE ptr ) as string
10241024

10251025
select case as const( n->class )
10261026
case AST_NODECLASS_BOP, AST_NODECLASS_UOP
1027-
s += astDumpOp( n->op.op ) + ", "
1027+
s += astDumpOpToStr( n->op.op ) + ", "
10281028
case AST_NODECLASS_CONST
10291029
if( typeGetClass( n->dtype ) = FB_DATACLASS_FPOINT ) then
10301030
s += str( astConstGetFloat( n ) ) + ", "
@@ -1071,7 +1071,7 @@ sub astDumpSmall( byval n as ASTNODE ptr, byref prefix as string )
10711071
else
10721072
's += "[" + hex( n ) + "] "
10731073
s += hAstNodeClassToStr( n->class )
1074-
s += typeDump( n->dtype, n->subtype )
1074+
s += typeDumpToStr( n->dtype, n->subtype )
10751075

10761076
select case as const( n->class )
10771077
case AST_NODECLASS_MEM
@@ -1088,10 +1088,14 @@ sub astDumpSmall( byval n as ASTNODE ptr, byref prefix as string )
10881088
case AST_NODECLASS_IDX : if( n->idx.ofs ) then s += " ofs=" & n->idx.ofs
10891089
if( n->idx.mult <> 1 ) then s += " mult=" & n->idx.mult
10901090
case AST_NODECLASS_BOP, AST_NODECLASS_UOP
1091-
s += " " + astDumpOp( n->op.op )
1091+
s += " " + astDumpOpToStr( n->op.op )
10921092
case AST_NODECLASS_CONV
1093-
if( n->cast.doconv = FALSE ) then
1093+
if( n->cast.doconv = FALSE and n->cast.convconst = FALSE ) then
10941094
s += " noconv"
1095+
elseif( n->cast.doconv ) then
1096+
s += " conv"
1097+
elseif( n->cast.convconst ) then
1098+
s += " convconst"
10951099
end if
10961100
case AST_NODECLASS_CONST
10971101
if( typeGetClass( n->dtype ) = FB_DATACLASS_FPOINT ) then
@@ -1112,7 +1116,7 @@ sub astDumpSmall( byval n as ASTNODE ptr, byref prefix as string )
11121116
s += *n->sym->id.name
11131117
end if
11141118
#else
1115-
s += " " + symbDump( n->sym )
1119+
s += " " + symbDumpToStr( n->sym )
11161120
#endif
11171121
end if
11181122
end if

src/compiler/ast-node-ptr.bas

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,44 @@ function astNewDEREF _
3636

3737
case AST_NODECLASS_OFFSET
3838
delchild = (t->ofs.ofs = 0)
39+
40+
case AST_NODECLASS_PTRCHK
41+
42+
'' convert *PTRCHK(@expr) to (expr)
43+
'' TODO: remove null-ptr checks in ptr indexing
44+
45+
if( (t->l->class = AST_NODECLASS_ADDROF) or _
46+
(t->l->class = AST_NODECLASS_OFFSET and t->l->ofs.ofs = 0) ) then
47+
48+
'' delete the null ptr check func call
49+
astDelTree( t->r )
50+
51+
'' move to ADDROF/OFFSET node
52+
t = t->l
53+
54+
delchild = TRUE
55+
else
56+
delchild = FALSE
57+
end if
3958

4059
case else
4160
delchild = FALSE
4261
end select
4362

4463
''
4564
if( delchild ) then
65+
4666
n = t->l
47-
astDelNode( t )
48-
if( t <> l ) then
67+
68+
'' astSkipNoConvCAST() and removing the null pointer check
69+
'' may have skipped multiple nodes
70+
'' delete all nodes from L to T (up to but not including N)
71+
72+
while( l <> n )
73+
t = l->l
4974
astDelNode( l )
50-
end if
75+
l = t
76+
wend
5177

5278
astSetType( n, dtype, subtype )
5379
return n

0 commit comments

Comments
 (0)