@@ -40,12 +40,18 @@ type RANGEVALUES
4040 as ulongint umax
4141end type
4242
43- ''
44- function cConstIntExprRanged _
43+ function hIsConstInRange _
4544 ( _
46- byval expr as ASTNODE ptr, _
45+ byval dtype as integer , _
46+ byval value as longint, _
4747 byval todtype as integer _
48- ) as longint
48+ ) as integer
49+
50+ '' TODO:
51+ '' - consider moving this table to symb-data.bas
52+ '' - consider using in astCheckConst(), possibly? with -w pedantic
53+ '' - consider adding src/compiler/fb-limit.bi or inc/fb-limit.bi. These
54+ '' limit values are used in several locations in fbc compiler source.
4955
5056 static range( FB_SIZETYPE_BOOLEAN to FB_SIZETYPE_UINT64 ) as RANGEVALUES = _
5157 { _
@@ -60,12 +66,45 @@ function cConstIntExprRanged _
6066 / ' FB_SIZETYPE_UINT64 '/ ( 0ll , &h7fffffffffffffffll, &hffffffffffffffffull ) _
6167 }
6268
69+ dim as RANGEVALUES ptr r = @range( typeGetSizeType( todtype ) )
70+
71+ if ( typeIsSigned( dtype ) ) then
72+ if ( typeIsSigned( todtype ) ) then
73+ function = (value >= r->smin) and (value <= r->smax)
74+ else
75+ if ( typeGetSizeType(dtype) = FB_SIZETYPE_INT64 and typeGetSizeType(todtype) = FB_SIZETYPE_UINT64 ) then
76+ function = (value >= 0 ) and (culngint(value) <= culngint(r->smax))
77+ else
78+ function = (value >= 0 ) and (culngint(value) <= r->umax)
79+ end if
80+ endif
81+ else
82+ if ( typeIsSigned( todtype ) ) then
83+ if ( typeGetSizeType(dtype) = FB_SIZETYPE_UINT64 and typeGetSizeType(todtype) = FB_SIZETYPE_INT64 ) then
84+ function = (culngint(value) <= culngint(r->smax))
85+ else
86+ function = (culngint(value) <= r->umax)
87+ end if
88+ else
89+ function = (culngint(value) <= r->umax)
90+ endif
91+ end if
92+
93+ end function
94+
95+ ''
96+ function cConstIntExprRanged _
97+ ( _
98+ byval expr as ASTNODE ptr, _
99+ byval todtype as integer _
100+ ) as longint
101+
102+ '' - this function is very similar cConstIntExpr() except that
103+ '' we need to save the dtype of expr before it is flushed, but
104+ '' if expr was invalid it might be NULL
105+
63106 dim as longint value = any
64107 dim as integer dtype = any
65- dim as integer result = any
66- dim as RANGEVALUES ptr r = any
67-
68- r = @range( typeGetSizeType( todtype ) )
69108
70109 '' bad expression? fake a constant value
71110 if ( expr = NULL ) then
@@ -86,29 +125,7 @@ function cConstIntExprRanged _
86125 '' flush the expr to longint, it's the largest signed integer datatype we have
87126 value = astConstFlushToInt( expr, FB_DATATYPE_LONGINT )
88127
89- if ( typeIsSigned( dtype ) ) then
90- if ( typeIsSigned( todtype ) ) then
91- result = (value >= r->smin) and (value <= r->smax)
92- else
93- if ( typeGetSizeType(dtype) = FB_SIZETYPE_INT64 and typeGetSizeType(todtype) = FB_SIZETYPE_UINT64 ) then
94- result = (value >= 0 ) and (culngint(value) <= culngint(r->smax))
95- else
96- result = (value >= 0 ) and (culngint(value) <= r->umax)
97- end if
98- endif
99- else
100- if ( typeIsSigned( todtype ) ) then
101- if ( typeGetSizeType(dtype) = FB_SIZETYPE_UINT64 and typeGetSizeType(todtype) = FB_SIZETYPE_INT64 ) then
102- result = (culngint(value) <= culngint(r->smax))
103- else
104- result = (culngint(value) <= r->umax)
105- end if
106- else
107- result = (culngint(value) <= r->umax)
108- endif
109- end if
110-
111- if ( not result ) then
128+ if ( not hIsConstInRange( dtype, value, todtype ) ) then
112129 errReportWarn( FB_WARNINGMSG_CONVOVERFLOW )
113130 end if
114131
0 commit comments