Bug Summary

File:build/gcc/value-range.h
Warning:line 689, column 10
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name value-range.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-hkkovc.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc

/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc

1/* Support routines for value ranges.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Major hacks by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew MacLeod <amacleod@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "backend.h"
26#include "tree.h"
27#include "gimple.h"
28#include "ssa.h"
29#include "tree-pretty-print.h"
30#include "value-range-pretty-print.h"
31#include "fold-const.h"
32#include "gimple-range.h"
33
34void
35irange::accept (const vrange_visitor &v) const
36{
37 v.visit (*this);
38}
39
40void
41unsupported_range::accept (const vrange_visitor &v) const
42{
43 v.visit (*this);
44}
45
46// Convenience function only available for integers and pointers.
47
48wide_int
49Value_Range::lower_bound () const
50{
51 if (is_a <irange> (*m_vrange))
52 return as_a <irange> (*m_vrange).lower_bound ();
53 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 53, __FUNCTION__))
;
54}
55
56// Convenience function only available for integers and pointers.
57
58wide_int
59Value_Range::upper_bound () const
60{
61 if (is_a <irange> (*m_vrange))
62 return as_a <irange> (*m_vrange).upper_bound ();
63 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 63, __FUNCTION__))
;
64}
65
66void
67Value_Range::dump (FILE *out) const
68{
69 if (m_vrange)
70 m_vrange->dump (out);
71 else
72 fprintf (out, "NULL");
73}
74
75DEBUG_FUNCTION__attribute__ ((__used__)) void
76debug (const Value_Range &r)
77{
78 r.dump (stderrstderr);
79 fprintf (stderrstderr, "\n");
80}
81
82// Default vrange definitions.
83
84bool
85vrange::contains_p (tree) const
86{
87 return varying_p ();
88}
89
90bool
91vrange::singleton_p (tree *) const
92{
93 return false;
94}
95
96void
97vrange::set (tree min, tree, value_range_kind)
98{
99 set_varying (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 99, __FUNCTION__))->typed.type)
);
100}
101
102tree
103vrange::type () const
104{
105 return void_type_nodeglobal_trees[TI_VOID_TYPE];
106}
107
108bool
109vrange::supports_type_p (const_tree) const
110{
111 return false;
112}
113
114void
115vrange::set_undefined ()
116{
117 m_kind = VR_UNDEFINED;
118}
119
120void
121vrange::set_varying (tree)
122{
123 m_kind = VR_VARYING;
124}
125
126bool
127vrange::union_ (const vrange &r)
128{
129 if (r.undefined_p () || varying_p ())
130 return false;
131 if (undefined_p () || r.varying_p ())
132 {
133 operator= (r);
134 return true;
135 }
136 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 136, __FUNCTION__))
;
137 return false;
138}
139
140bool
141vrange::intersect (const vrange &r)
142{
143 if (undefined_p () || r.varying_p ())
144 return false;
145 if (r.undefined_p ())
146 {
147 set_undefined ();
148 return true;
149 }
150 if (varying_p ())
151 {
152 operator= (r);
153 return true;
154 }
155 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 155, __FUNCTION__))
;
156 return false;
157}
158
159bool
160vrange::zero_p () const
161{
162 return false;
163}
164
165bool
166vrange::nonzero_p () const
167{
168 return false;
169}
170
171void
172vrange::set_nonzero (tree type)
173{
174 set_varying (type);
175}
176
177void
178vrange::set_zero (tree type)
179{
180 set_varying (type);
181}
182
183void
184vrange::set_nonnegative (tree type)
185{
186 set_varying (type);
187}
188
189bool
190vrange::fits_p (const vrange &) const
191{
192 return true;
193}
194
195// Assignment operator for generic ranges. Copying incompatible types
196// is not allowed.
197
198vrange &
199vrange::operator= (const vrange &src)
200{
201 if (is_a <irange> (src))
202 as_a <irange> (*this) = as_a <irange> (src);
203 else if (is_a <frange> (src))
204 as_a <frange> (*this) = as_a <frange> (src);
205 else
206 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 206, __FUNCTION__))
;
207 return *this;
208}
209
210// Equality operator for generic ranges.
211
212bool
213vrange::operator== (const vrange &src) const
214{
215 if (is_a <irange> (src))
216 return as_a <irange> (*this) == as_a <irange> (src);
217 if (is_a <frange> (src))
218 return as_a <frange> (*this) == as_a <frange> (src);
219 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 219, __FUNCTION__))
;
220}
221
222// Wrapper for vrange_printer to dump a range to a file.
223
224void
225vrange::dump (FILE *file) const
226{
227 pretty_printer buffer;
228 pp_needs_newline (&buffer)(&buffer)->need_newline = true;
229 buffer.buffer->stream = file;
230 vrange_printer vrange_pp (&buffer);
231 this->accept (vrange_pp);
232 pp_flush (&buffer);
233}
234
235bool
236irange::supports_type_p (const_tree type) const
237{
238 return supports_p (type);
239}
240
241// Return TRUE if R fits in THIS.
242
243bool
244irange::fits_p (const vrange &r) const
245{
246 return m_max_ranges >= as_a <irange> (r).num_pairs ();
247}
248
249void
250irange::set_nonnegative (tree type)
251{
252 set (build_int_cst (type, 0), TYPE_MAX_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 252, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
);
253}
254
255void
256frange::accept (const vrange_visitor &v) const
257{
258 v.visit (*this);
259}
260
261// Flush denormal endpoints to the appropriate 0.0.
262
263void
264frange::flush_denormals_to_zero ()
265{
266 if (undefined_p () || known_isnan ())
267 return;
268
269 machine_mode mode = TYPE_MODE (type ())((((enum tree_code) ((tree_class_check ((type ()), (tcc_type)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 269, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type ()) : (type ())->type_common.mode)
;
270 // Flush [x, -DENORMAL] to [x, -0.0].
271 if (real_isdenormal (&m_max, mode) && real_isneg (&m_max))
272 {
273 m_max = dconst0;
274 if (HONOR_SIGNED_ZEROS (m_type))
275 m_max.sign = 1;
276 }
277 // Flush [+DENORMAL, x] to [+0.0, x].
278 if (real_isdenormal (&m_min, mode) && !real_isneg (&m_min))
279 m_min = dconst0;
280}
281
282// Setter for franges.
283
284void
285frange::set (tree type,
286 const REAL_VALUE_TYPEstruct real_value &min, const REAL_VALUE_TYPEstruct real_value &max,
287 const nan_state &nan, value_range_kind kind)
288{
289 switch (kind)
290 {
291 case VR_UNDEFINED:
292 set_undefined ();
293 return;
294 case VR_VARYING:
295 case VR_ANTI_RANGE:
296 set_varying (type);
297 return;
298 case VR_RANGE:
299 break;
300 default:
301 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 301, __FUNCTION__))
;
302 }
303
304 // Handle NANs.
305 if (real_isnan (&min) || real_isnan (&max))
306 {
307 gcc_checking_assert (real_identical (&min, &max))((void)(!(real_identical (&min, &max)) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 307, __FUNCTION__), 0 : 0))
;
308 bool sign = real_isneg (&min);
309 set_nan (type, sign);
310 return;
311 }
312
313 m_kind = kind;
314 m_type = type;
315 m_min = min;
316 m_max = max;
317 if (HONOR_NANS (m_type))
318 {
319 m_pos_nan = nan.pos_p ();
320 m_neg_nan = nan.neg_p ();
321 }
322 else
323 {
324 m_pos_nan = false;
325 m_neg_nan = false;
326 }
327
328 if (!MODE_HAS_SIGNED_ZEROS (TYPE_MODE (m_type))((((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_FLOAT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_DECIMAL_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_COMPLEX_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_VECTOR_FLOAT
) && ((real_format_for_mode[(((enum mode_class) mode_class
[as_a <scalar_float_mode> ((mode_to_inner (((((enum tree_code
) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_DECIMAL_FLOAT
) ? (((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_DECIMAL_FLOAT
) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class
) mode_class[as_a <scalar_float_mode> ((mode_to_inner (
((((enum tree_code) ((tree_class_check ((m_type), (tcc_type),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_FLOAT
? ((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_FLOAT
) : ((fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 328, __FUNCTION__)), 0)]))->has_signed_zero)
)
329 {
330 if (real_iszero (&m_min, 1))
331 m_min.sign = 0;
332 if (real_iszero (&m_max, 1))
333 m_max.sign = 0;
334 }
335 else if (!HONOR_SIGNED_ZEROS (m_type))
336 {
337 if (real_iszero (&m_max, 1))
338 m_max.sign = 0;
339 if (real_iszero (&m_min, 0))
340 m_min.sign = 1;
341 }
342
343 // For -ffinite-math-only we can drop ranges outside the
344 // representable numbers to min/max for the type.
345 if (!HONOR_INFINITIES (m_type))
346 {
347 REAL_VALUE_TYPEstruct real_value min_repr = frange_val_min (m_type);
348 REAL_VALUE_TYPEstruct real_value max_repr = frange_val_max (m_type);
349 if (real_less (&m_min, &min_repr))
350 m_min = min_repr;
351 else if (real_less (&max_repr, &m_min))
352 m_min = max_repr;
353 if (real_less (&max_repr, &m_max))
354 m_max = max_repr;
355 else if (real_less (&m_max, &min_repr))
356 m_max = min_repr;
357 }
358
359 // Check for swapped ranges.
360 gcc_checking_assert (real_compare (LE_EXPR, &min, &max))((void)(!(real_compare (LE_EXPR, &min, &max)) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 360, __FUNCTION__), 0 : 0))
;
361
362 normalize_kind ();
363
364 flush_denormals_to_zero ();
365
366 if (flag_checkingglobal_options.x_flag_checking)
367 verify_range ();
368}
369
370// Setter for an frange defaulting the NAN possibility to +-NAN when
371// HONOR_NANS.
372
373void
374frange::set (tree type,
375 const REAL_VALUE_TYPEstruct real_value &min, const REAL_VALUE_TYPEstruct real_value &max,
376 value_range_kind kind)
377{
378 nan_state nan;
379 set (type, min, max, nan, kind);
380}
381
382void
383frange::set (tree min, tree max, value_range_kind kind)
384{
385 set (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 385, __FUNCTION__))->typed.type)
,
386 *TREE_REAL_CST_PTR (min)(&(tree_check ((min), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 386, __FUNCTION__, (REAL_CST)))->real_cst.value)
, *TREE_REAL_CST_PTR (max)(&(tree_check ((max), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 386, __FUNCTION__, (REAL_CST)))->real_cst.value)
, kind);
387}
388
389// Normalize range to VARYING or UNDEFINED, or vice versa. Return
390// TRUE if anything changed.
391//
392// A range with no known properties can be dropped to VARYING.
393// Similarly, a VARYING with any properties should be dropped to a
394// VR_RANGE. Normalizing ranges upon changing them ensures there is
395// only one representation for a given range.
396
397bool
398frange::normalize_kind ()
399{
400 if (m_kind == VR_RANGE
401 && frange_val_is_min (m_min, m_type)
402 && frange_val_is_max (m_max, m_type))
403 {
404 if (!HONOR_NANS (m_type) || (m_pos_nan && m_neg_nan))
405 {
406 set_varying (m_type);
407 return true;
408 }
409 }
410 else if (m_kind == VR_VARYING)
411 {
412 if (HONOR_NANS (m_type) && (!m_pos_nan || !m_neg_nan))
413 {
414 m_kind = VR_RANGE;
415 m_min = frange_val_min (m_type);
416 m_max = frange_val_max (m_type);
417 return true;
418 }
419 }
420 else if (m_kind == VR_NAN && !m_pos_nan && !m_neg_nan)
421 set_undefined ();
422 return false;
423}
424
425// Union or intersect the zero endpoints of two ranges. For example:
426// [-0, x] U [+0, x] => [-0, x]
427// [ x, -0] U [ x, +0] => [ x, +0]
428// [-0, x] ^ [+0, x] => [+0, x]
429// [ x, -0] ^ [ x, +0] => [ x, -0]
430//
431// UNION_P is true when performing a union, or false when intersecting.
432
433bool
434frange::combine_zeros (const frange &r, bool union_p)
435{
436 gcc_checking_assert (!undefined_p () && !known_isnan ())((void)(!(!undefined_p () && !known_isnan ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 436, __FUNCTION__), 0 : 0))
;
437
438 bool changed = false;
439 if (real_iszero (&m_min) && real_iszero (&r.m_min)
440 && real_isneg (&m_min) != real_isneg (&r.m_min))
441 {
442 m_min.sign = union_p;
443 changed = true;
444 }
445 if (real_iszero (&m_max) && real_iszero (&r.m_max)
446 && real_isneg (&m_max) != real_isneg (&r.m_max))
447 {
448 m_max.sign = !union_p;
449 changed = true;
450 }
451 // If the signs are swapped, the resulting range is empty.
452 if (m_min.sign == 0 && m_max.sign == 1)
453 {
454 if (maybe_isnan ())
455 m_kind = VR_NAN;
456 else
457 set_undefined ();
458 changed = true;
459 }
460 return changed;
461}
462
463// Union two ranges when one is known to be a NAN.
464
465bool
466frange::union_nans (const frange &r)
467{
468 gcc_checking_assert (known_isnan () || r.known_isnan ())((void)(!(known_isnan () || r.known_isnan ()) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 468, __FUNCTION__), 0 : 0))
;
469
470 if (known_isnan ())
471 {
472 m_kind = r.m_kind;
473 m_min = r.m_min;
474 m_max = r.m_max;
475 }
476 m_pos_nan |= r.m_pos_nan;
477 m_neg_nan |= r.m_neg_nan;
478 normalize_kind ();
479 if (flag_checkingglobal_options.x_flag_checking)
480 verify_range ();
481 return true;
482}
483
484bool
485frange::union_ (const vrange &v)
486{
487 const frange &r = as_a <frange> (v);
488
489 if (r.undefined_p () || varying_p ())
490 return false;
491 if (undefined_p () || r.varying_p ())
492 {
493 *this = r;
494 return true;
495 }
496
497 // Combine NAN info.
498 if (known_isnan () || r.known_isnan ())
499 return union_nans (r);
500 bool changed = false;
501 if (m_pos_nan != r.m_pos_nan || m_neg_nan != r.m_neg_nan)
502 {
503 m_pos_nan |= r.m_pos_nan;
504 m_neg_nan |= r.m_neg_nan;
505 changed = true;
506 }
507
508 // Combine endpoints.
509 if (real_less (&r.m_min, &m_min))
510 {
511 m_min = r.m_min;
512 changed = true;
513 }
514 if (real_less (&m_max, &r.m_max))
515 {
516 m_max = r.m_max;
517 changed = true;
518 }
519
520 if (HONOR_SIGNED_ZEROS (m_type))
521 changed |= combine_zeros (r, true);
522
523 changed |= normalize_kind ();
524 if (flag_checkingglobal_options.x_flag_checking)
525 verify_range ();
526 return changed;
527}
528
529// Intersect two ranges when one is known to be a NAN.
530
531bool
532frange::intersect_nans (const frange &r)
533{
534 gcc_checking_assert (known_isnan () || r.known_isnan ())((void)(!(known_isnan () || r.known_isnan ()) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 534, __FUNCTION__), 0 : 0))
;
535
536 m_pos_nan &= r.m_pos_nan;
537 m_neg_nan &= r.m_neg_nan;
538 if (maybe_isnan ())
539 m_kind = VR_NAN;
540 else
541 set_undefined ();
542 if (flag_checkingglobal_options.x_flag_checking)
543 verify_range ();
544 return true;
545}
546
547bool
548frange::intersect (const vrange &v)
549{
550 const frange &r = as_a <frange> (v);
551
552 if (undefined_p () || r.varying_p ())
553 return false;
554 if (r.undefined_p ())
555 {
556 set_undefined ();
557 return true;
558 }
559 if (varying_p ())
560 {
561 *this = r;
562 return true;
563 }
564
565 // Combine NAN info.
566 if (known_isnan () || r.known_isnan ())
567 return intersect_nans (r);
568 bool changed = false;
569 if (m_pos_nan != r.m_pos_nan || m_neg_nan != r.m_neg_nan)
570 {
571 m_pos_nan &= r.m_pos_nan;
572 m_neg_nan &= r.m_neg_nan;
573 changed = true;
574 }
575
576 // Combine endpoints.
577 if (real_less (&m_min, &r.m_min))
578 {
579 m_min = r.m_min;
580 changed = true;
581 }
582 if (real_less (&r.m_max, &m_max))
583 {
584 m_max = r.m_max;
585 changed = true;
586 }
587 // If the endpoints are swapped, the resulting range is empty.
588 if (real_less (&m_max, &m_min))
589 {
590 if (maybe_isnan ())
591 m_kind = VR_NAN;
592 else
593 set_undefined ();
594 if (flag_checkingglobal_options.x_flag_checking)
595 verify_range ();
596 return true;
597 }
598
599 if (HONOR_SIGNED_ZEROS (m_type))
600 changed |= combine_zeros (r, false);
601
602 changed |= normalize_kind ();
603 if (flag_checkingglobal_options.x_flag_checking)
604 verify_range ();
605 return changed;
606}
607
608frange &
609frange::operator= (const frange &src)
610{
611 m_kind = src.m_kind;
612 m_type = src.m_type;
613 m_min = src.m_min;
614 m_max = src.m_max;
615 m_pos_nan = src.m_pos_nan;
616 m_neg_nan = src.m_neg_nan;
617
618 if (flag_checkingglobal_options.x_flag_checking)
619 verify_range ();
620 return *this;
621}
622
623bool
624frange::operator== (const frange &src) const
625{
626 if (m_kind == src.m_kind)
627 {
628 if (undefined_p ())
629 return true;
630
631 if (varying_p ())
632 return types_compatible_p (m_type, src.m_type);
633
634 if (known_isnan () || src.known_isnan ())
635 return false;
636
637 return (real_identical (&m_min, &src.m_min)
638 && real_identical (&m_max, &src.m_max)
639 && m_pos_nan == src.m_pos_nan
640 && m_neg_nan == src.m_neg_nan
641 && types_compatible_p (m_type, src.m_type));
642 }
643 return false;
644}
645
646// Return TRUE if range contains the TREE_REAL_CST_PTR in CST.
647
648bool
649frange::contains_p (tree cst) const
650{
651 gcc_checking_assert (m_kind != VR_ANTI_RANGE)((void)(!(m_kind != VR_ANTI_RANGE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 651, __FUNCTION__), 0 : 0))
;
652 const REAL_VALUE_TYPEstruct real_value *rv = TREE_REAL_CST_PTR (cst)(&(tree_check ((cst), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 652, __FUNCTION__, (REAL_CST)))->real_cst.value)
;
653
654 if (undefined_p ())
655 return false;
656
657 if (varying_p ())
658 return true;
659
660 if (real_isnan (rv))
661 {
662 // No NAN in range.
663 if (!m_pos_nan && !m_neg_nan)
664 return false;
665 // Both +NAN and -NAN are present.
666 if (m_pos_nan && m_neg_nan)
667 return true;
668 return m_neg_nan == rv->sign;
669 }
670 if (known_isnan ())
671 return false;
672
673 if (real_compare (GE_EXPR, rv, &m_min) && real_compare (LE_EXPR, rv, &m_max))
674 {
675 // Make sure the signs are equal for signed zeros.
676 if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
677 return rv->sign == m_min.sign || rv->sign == m_max.sign;
678 return true;
679 }
680 return false;
681}
682
683// If range is a singleton, place it in RESULT and return TRUE. If
684// RESULT is NULL, just return TRUE.
685//
686// A NAN can never be a singleton.
687
688bool
689frange::singleton_p (tree *result) const
690{
691 if (m_kind == VR_RANGE && real_identical (&m_min, &m_max))
692 {
693 // Return false for any singleton that may be a NAN.
694 if (HONOR_NANS (m_type) && maybe_isnan ())
695 return false;
696
697 if (MODE_COMPOSITE_P (TYPE_MODE (m_type))((((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_FLOAT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_DECIMAL_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_COMPLEX_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode)]) == MODE_VECTOR_FLOAT
) && ((real_format_for_mode[(((enum mode_class) mode_class
[as_a <scalar_float_mode> ((mode_to_inner (((((enum tree_code
) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_DECIMAL_FLOAT
) ? (((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_DECIMAL_FLOAT
) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class
) mode_class[as_a <scalar_float_mode> ((mode_to_inner (
((((enum tree_code) ((tree_class_check ((m_type), (tcc_type),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_FLOAT
? ((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_FLOAT
) : ((fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)), 0)]))->pnan < ((real_format_for_mode
[(((enum mode_class) mode_class[as_a <scalar_float_mode>
((mode_to_inner (((((enum tree_code) ((tree_class_check ((m_type
), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_DECIMAL_FLOAT
) ? (((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_DECIMAL_FLOAT
) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class
) mode_class[as_a <scalar_float_mode> ((mode_to_inner (
((((enum tree_code) ((tree_class_check ((m_type), (tcc_type),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))]) == MODE_FLOAT
? ((as_a <scalar_float_mode> ((mode_to_inner (((((enum
tree_code) ((tree_class_check ((m_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(m_type) : (m_type)->type_common.mode))))) - MIN_MODE_FLOAT
) : ((fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 697, __FUNCTION__)), 0)]))->p)
)
698 {
699 // For IBM long doubles, if the value is +-Inf or is exactly
700 // representable in double, the other double could be +0.0
701 // or -0.0. Since this means there is more than one way to
702 // represent a value, return false to avoid propagating it.
703 // See libgcc/config/rs6000/ibm-ldouble-format for details.
704 if (real_isinf (&m_min))
705 return false;
706 REAL_VALUE_TYPEstruct real_value r;
707 real_convert (&r, DFmode(scalar_float_mode ((scalar_float_mode::from_int) E_DFmode)), &m_min);
708 if (real_identical (&r, &m_min))
709 return false;
710 }
711
712 if (result)
713 *result = build_real (m_type, m_min);
714 return true;
715 }
716 return false;
717}
718
719bool
720frange::supports_type_p (const_tree type) const
721{
722 return supports_p (type);
723}
724
725void
726frange::verify_range ()
727{
728 if (!undefined_p ())
729 gcc_checking_assert (HONOR_NANS (m_type) || !maybe_isnan ())((void)(!(HONOR_NANS (m_type) || !maybe_isnan ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 729, __FUNCTION__), 0 : 0))
;
730 switch (m_kind)
731 {
732 case VR_UNDEFINED:
733 gcc_checking_assert (!m_type)((void)(!(!m_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 733, __FUNCTION__), 0 : 0))
;
734 return;
735 case VR_VARYING:
736 gcc_checking_assert (m_type)((void)(!(m_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 736, __FUNCTION__), 0 : 0))
;
737 gcc_checking_assert (frange_val_is_min (m_min, m_type))((void)(!(frange_val_is_min (m_min, m_type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 737, __FUNCTION__), 0 : 0))
;
738 gcc_checking_assert (frange_val_is_max (m_max, m_type))((void)(!(frange_val_is_max (m_max, m_type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 738, __FUNCTION__), 0 : 0))
;
739 if (HONOR_NANS (m_type))
740 gcc_checking_assert (m_pos_nan && m_neg_nan)((void)(!(m_pos_nan && m_neg_nan) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 740, __FUNCTION__), 0 : 0))
;
741 else
742 gcc_checking_assert (!m_pos_nan && !m_neg_nan)((void)(!(!m_pos_nan && !m_neg_nan) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 742, __FUNCTION__), 0 : 0))
;
743 return;
744 case VR_RANGE:
745 gcc_checking_assert (m_type)((void)(!(m_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 745, __FUNCTION__), 0 : 0))
;
746 break;
747 case VR_NAN:
748 gcc_checking_assert (m_type)((void)(!(m_type) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 748, __FUNCTION__), 0 : 0))
;
749 gcc_checking_assert (m_pos_nan || m_neg_nan)((void)(!(m_pos_nan || m_neg_nan) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 749, __FUNCTION__), 0 : 0))
;
750 return;
751 default:
752 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 752, __FUNCTION__))
;
753 }
754
755 // NANs cannot appear in the endpoints of a range.
756 gcc_checking_assert (!real_isnan (&m_min) && !real_isnan (&m_max))((void)(!(!real_isnan (&m_min) && !real_isnan (&
m_max)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 756, __FUNCTION__), 0 : 0))
;
757
758 // Make sure we don't have swapped ranges.
759 gcc_checking_assert (!real_less (&m_max, &m_min))((void)(!(!real_less (&m_max, &m_min)) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 759, __FUNCTION__), 0 : 0))
;
760
761 // [ +0.0, -0.0 ] is nonsensical.
762 gcc_checking_assert (!(real_iszero (&m_min, 0) && real_iszero (&m_max, 1)))((void)(!(!(real_iszero (&m_min, 0) && real_iszero
(&m_max, 1))) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 762, __FUNCTION__), 0 : 0))
;
763
764 // If all the properties are clear, we better not span the entire
765 // domain, because that would make us varying.
766 if (m_pos_nan && m_neg_nan)
767 gcc_checking_assert (!frange_val_is_min (m_min, m_type)((void)(!(!frange_val_is_min (m_min, m_type) || !frange_val_is_max
(m_max, m_type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 768, __FUNCTION__), 0 : 0))
768 || !frange_val_is_max (m_max, m_type))((void)(!(!frange_val_is_min (m_min, m_type) || !frange_val_is_max
(m_max, m_type)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 768, __FUNCTION__), 0 : 0))
;
769}
770
771// We can't do much with nonzeros yet.
772void
773frange::set_nonzero (tree type)
774{
775 set_varying (type);
776}
777
778// We can't do much with nonzeros yet.
779bool
780frange::nonzero_p () const
781{
782 return false;
783}
784
785// Set range to [+0.0, +0.0] if honoring signed zeros, or [0.0, 0.0]
786// otherwise.
787
788void
789frange::set_zero (tree type)
790{
791 if (HONOR_SIGNED_ZEROS (type))
792 {
793 REAL_VALUE_TYPEstruct real_value dconstm0 = dconst0;
794 dconstm0.sign = 1;
795 set (type, dconstm0, dconst0);
796 clear_nan ();
797 }
798 else
799 set (type, dconst0, dconst0);
800}
801
802// Return TRUE for any zero regardless of sign.
803
804bool
805frange::zero_p () const
806{
807 return (m_kind == VR_RANGE
808 && real_iszero (&m_min)
809 && real_iszero (&m_max));
810}
811
812// Set the range to non-negative numbers, that is [+0.0, +INF].
813//
814// The NAN in the resulting range (if HONOR_NANS) has a varying sign
815// as there are no guarantees in IEEE 754 wrt to the sign of a NAN,
816// except for copy, abs, and copysign. It is the responsibility of
817// the caller to set the NAN's sign if desired.
818
819void
820frange::set_nonnegative (tree type)
821{
822 set (type, dconst0, frange_val_max (type));
823}
824
825// Here we copy between any two irange's. The ranges can be legacy or
826// multi-ranges, and copying between any combination works correctly.
827
828irange &
829irange::operator= (const irange &src)
830{
831 if (legacy_mode_p ())
832 {
833 copy_to_legacy (src);
834 return *this;
835 }
836 if (src.legacy_mode_p ())
837 {
838 copy_legacy_to_multi_range (src);
839 return *this;
840 }
841
842 unsigned x;
843 unsigned lim = src.m_num_ranges;
844 if (lim > m_max_ranges)
845 lim = m_max_ranges;
846
847 for (x = 0; x < lim * 2; ++x)
848 m_base[x] = src.m_base[x];
849
850 // If the range didn't fit, the last range should cover the rest.
851 if (lim != src.m_num_ranges)
852 m_base[x - 1] = src.m_base[src.m_num_ranges * 2 - 1];
853
854 m_num_ranges = lim;
855 m_kind = src.m_kind;
856 m_nonzero_mask = src.m_nonzero_mask;
857 if (flag_checkingglobal_options.x_flag_checking)
858 verify_range ();
859 return *this;
860}
861
862// Return TRUE if range is a multi-range that can be represented as a
863// VR_ANTI_RANGE.
864
865bool
866irange::maybe_anti_range () const
867{
868 tree ttype = type ();
869 unsigned int precision = TYPE_PRECISION (ttype)((tree_class_check ((ttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 869, __FUNCTION__))->type_common.precision)
;
870 signop sign = TYPE_SIGN (ttype)((signop) ((tree_class_check ((ttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 870, __FUNCTION__))->base.u.bits.unsigned_flag))
;
871 return (num_pairs () > 1
872 && precision > 1
873 && lower_bound () == wi::min_value (precision, sign)
874 && upper_bound () == wi::max_value (precision, sign));
875}
876
877void
878irange::copy_legacy_to_multi_range (const irange &src)
879{
880 gcc_checking_assert (src.legacy_mode_p ())((void)(!(src.legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 880, __FUNCTION__), 0 : 0))
;
881 gcc_checking_assert (!legacy_mode_p ())((void)(!(!legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 881, __FUNCTION__), 0 : 0))
;
882 if (src.undefined_p ())
883 set_undefined ();
884 else if (src.varying_p ())
885 set_varying (src.type ());
886 else
887 {
888 if (range_has_numeric_bounds_p (&src))
889 set (src.min (), src.max (), src.kind ());
890 else
891 {
892 value_range cst (src);
893 cst.normalize_symbolics ();
894 gcc_checking_assert (cst.varying_p () || cst.kind () == VR_RANGE)((void)(!(cst.varying_p () || cst.kind () == VR_RANGE) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 894, __FUNCTION__), 0 : 0))
;
895 set (cst.min (), cst.max ());
896 }
897 }
898}
899
900// Copy any type of irange into a legacy.
901
902void
903irange::copy_to_legacy (const irange &src)
904{
905 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 905, __FUNCTION__), 0 : 0))
;
906 // Handle legacy to legacy and other things that are easy to copy.
907 if (src.legacy_mode_p () || src.varying_p () || src.undefined_p ())
908 {
909 m_num_ranges = src.m_num_ranges;
910 m_base[0] = src.m_base[0];
911 m_base[1] = src.m_base[1];
912 m_kind = src.m_kind;
913 m_nonzero_mask = src.m_nonzero_mask;
914 return;
915 }
916 // Copy multi-range to legacy.
917 if (src.maybe_anti_range ())
918 {
919 int_range<3> r (src);
920 r.invert ();
921 // Use tree variants to save on tree -> wi -> tree conversions.
922 set (r.tree_lower_bound (0), r.tree_upper_bound (0), VR_ANTI_RANGE);
923 }
924 else
925 set (src.tree_lower_bound (), src.tree_upper_bound ());
926}
927
928// Swap MIN/MAX if they are out of order and adjust KIND appropriately.
929
930static void
931swap_out_of_order_endpoints (tree &min, tree &max, value_range_kind &kind)
932{
933 gcc_checking_assert (kind != VR_UNDEFINED)((void)(!(kind != VR_UNDEFINED) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 933, __FUNCTION__), 0 : 0))
;
934 if (kind == VR_VARYING)
935 return;
936 /* Wrong order for min and max, to swap them and the VR type we need
937 to adjust them. */
938 if (tree_int_cst_lt (max, min))
939 {
940 tree one, tmp;
941
942 /* For one bit precision if max < min, then the swapped
943 range covers all values, so for VR_RANGE it is varying and
944 for VR_ANTI_RANGE empty range, so drop to varying as well. */
945 if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 945, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 945, __FUNCTION__))->type_common.precision)
== 1)
946 {
947 kind = VR_VARYING;
948 return;
949 }
950
951 one = build_int_cst (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 951, __FUNCTION__))->typed.type)
, 1);
952 tmp = int_const_binop (PLUS_EXPR, max, one);
953 max = int_const_binop (MINUS_EXPR, min, one);
954 min = tmp;
955
956 /* There's one corner case, if we had [C+1, C] before we now have
957 that again. But this represents an empty value range, so drop
958 to varying in this case. */
959 if (tree_int_cst_lt (max, min))
960 {
961 kind = VR_VARYING;
962 return;
963 }
964 kind = kind == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
965 }
966}
967
968void
969irange::irange_set (tree min, tree max)
970{
971 gcc_checking_assert (!POLY_INT_CST_P (min))((void)(!(!(1 > 1 && ((enum tree_code) (min)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 971, __FUNCTION__), 0 : 0))
;
972 gcc_checking_assert (!POLY_INT_CST_P (max))((void)(!(!(1 > 1 && ((enum tree_code) (max)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 972, __FUNCTION__), 0 : 0))
;
973
974 m_base[0] = min;
975 m_base[1] = max;
976 m_num_ranges = 1;
977 m_kind = VR_RANGE;
978 m_nonzero_mask = NULLnullptr;
979 normalize_kind ();
980
981 if (flag_checkingglobal_options.x_flag_checking)
982 verify_range ();
983}
984
985void
986irange::irange_set_1bit_anti_range (tree min, tree max)
987{
988 tree type = TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 988, __FUNCTION__))->typed.type)
;
989 gcc_checking_assert (TYPE_PRECISION (type) == 1)((void)(!(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 989, __FUNCTION__))->type_common.precision) == 1) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 989, __FUNCTION__), 0 : 0))
;
990
991 if (operand_equal_p (min, max))
992 {
993 // Since these are 1-bit quantities, they can only be [MIN,MIN]
994 // or [MAX,MAX].
995 if (vrp_val_is_min (min))
996 min = max = vrp_val_max (type);
997 else
998 min = max = vrp_val_min (type);
999 set (min, max);
1000 }
1001 else
1002 {
1003 // The only alternative is [MIN,MAX], which is the empty range.
1004 gcc_checking_assert (vrp_val_is_min (min))((void)(!(vrp_val_is_min (min)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1004, __FUNCTION__), 0 : 0))
;
1005 gcc_checking_assert (vrp_val_is_max (max))((void)(!(vrp_val_is_max (max)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1005, __FUNCTION__), 0 : 0))
;
1006 set_undefined ();
1007 }
1008 if (flag_checkingglobal_options.x_flag_checking)
1009 verify_range ();
1010}
1011
1012void
1013irange::irange_set_anti_range (tree min, tree max)
1014{
1015 gcc_checking_assert (!POLY_INT_CST_P (min))((void)(!(!(1 > 1 && ((enum tree_code) (min)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1015, __FUNCTION__), 0 : 0))
;
1016 gcc_checking_assert (!POLY_INT_CST_P (max))((void)(!(!(1 > 1 && ((enum tree_code) (max)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1016, __FUNCTION__), 0 : 0))
;
1017
1018 if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1018, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1018, __FUNCTION__))->type_common.precision)
== 1)
1019 {
1020 irange_set_1bit_anti_range (min, max);
1021 return;
1022 }
1023
1024 // set an anti-range
1025 tree type = TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1025, __FUNCTION__))->typed.type)
;
1026 signop sign = TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1026, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1027 int_range<2> type_range (type);
1028 // Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
1029 m_num_ranges = 0;
1030 wi::overflow_type ovf;
1031
1032 wide_int w_min = wi::to_wide (min);
1033 if (wi::ne_p (w_min, type_range.lower_bound ()))
1034 {
1035 wide_int lim1 = wi::sub (w_min, 1, sign, &ovf);
1036 gcc_checking_assert (ovf != wi::OVF_OVERFLOW)((void)(!(ovf != wi::OVF_OVERFLOW) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1036, __FUNCTION__), 0 : 0))
;
1037 m_base[0] = type_range.tree_lower_bound (0);
1038 m_base[1] = wide_int_to_tree (type, lim1);
1039 m_num_ranges = 1;
1040 }
1041 wide_int w_max = wi::to_wide (max);
1042 if (wi::ne_p (w_max, type_range.upper_bound ()))
1043 {
1044 wide_int lim2 = wi::add (w_max, 1, sign, &ovf);
1045 gcc_checking_assert (ovf != wi::OVF_OVERFLOW)((void)(!(ovf != wi::OVF_OVERFLOW) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1045, __FUNCTION__), 0 : 0))
;
1046 m_base[m_num_ranges * 2] = wide_int_to_tree (type, lim2);
1047 m_base[m_num_ranges * 2 + 1] = type_range.tree_upper_bound (0);
1048 ++m_num_ranges;
1049 }
1050
1051 m_kind = VR_RANGE;
1052 m_nonzero_mask = NULLnullptr;
1053 normalize_kind ();
1054
1055 if (flag_checkingglobal_options.x_flag_checking)
1056 verify_range ();
1057}
1058
1059/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
1060 This means adjusting VRTYPE, MIN and MAX representing the case of a
1061 wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
1062 as anti-rage ~[MAX+1, MIN-1]. Likewise for wrapping anti-ranges.
1063 In corner cases where MAX+1 or MIN-1 wraps this will fall back
1064 to varying.
1065 This routine exists to ease canonicalization in the case where we
1066 extract ranges from var + CST op limit. */
1067
1068void
1069irange::set (tree min, tree max, value_range_kind kind)
1070{
1071 if (kind == VR_UNDEFINED)
1072 {
1073 irange::set_undefined ();
1074 return;
1075 }
1076
1077 if (kind == VR_VARYING
1078 || POLY_INT_CST_P (min)(1 > 1 && ((enum tree_code) (min)->base.code) ==
POLY_INT_CST)
1079 || POLY_INT_CST_P (max)(1 > 1 && ((enum tree_code) (max)->base.code) ==
POLY_INT_CST)
)
1080 {
1081 set_varying (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1081, __FUNCTION__))->typed.type)
);
1082 return;
1083 }
1084
1085 if (TREE_OVERFLOW_P (min)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum
tree_code) (min)->base.code))] == tcc_constant) &&
((tree_class_check ((min), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1085, __FUNCTION__))->base.public_flag))
)
1086 min = drop_tree_overflow (min);
1087 if (TREE_OVERFLOW_P (max)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum
tree_code) (max)->base.code))] == tcc_constant) &&
((tree_class_check ((max), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1087, __FUNCTION__))->base.public_flag))
)
1088 max = drop_tree_overflow (max);
1089
1090 if (!legacy_mode_p ())
1091 {
1092 if (kind == VR_RANGE)
1093 irange_set (min, max);
1094 else
1095 {
1096 gcc_checking_assert (kind == VR_ANTI_RANGE)((void)(!(kind == VR_ANTI_RANGE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1096, __FUNCTION__), 0 : 0))
;
1097 irange_set_anti_range (min, max);
1098 }
1099 return;
1100 }
1101 // Nothing to canonicalize for symbolic ranges.
1102 if (TREE_CODE (min)((enum tree_code) (min)->base.code) != INTEGER_CST
1103 || TREE_CODE (max)((enum tree_code) (max)->base.code) != INTEGER_CST)
1104 {
1105 m_kind = kind;
1106 m_base[0] = min;
1107 m_base[1] = max;
1108 m_num_ranges = 1;
1109 m_nonzero_mask = NULLnullptr;
1110 return;
1111 }
1112
1113 swap_out_of_order_endpoints (min, max, kind);
1114 if (kind == VR_VARYING)
1115 {
1116 set_varying (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1116, __FUNCTION__))->typed.type)
);
1117 return;
1118 }
1119
1120 // Anti-ranges that can be represented as ranges should be so.
1121 if (kind == VR_ANTI_RANGE)
1122 {
1123 bool is_min = vrp_val_is_min (min);
1124 bool is_max = vrp_val_is_max (max);
1125
1126 if (is_min && is_max)
1127 {
1128 // Fall through. This will either be normalized as
1129 // VR_UNDEFINED if the anti-range spans the entire
1130 // precision, or it will remain an VR_ANTI_RANGE in the case
1131 // of an -fstrict-enum where [MIN,MAX] is less than the span
1132 // of underlying precision.
1133 }
1134 else if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1134, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1134, __FUNCTION__))->type_common.precision)
== 1)
1135 {
1136 irange_set_1bit_anti_range (min, max);
1137 return;
1138 }
1139 else if (is_min)
1140 {
1141 tree one = build_int_cst (TREE_TYPE (max)((contains_struct_check ((max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1141, __FUNCTION__))->typed.type)
, 1);
1142 min = int_const_binop (PLUS_EXPR, max, one);
1143 max = vrp_val_max (TREE_TYPE (max)((contains_struct_check ((max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1143, __FUNCTION__))->typed.type)
);
1144 kind = VR_RANGE;
1145 }
1146 else if (is_max)
1147 {
1148 tree one = build_int_cst (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1148, __FUNCTION__))->typed.type)
, 1);
1149 max = int_const_binop (MINUS_EXPR, min, one);
1150 min = vrp_val_min (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1150, __FUNCTION__))->typed.type)
);
1151 kind = VR_RANGE;
1152 }
1153 }
1154
1155 m_kind = kind;
1156 m_base[0] = min;
1157 m_base[1] = max;
1158 m_num_ranges = 1;
1159 m_nonzero_mask = NULLnullptr;
1160 normalize_kind ();
1161 if (flag_checkingglobal_options.x_flag_checking)
1162 verify_range ();
1163}
1164
1165// Check the validity of the range.
1166
1167void
1168irange::verify_range ()
1169{
1170 gcc_checking_assert (m_discriminator == VR_IRANGE)((void)(!(m_discriminator == VR_IRANGE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1170, __FUNCTION__), 0 : 0))
;
1171 if (m_kind == VR_UNDEFINED)
1172 {
1173 gcc_checking_assert (m_num_ranges == 0)((void)(!(m_num_ranges == 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1173, __FUNCTION__), 0 : 0))
;
1174 return;
1175 }
1176 if (m_kind == VR_VARYING)
1177 {
1178 gcc_checking_assert (!m_nonzero_mask((void)(!(!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -
1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1179, __FUNCTION__), 0 : 0))
1179 || wi::to_wide (m_nonzero_mask) == -1)((void)(!(!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -
1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1179, __FUNCTION__), 0 : 0))
;
1180 gcc_checking_assert (m_num_ranges == 1)((void)(!(m_num_ranges == 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1180, __FUNCTION__), 0 : 0))
;
1181 gcc_checking_assert (varying_compatible_p ())((void)(!(varying_compatible_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1181, __FUNCTION__), 0 : 0))
;
1182 return;
1183 }
1184 if (!legacy_mode_p ())
1185 {
1186 gcc_checking_assert (m_num_ranges != 0)((void)(!(m_num_ranges != 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1186, __FUNCTION__), 0 : 0))
;
1187 gcc_checking_assert (!varying_compatible_p ())((void)(!(!varying_compatible_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1187, __FUNCTION__), 0 : 0))
;
1188 for (unsigned i = 0; i < m_num_ranges; ++i)
1189 {
1190 tree lb = tree_lower_bound (i);
1191 tree ub = tree_upper_bound (i);
1192 int c = compare_values (lb, ub);
1193 gcc_checking_assert (c == 0 || c == -1)((void)(!(c == 0 || c == -1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1193, __FUNCTION__), 0 : 0))
;
1194 }
1195 return;
1196 }
1197 if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
1198 {
1199 gcc_checking_assert (m_num_ranges == 1)((void)(!(m_num_ranges == 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1199, __FUNCTION__), 0 : 0))
;
1200 int cmp = compare_values (tree_lower_bound (0), tree_upper_bound (0));
1201 gcc_checking_assert (cmp == 0 || cmp == -1 || cmp == -2)((void)(!(cmp == 0 || cmp == -1 || cmp == -2) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1201, __FUNCTION__), 0 : 0))
;
1202 }
1203}
1204
1205// Return the lower bound for a sub-range. PAIR is the sub-range in
1206// question.
1207
1208wide_int
1209irange::legacy_lower_bound (unsigned pair) const
1210{
1211 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1211, __FUNCTION__), 0 : 0))
;
1212 if (symbolic_p ())
1213 {
1214 value_range numeric_range (*this);
1215 numeric_range.normalize_symbolics ();
1216 return numeric_range.legacy_lower_bound (pair);
1217 }
1218 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1218, __FUNCTION__), 0 : 0))
;
1219 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1219, __FUNCTION__), 0 : 0))
;
1220 if (m_kind == VR_ANTI_RANGE)
1221 {
1222 tree typ = type (), t;
1223 if (pair == 1 || vrp_val_is_min (min ()))
1224 t = wide_int_to_tree (typ, wi::to_wide (max ()) + 1);
1225 else
1226 t = vrp_val_min (typ);
1227 return wi::to_wide (t);
1228 }
1229 return wi::to_wide (tree_lower_bound (pair));
1230}
1231
1232// Return the upper bound for a sub-range. PAIR is the sub-range in
1233// question.
1234
1235wide_int
1236irange::legacy_upper_bound (unsigned pair) const
1237{
1238 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1238, __FUNCTION__), 0 : 0))
;
1239 if (symbolic_p ())
1240 {
1241 value_range numeric_range (*this);
1242 numeric_range.normalize_symbolics ();
1243 return numeric_range.legacy_upper_bound (pair);
1244 }
1245 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1245, __FUNCTION__), 0 : 0))
;
1246 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1246, __FUNCTION__), 0 : 0))
;
1247 if (m_kind == VR_ANTI_RANGE)
1248 {
1249 tree typ = type (), t;
1250 if (pair == 1 || vrp_val_is_min (min ()))
1251 t = vrp_val_max (typ);
1252 else
1253 t = wide_int_to_tree (typ, wi::to_wide (min ()) - 1);
1254 return wi::to_wide (t);
1255 }
1256 return wi::to_wide (tree_upper_bound (pair));
1257}
1258
1259bool
1260irange::legacy_equal_p (const irange &other) const
1261{
1262 gcc_checking_assert (legacy_mode_p () && other.legacy_mode_p ())((void)(!(legacy_mode_p () && other.legacy_mode_p ())
? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1262, __FUNCTION__), 0 : 0))
;
1263
1264 if (m_kind != other.m_kind)
1265 return false;
1266 if (m_kind == VR_UNDEFINED)
1267 return true;
1268 if (m_kind == VR_VARYING)
1269 return range_compatible_p (type (), other.type ());
1270 return (vrp_operand_equal_p (tree_lower_bound (0),
1271 other.tree_lower_bound (0))
1272 && vrp_operand_equal_p (tree_upper_bound (0),
1273 other.tree_upper_bound (0))
1274 && (widest_int::from (get_nonzero_bits (),
1275 TYPE_SIGN (type ())((signop) ((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1275, __FUNCTION__))->base.u.bits.unsigned_flag))
)
1276 == widest_int::from (other.get_nonzero_bits (),
1277 TYPE_SIGN (other.type ())((signop) ((tree_class_check ((other.type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1277, __FUNCTION__))->base.u.bits.unsigned_flag))
)));
1278}
1279
1280bool
1281irange::operator== (const irange &other) const
1282{
1283 if (legacy_mode_p ())
1284 {
1285 if (other.legacy_mode_p ())
1286 return legacy_equal_p (other);
1287 value_range tmp (other);
1288 return legacy_equal_p (tmp);
1289 }
1290 if (other.legacy_mode_p ())
1291 {
1292 value_range tmp2 (*this);
1293 return tmp2.legacy_equal_p (other);
1294 }
1295
1296 if (m_num_ranges != other.m_num_ranges)
1297 return false;
1298
1299 if (m_num_ranges == 0)
1300 return true;
1301
1302 for (unsigned i = 0; i < m_num_ranges; ++i)
1303 {
1304 tree lb = tree_lower_bound (i);
1305 tree ub = tree_upper_bound (i);
1306 tree lb_other = other.tree_lower_bound (i);
1307 tree ub_other = other.tree_upper_bound (i);
1308 if (!operand_equal_p (lb, lb_other, 0)
1309 || !operand_equal_p (ub, ub_other, 0))
1310 return false;
1311 }
1312 widest_int nz1 = widest_int::from (get_nonzero_bits (),
1313 TYPE_SIGN (type ())((signop) ((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1313, __FUNCTION__))->base.u.bits.unsigned_flag))
);
1314 widest_int nz2 = widest_int::from (other.get_nonzero_bits (),
1315 TYPE_SIGN (other.type ())((signop) ((tree_class_check ((other.type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1315, __FUNCTION__))->base.u.bits.unsigned_flag))
);
1316 return nz1 == nz2;
1317}
1318
1319/* Return TRUE if this is a symbolic range. */
1320
1321bool
1322irange::symbolic_p () const
1323{
1324 return (m_num_ranges > 0
1325 && (!is_gimple_min_invariant (min ())
1326 || !is_gimple_min_invariant (max ())));
1327}
1328
1329/* Return TRUE if this is a constant range. */
1330
1331bool
1332irange::constant_p () const
1333{
1334 return (m_num_ranges > 0
1335 && TREE_CODE (min ())((enum tree_code) (min ())->base.code) == INTEGER_CST
1336 && TREE_CODE (max ())((enum tree_code) (max ())->base.code) == INTEGER_CST);
1337}
1338
1339/* If range is a singleton, place it in RESULT and return TRUE.
1340 Note: A singleton can be any gimple invariant, not just constants.
1341 So, [&x, &x] counts as a singleton. */
1342
1343bool
1344irange::singleton_p (tree *result) const
1345{
1346 if (!legacy_mode_p ())
1347 {
1348 if (num_pairs () == 1 && (wi::to_wide (tree_lower_bound ())
1349 == wi::to_wide (tree_upper_bound ())))
1350 {
1351 if (result)
1352 *result = tree_lower_bound ();
1353 return true;
1354 }
1355 return false;
1356 }
1357 if (m_kind == VR_ANTI_RANGE)
1358 {
1359 if (nonzero_p ())
1360 {
1361 if (TYPE_PRECISION (type ())((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1361, __FUNCTION__))->type_common.precision)
== 1)
1362 {
1363 if (result)
1364 *result = max ();
1365 return true;
1366 }
1367 return false;
1368 }
1369 if (num_pairs () == 1)
1370 {
1371 value_range vr0, vr1;
1372 ranges_from_anti_range ((const value_range *) this, &vr0, &vr1);
1373 return vr0.singleton_p (result);
1374 }
1375 }
1376 // Catches non-numeric extremes as well.
1377 if (m_kind == VR_RANGE
1378 && vrp_operand_equal_p (min (), max ())
1379 && is_gimple_min_invariant (min ()))
1380 {
1381 if (result)
1382 *result = min ();
1383 return true;
1384 }
1385 return false;
1386}
1387
1388/* Return 1 if VAL is inside value range.
1389 0 if VAL is not inside value range.
1390 -2 if we cannot tell either way.
1391
1392 Benchmark compile/20001226-1.c compilation time after changing this
1393 function. */
1394
1395int
1396irange::value_inside_range (tree val) const
1397{
1398 if (varying_p ())
1399 return 1;
1400
1401 if (undefined_p ())
1402 return 0;
1403
1404 if (!legacy_mode_p () && TREE_CODE (val)((enum tree_code) (val)->base.code) == INTEGER_CST)
1405 return contains_p (val);
1406
1407 int cmp1 = operand_less_p (val, min ());
1408 if (cmp1 == -2)
1409 return -2;
1410 if (cmp1 == 1)
1411 return m_kind != VR_RANGE;
1412
1413 int cmp2 = operand_less_p (max (), val);
1414 if (cmp2 == -2)
1415 return -2;
1416
1417 if (m_kind == VR_RANGE)
1418 return !cmp2;
1419 else
1420 return !!cmp2;
1421}
1422
1423/* Return TRUE if it is possible that range contains VAL. */
1424
1425bool
1426irange::may_contain_p (tree val) const
1427{
1428 return value_inside_range (val) != 0;
1429}
1430
1431/* Return TRUE if range contains INTEGER_CST. */
1432/* Return 1 if VAL is inside value range.
1433 0 if VAL is not inside value range.
1434
1435 Benchmark compile/20001226-1.c compilation time after changing this
1436 function. */
1437
1438
1439bool
1440irange::contains_p (tree cst) const
1441{
1442 if (undefined_p ())
1443 return false;
1444
1445 if (legacy_mode_p ())
1446 {
1447 gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST)((void)(!(((enum tree_code) (cst)->base.code) == INTEGER_CST
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1447, __FUNCTION__), 0 : 0))
;
1448 if (symbolic_p ())
1449 {
1450 value_range numeric_range (*this);
1451 numeric_range.normalize_symbolics ();
1452 return numeric_range.contains_p (cst);
1453 }
1454 return value_inside_range (cst) == 1;
1455 }
1456
1457 gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST)((void)(!(((enum tree_code) (cst)->base.code) == INTEGER_CST
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1457, __FUNCTION__), 0 : 0))
;
1458
1459 // See if we can exclude CST based on the nonzero bits.
1460 if (m_nonzero_mask)
1461 {
1462 wide_int cstw = wi::to_wide (cst);
1463 if (cstw != 0 && wi::bit_and (wi::to_wide (m_nonzero_mask), cstw) == 0)
1464 return false;
1465 }
1466
1467 signop sign = TYPE_SIGN (TREE_TYPE (cst))((signop) ((tree_class_check ((((contains_struct_check ((cst)
, (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1467, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1467, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1468 wide_int v = wi::to_wide (cst);
1469 for (unsigned r = 0; r < m_num_ranges; ++r)
1470 {
1471 if (wi::lt_p (v, lower_bound (r), sign))
1472 return false;
1473 if (wi::le_p (v, upper_bound (r), sign))
1474 return true;
1475 }
1476
1477 return false;
1478}
1479
1480
1481/* Normalize addresses into constants. */
1482
1483void
1484irange::normalize_addresses ()
1485{
1486 if (undefined_p ())
1487 return;
1488
1489 if (!POINTER_TYPE_P (type ())(((enum tree_code) (type ())->base.code) == POINTER_TYPE ||
((enum tree_code) (type ())->base.code) == REFERENCE_TYPE
)
|| range_has_numeric_bounds_p (this))
1490 return;
1491
1492 if (!range_includes_zero_p (this))
1493 {
1494 gcc_checking_assert (TREE_CODE (min ()) == ADDR_EXPR((void)(!(((enum tree_code) (min ())->base.code) == ADDR_EXPR
|| ((enum tree_code) (max ())->base.code) == ADDR_EXPR) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1495, __FUNCTION__), 0 : 0))
1495 || TREE_CODE (max ()) == ADDR_EXPR)((void)(!(((enum tree_code) (min ())->base.code) == ADDR_EXPR
|| ((enum tree_code) (max ())->base.code) == ADDR_EXPR) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1495, __FUNCTION__), 0 : 0))
;
1496 set_nonzero (type ());
1497 return;
1498 }
1499 set_varying (type ());
1500}
1501
1502/* Normalize symbolics and addresses into constants. */
1503
1504void
1505irange::normalize_symbolics ()
1506{
1507 if (varying_p () || undefined_p ())
1508 return;
1509
1510 tree ttype = type ();
1511 bool min_symbolic = !is_gimple_min_invariant (min ());
1512 bool max_symbolic = !is_gimple_min_invariant (max ());
1513 if (!min_symbolic && !max_symbolic)
1514 {
1515 normalize_addresses ();
1516 return;
1517 }
1518
1519 // [SYM, SYM] -> VARYING
1520 if (min_symbolic && max_symbolic)
1521 {
1522 set_varying (ttype);
1523 return;
1524 }
1525 if (kind () == VR_RANGE)
1526 {
1527 // [SYM, NUM] -> [-MIN, NUM]
1528 if (min_symbolic)
1529 {
1530 set (vrp_val_min (ttype), max ());
1531 return;
1532 }
1533 // [NUM, SYM] -> [NUM, +MAX]
1534 set (min (), vrp_val_max (ttype));
1535 return;
1536 }
1537 gcc_checking_assert (kind () == VR_ANTI_RANGE)((void)(!(kind () == VR_ANTI_RANGE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1537, __FUNCTION__), 0 : 0))
;
1538 // ~[SYM, NUM] -> [NUM + 1, +MAX]
1539 if (min_symbolic)
1540 {
1541 if (!vrp_val_is_max (max ()))
1542 {
1543 tree n = wide_int_to_tree (ttype, wi::to_wide (max ()) + 1);
1544 set (n, vrp_val_max (ttype));
1545 return;
1546 }
1547 set_varying (ttype);
1548 return;
1549 }
1550 // ~[NUM, SYM] -> [-MIN, NUM - 1]
1551 if (!vrp_val_is_min (min ()))
1552 {
1553 tree n = wide_int_to_tree (ttype, wi::to_wide (min ()) - 1);
1554 set (vrp_val_min (ttype), n);
1555 return;
1556 }
1557 set_varying (ttype);
1558}
1559
1560/* Intersect the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
1561 { VR1TYPE, VR0MIN, VR0MAX } and store the result
1562 in { *VR0TYPE, *VR0MIN, *VR0MAX }. This may not be the smallest
1563 possible such range. The resulting range is not canonicalized. */
1564
1565static void
1566intersect_ranges (enum value_range_kind *vr0type,
1567 tree *vr0min, tree *vr0max,
1568 enum value_range_kind vr1type,
1569 tree vr1min, tree vr1max)
1570{
1571 bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
1572 bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
1573
1574 /* [] is vr0, () is vr1 in the following classification comments. */
1575 if (mineq && maxeq)
1576 {
1577 /* [( )] */
1578 if (*vr0type == vr1type)
1579 /* Nothing to do for equal ranges. */
1580 ;
1581 else if ((*vr0type == VR_RANGE
1582 && vr1type == VR_ANTI_RANGE)
1583 || (*vr0type == VR_ANTI_RANGE
1584 && vr1type == VR_RANGE))
1585 {
1586 /* For anti-range with range intersection the result is empty. */
1587 *vr0type = VR_UNDEFINED;
1588 *vr0min = NULL_TREE(tree) nullptr;
1589 *vr0max = NULL_TREE(tree) nullptr;
1590 }
1591 else
1592 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1592, __FUNCTION__))
;
1593 }
1594 else if (operand_less_p (*vr0max, vr1min) == 1
1595 || operand_less_p (vr1max, *vr0min) == 1)
1596 {
1597 /* [ ] ( ) or ( ) [ ]
1598 If the ranges have an empty intersection, the result of the
1599 intersect operation is the range for intersecting an
1600 anti-range with a range or empty when intersecting two ranges. */
1601 if (*vr0type == VR_RANGE
1602 && vr1type == VR_ANTI_RANGE)
1603 ;
1604 else if (*vr0type == VR_ANTI_RANGE
1605 && vr1type == VR_RANGE)
1606 {
1607 *vr0type = vr1type;
1608 *vr0min = vr1min;
1609 *vr0max = vr1max;
1610 }
1611 else if (*vr0type == VR_RANGE
1612 && vr1type == VR_RANGE)
1613 {
1614 *vr0type = VR_UNDEFINED;
1615 *vr0min = NULL_TREE(tree) nullptr;
1616 *vr0max = NULL_TREE(tree) nullptr;
1617 }
1618 else if (*vr0type == VR_ANTI_RANGE
1619 && vr1type == VR_ANTI_RANGE)
1620 {
1621 /* If the anti-ranges are adjacent to each other merge them. */
1622 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST
1623 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
1624 && operand_less_p (*vr0max, vr1min) == 1
1625 && integer_onep (int_const_binop (MINUS_EXPR,
1626 vr1min, *vr0max)))
1627 *vr0max = vr1max;
1628 else if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
1629 && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST
1630 && operand_less_p (vr1max, *vr0min) == 1
1631 && integer_onep (int_const_binop (MINUS_EXPR,
1632 *vr0min, vr1max)))
1633 *vr0min = vr1min;
1634 /* Else arbitrarily take VR0. */
1635 }
1636 }
1637 else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1)
1638 && (mineq || operand_less_p (*vr0min, vr1min) == 1))
1639 {
1640 /* [ ( ) ] or [( ) ] or [ ( )] */
1641 if (*vr0type == VR_RANGE
1642 && vr1type == VR_RANGE)
1643 {
1644 /* If both are ranges the result is the inner one. */
1645 *vr0type = vr1type;
1646 *vr0min = vr1min;
1647 *vr0max = vr1max;
1648 }
1649 else if (*vr0type == VR_RANGE
1650 && vr1type == VR_ANTI_RANGE)
1651 {
1652 /* Choose the right gap if the left one is empty. */
1653 if (mineq)
1654 {
1655 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) != INTEGER_CST)
1656 *vr0min = vr1max;
1657 else if (TYPE_PRECISION (TREE_TYPE (vr1max))((tree_class_check ((((contains_struct_check ((vr1max), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1657, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1657, __FUNCTION__))->type_common.precision)
== 1
1658 && !TYPE_UNSIGNED (TREE_TYPE (vr1max))((tree_class_check ((((contains_struct_check ((vr1max), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1658, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1658, __FUNCTION__))->base.u.bits.unsigned_flag)
)
1659 *vr0min
1660 = int_const_binop (MINUS_EXPR, vr1max,
1661 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1661, __FUNCTION__))->typed.type)
, -1));
1662 else
1663 *vr0min
1664 = int_const_binop (PLUS_EXPR, vr1max,
1665 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1665, __FUNCTION__))->typed.type)
, 1));
1666 }
1667 /* Choose the left gap if the right one is empty. */
1668 else if (maxeq)
1669 {
1670 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) != INTEGER_CST)
1671 *vr0max = vr1min;
1672 else if (TYPE_PRECISION (TREE_TYPE (vr1min))((tree_class_check ((((contains_struct_check ((vr1min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1672, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1672, __FUNCTION__))->type_common.precision)
== 1
1673 && !TYPE_UNSIGNED (TREE_TYPE (vr1min))((tree_class_check ((((contains_struct_check ((vr1min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1673, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1673, __FUNCTION__))->base.u.bits.unsigned_flag)
)
1674 *vr0max
1675 = int_const_binop (PLUS_EXPR, vr1min,
1676 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1676, __FUNCTION__))->typed.type)
, -1));
1677 else
1678 *vr0max
1679 = int_const_binop (MINUS_EXPR, vr1min,
1680 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1680, __FUNCTION__))->typed.type)
, 1));
1681 }
1682 /* Choose the anti-range if the range is effectively varying. */
1683 else if (vrp_val_is_min (*vr0min)
1684 && vrp_val_is_max (*vr0max))
1685 {
1686 *vr0type = vr1type;
1687 *vr0min = vr1min;
1688 *vr0max = vr1max;
1689 }
1690 /* Else choose the range. */
1691 }
1692 else if (*vr0type == VR_ANTI_RANGE
1693 && vr1type == VR_ANTI_RANGE)
1694 /* If both are anti-ranges the result is the outer one. */
1695 ;
1696 else if (*vr0type == VR_ANTI_RANGE
1697 && vr1type == VR_RANGE)
1698 {
1699 /* The intersection is empty. */
1700 *vr0type = VR_UNDEFINED;
1701 *vr0min = NULL_TREE(tree) nullptr;
1702 *vr0max = NULL_TREE(tree) nullptr;
1703 }
1704 else
1705 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1705, __FUNCTION__))
;
1706 }
1707 else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1)
1708 && (mineq || operand_less_p (vr1min, *vr0min) == 1))
1709 {
1710 /* ( [ ] ) or ([ ] ) or ( [ ]) */
1711 if (*vr0type == VR_RANGE
1712 && vr1type == VR_RANGE)
1713 /* Choose the inner range. */
1714 ;
1715 else if (*vr0type == VR_ANTI_RANGE
1716 && vr1type == VR_RANGE)
1717 {
1718 /* Choose the right gap if the left is empty. */
1719 if (mineq)
1720 {
1721 *vr0type = VR_RANGE;
1722 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) != INTEGER_CST)
1723 *vr0min = *vr0max;
1724 else if (TYPE_PRECISION (TREE_TYPE (*vr0max))((tree_class_check ((((contains_struct_check ((*vr0max), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1724, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1724, __FUNCTION__))->type_common.precision)
== 1
1725 && !TYPE_UNSIGNED (TREE_TYPE (*vr0max))((tree_class_check ((((contains_struct_check ((*vr0max), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1725, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1725, __FUNCTION__))->base.u.bits.unsigned_flag)
)
1726 *vr0min
1727 = int_const_binop (MINUS_EXPR, *vr0max,
1728 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1728, __FUNCTION__))->typed.type)
, -1));
1729 else
1730 *vr0min
1731 = int_const_binop (PLUS_EXPR, *vr0max,
1732 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1732, __FUNCTION__))->typed.type)
, 1));
1733 *vr0max = vr1max;
1734 }
1735 /* Choose the left gap if the right is empty. */
1736 else if (maxeq)
1737 {
1738 *vr0type = VR_RANGE;
1739 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) != INTEGER_CST)
1740 *vr0max = *vr0min;
1741 else if (TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1741, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1741, __FUNCTION__))->type_common.precision)
== 1
1742 && !TYPE_UNSIGNED (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1742, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1742, __FUNCTION__))->base.u.bits.unsigned_flag)
)
1743 *vr0max
1744 = int_const_binop (PLUS_EXPR, *vr0min,
1745 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1745, __FUNCTION__))->typed.type)
, -1));
1746 else
1747 *vr0max
1748 = int_const_binop (MINUS_EXPR, *vr0min,
1749 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1749, __FUNCTION__))->typed.type)
, 1));
1750 *vr0min = vr1min;
1751 }
1752 /* Choose the anti-range if the range is effectively varying. */
1753 else if (vrp_val_is_min (vr1min)
1754 && vrp_val_is_max (vr1max))
1755 ;
1756 /* Choose the anti-range if it is ~[0,0], that range is special
1757 enough to special case when vr1's range is relatively wide.
1758 At least for types bigger than int - this covers pointers
1759 and arguments to functions like ctz. */
1760 else if (*vr0min == *vr0max
1761 && integer_zerop (*vr0min)
1762 && ((TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1762, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1762, __FUNCTION__))->type_common.precision)
1763 >= TYPE_PRECISION (integer_type_node)((tree_class_check ((integer_types[itk_int]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1763, __FUNCTION__))->type_common.precision)
)
1764 || POINTER_TYPE_P (TREE_TYPE (*vr0min))(((enum tree_code) (((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1764, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1764, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
1765 && TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
1766 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
1767 && (wi::clz (wi::to_wide (vr1max) - wi::to_wide (vr1min))
1768 < TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1768, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1768, __FUNCTION__))->type_common.precision)
/ 2))
1769 ;
1770 /* Else choose the range. */
1771 else
1772 {
1773 *vr0type = vr1type;
1774 *vr0min = vr1min;
1775 *vr0max = vr1max;
1776 }
1777 }
1778 else if (*vr0type == VR_ANTI_RANGE
1779 && vr1type == VR_ANTI_RANGE)
1780 {
1781 /* If both are anti-ranges the result is the outer one. */
1782 *vr0type = vr1type;
1783 *vr0min = vr1min;
1784 *vr0max = vr1max;
1785 }
1786 else if (vr1type == VR_ANTI_RANGE
1787 && *vr0type == VR_RANGE)
1788 {
1789 /* The intersection is empty. */
1790 *vr0type = VR_UNDEFINED;
1791 *vr0min = NULL_TREE(tree) nullptr;
1792 *vr0max = NULL_TREE(tree) nullptr;
1793 }
1794 else
1795 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1795, __FUNCTION__))
;
1796 }
1797 else if ((operand_less_p (vr1min, *vr0max) == 1
1798 || operand_equal_p (vr1min, *vr0max, 0))
1799 && operand_less_p (*vr0min, vr1min) == 1
1800 && operand_less_p (*vr0max, vr1max) == 1)
1801 {
1802 /* [ ( ] ) or [ ]( ) */
1803 if (*vr0type == VR_ANTI_RANGE
1804 && vr1type == VR_ANTI_RANGE)
1805 *vr0max = vr1max;
1806 else if (*vr0type == VR_RANGE
1807 && vr1type == VR_RANGE)
1808 *vr0min = vr1min;
1809 else if (*vr0type == VR_RANGE
1810 && vr1type == VR_ANTI_RANGE)
1811 {
1812 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
1813 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
1814 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1814, __FUNCTION__))->typed.type)
, 1));
1815 else
1816 *vr0max = vr1min;
1817 }
1818 else if (*vr0type == VR_ANTI_RANGE
1819 && vr1type == VR_RANGE)
1820 {
1821 *vr0type = VR_RANGE;
1822 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
1823 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
1824 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1824, __FUNCTION__))->typed.type)
, 1));
1825 else
1826 *vr0min = *vr0max;
1827 *vr0max = vr1max;
1828 }
1829 else
1830 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1830, __FUNCTION__))
;
1831 }
1832 else if ((operand_less_p (*vr0min, vr1max) == 1
1833 || operand_equal_p (*vr0min, vr1max, 0))
1834 && operand_less_p (vr1min, *vr0min) == 1
1835 && operand_less_p (vr1max, *vr0max) == 1)
1836 {
1837 /* ( [ ) ] or ( )[ ] */
1838 if (*vr0type == VR_ANTI_RANGE
1839 && vr1type == VR_ANTI_RANGE)
1840 *vr0min = vr1min;
1841 else if (*vr0type == VR_RANGE
1842 && vr1type == VR_RANGE)
1843 *vr0max = vr1max;
1844 else if (*vr0type == VR_RANGE
1845 && vr1type == VR_ANTI_RANGE)
1846 {
1847 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
1848 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
1849 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1849, __FUNCTION__))->typed.type)
, 1));
1850 else
1851 *vr0min = vr1max;
1852 }
1853 else if (*vr0type == VR_ANTI_RANGE
1854 && vr1type == VR_RANGE)
1855 {
1856 *vr0type = VR_RANGE;
1857 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
1858 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
1859 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1859, __FUNCTION__))->typed.type)
, 1));
1860 else
1861 *vr0max = *vr0min;
1862 *vr0min = vr1min;
1863 }
1864 else
1865 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1865, __FUNCTION__))
;
1866 }
1867
1868 /* If we know the intersection is empty, there's no need to
1869 conservatively add anything else to the set. */
1870 if (*vr0type == VR_UNDEFINED)
1871 return;
1872
1873 /* As a fallback simply use { *VRTYPE, *VR0MIN, *VR0MAX } as
1874 result for the intersection. That's always a conservative
1875 correct estimate unless VR1 is a constant singleton range
1876 in which case we choose that. */
1877 if (vr1type == VR_RANGE
1878 && is_gimple_min_invariant (vr1min)
1879 && vrp_operand_equal_p (vr1min, vr1max))
1880 {
1881 *vr0type = vr1type;
1882 *vr0min = vr1min;
1883 *vr0max = vr1max;
1884 }
1885}
1886
1887/* Helper for the intersection operation for value ranges. Given two
1888 ranges VR0 and VR1, set VR0 to the intersection of both ranges.
1889 This may not be the smallest possible such range. */
1890
1891void
1892irange::legacy_intersect (irange *vr0, const irange *vr1)
1893{
1894 gcc_checking_assert (vr0->legacy_mode_p ())((void)(!(vr0->legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1894, __FUNCTION__), 0 : 0))
;
1895 gcc_checking_assert (vr1->legacy_mode_p ())((void)(!(vr1->legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1895, __FUNCTION__), 0 : 0))
;
1896 /* If either range is VR_VARYING the other one wins. */
1897 if (vr1->varying_p ())
1898 return;
1899 if (vr0->varying_p ())
1900 {
1901 vr0->set (vr1->min (), vr1->max (), vr1->kind ());
1902 return;
1903 }
1904
1905 /* When either range is VR_UNDEFINED the resulting range is
1906 VR_UNDEFINED, too. */
1907 if (vr0->undefined_p ())
1908 return;
1909 if (vr1->undefined_p ())
1910 {
1911 vr0->set_undefined ();
1912 return;
1913 }
1914
1915 value_range_kind vr0kind = vr0->kind ();
1916 tree vr0min = vr0->min ();
1917 tree vr0max = vr0->max ();
1918
1919 intersect_ranges (&vr0kind, &vr0min, &vr0max,
1920 vr1->kind (), vr1->min (), vr1->max ());
1921
1922 /* Make sure to canonicalize the result though as the inversion of a
1923 VR_RANGE can still be a VR_RANGE. */
1924 if (vr0kind == VR_UNDEFINED)
1925 vr0->set_undefined ();
1926 else if (vr0kind == VR_VARYING)
1927 {
1928 /* If we failed, use the original VR0. */
1929 return;
1930 }
1931 else
1932 vr0->set (vr0min, vr0max, vr0kind);
1933}
1934
1935/* Union the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
1936 { VR1TYPE, VR0MIN, VR0MAX } and store the result
1937 in { *VR0TYPE, *VR0MIN, *VR0MAX }. This may not be the smallest
1938 possible such range. The resulting range is not canonicalized. */
1939
1940static void
1941union_ranges (enum value_range_kind *vr0type,
1942 tree *vr0min, tree *vr0max,
1943 enum value_range_kind vr1type,
1944 tree vr1min, tree vr1max)
1945{
1946 int cmpmin = compare_values (*vr0min, vr1min);
1947 int cmpmax = compare_values (*vr0max, vr1max);
1948 bool mineq = cmpmin == 0;
1949 bool maxeq = cmpmax == 0;
1950
1951 /* [] is vr0, () is vr1 in the following classification comments. */
1952 if (mineq && maxeq)
1953 {
1954 /* [( )] */
1955 if (*vr0type == vr1type)
1956 /* Nothing to do for equal ranges. */
1957 ;
1958 else if ((*vr0type == VR_RANGE
1959 && vr1type == VR_ANTI_RANGE)
1960 || (*vr0type == VR_ANTI_RANGE
1961 && vr1type == VR_RANGE))
1962 {
1963 /* For anti-range with range union the result is varying. */
1964 goto give_up;
1965 }
1966 else
1967 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1967, __FUNCTION__))
;
1968 }
1969 else if (operand_less_p (*vr0max, vr1min) == 1
1970 || operand_less_p (vr1max, *vr0min) == 1)
1971 {
1972 /* [ ] ( ) or ( ) [ ]
1973 If the ranges have an empty intersection, result of the union
1974 operation is the anti-range or if both are anti-ranges
1975 it covers all. */
1976 if (*vr0type == VR_ANTI_RANGE
1977 && vr1type == VR_ANTI_RANGE)
1978 goto give_up;
1979 else if (*vr0type == VR_ANTI_RANGE
1980 && vr1type == VR_RANGE)
1981 ;
1982 else if (*vr0type == VR_RANGE
1983 && vr1type == VR_ANTI_RANGE)
1984 {
1985 *vr0type = vr1type;
1986 *vr0min = vr1min;
1987 *vr0max = vr1max;
1988 }
1989 else if (*vr0type == VR_RANGE
1990 && vr1type == VR_RANGE)
1991 {
1992 /* The result is the convex hull of both ranges. */
1993 if (operand_less_p (*vr0max, vr1min) == 1)
1994 {
1995 /* If the result can be an anti-range, create one. */
1996 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST
1997 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
1998 && vrp_val_is_min (*vr0min)
1999 && vrp_val_is_max (vr1max))
2000 {
2001 tree min = int_const_binop (PLUS_EXPR,
2002 *vr0max,
2003 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2003, __FUNCTION__))->typed.type)
, 1));
2004 tree max = int_const_binop (MINUS_EXPR,
2005 vr1min,
2006 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2006, __FUNCTION__))->typed.type)
, 1));
2007 if (!operand_less_p (max, min))
2008 {
2009 *vr0type = VR_ANTI_RANGE;
2010 *vr0min = min;
2011 *vr0max = max;
2012 }
2013 else
2014 *vr0max = vr1max;
2015 }
2016 else
2017 *vr0max = vr1max;
2018 }
2019 else
2020 {
2021 /* If the result can be an anti-range, create one. */
2022 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
2023 && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST
2024 && vrp_val_is_min (vr1min)
2025 && vrp_val_is_max (*vr0max))
2026 {
2027 tree min = int_const_binop (PLUS_EXPR,
2028 vr1max,
2029 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2029, __FUNCTION__))->typed.type)
, 1));
2030 tree max = int_const_binop (MINUS_EXPR,
2031 *vr0min,
2032 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2032, __FUNCTION__))->typed.type)
, 1));
2033 if (!operand_less_p (max, min))
2034 {
2035 *vr0type = VR_ANTI_RANGE;
2036 *vr0min = min;
2037 *vr0max = max;
2038 }
2039 else
2040 *vr0min = vr1min;
2041 }
2042 else
2043 *vr0min = vr1min;
2044 }
2045 }
2046 else
2047 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2047, __FUNCTION__))
;
2048 }
2049 else if ((maxeq || cmpmax == 1)
2050 && (mineq || cmpmin == -1))
2051 {
2052 /* [ ( ) ] or [( ) ] or [ ( )] */
2053 if (*vr0type == VR_RANGE
2054 && vr1type == VR_RANGE)
2055 ;
2056 else if (*vr0type == VR_ANTI_RANGE
2057 && vr1type == VR_ANTI_RANGE)
2058 {
2059 *vr0type = vr1type;
2060 *vr0min = vr1min;
2061 *vr0max = vr1max;
2062 }
2063 else if (*vr0type == VR_ANTI_RANGE
2064 && vr1type == VR_RANGE)
2065 {
2066 /* Arbitrarily choose the right or left gap. */
2067 if (!mineq && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
2068 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
2069 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2069, __FUNCTION__))->typed.type)
, 1));
2070 else if (!maxeq && TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
2071 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
2072 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2072, __FUNCTION__))->typed.type)
, 1));
2073 else
2074 goto give_up;
2075 }
2076 else if (*vr0type == VR_RANGE
2077 && vr1type == VR_ANTI_RANGE)
2078 /* The result covers everything. */
2079 goto give_up;
2080 else
2081 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2081, __FUNCTION__))
;
2082 }
2083 else if ((maxeq || cmpmax == -1)
2084 && (mineq || cmpmin == 1))
2085 {
2086 /* ( [ ] ) or ([ ] ) or ( [ ]) */
2087 if (*vr0type == VR_RANGE
2088 && vr1type == VR_RANGE)
2089 {
2090 *vr0type = vr1type;
2091 *vr0min = vr1min;
2092 *vr0max = vr1max;
2093 }
2094 else if (*vr0type == VR_ANTI_RANGE
2095 && vr1type == VR_ANTI_RANGE)
2096 ;
2097 else if (*vr0type == VR_RANGE
2098 && vr1type == VR_ANTI_RANGE)
2099 {
2100 *vr0type = VR_ANTI_RANGE;
2101 if (!mineq && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
2102 {
2103 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
2104 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2104, __FUNCTION__))->typed.type)
, 1));
2105 *vr0min = vr1min;
2106 }
2107 else if (!maxeq && TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
2108 {
2109 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
2110 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2110, __FUNCTION__))->typed.type)
, 1));
2111 *vr0max = vr1max;
2112 }
2113 else
2114 goto give_up;
2115 }
2116 else if (*vr0type == VR_ANTI_RANGE
2117 && vr1type == VR_RANGE)
2118 /* The result covers everything. */
2119 goto give_up;
2120 else
2121 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2121, __FUNCTION__))
;
2122 }
2123 else if (cmpmin == -1
2124 && cmpmax == -1
2125 && (operand_less_p (vr1min, *vr0max) == 1
2126 || operand_equal_p (vr1min, *vr0max, 0)))
2127 {
2128 /* [ ( ] ) or [ ]( ) */
2129 if (*vr0type == VR_RANGE
2130 && vr1type == VR_RANGE)
2131 *vr0max = vr1max;
2132 else if (*vr0type == VR_ANTI_RANGE
2133 && vr1type == VR_ANTI_RANGE)
2134 *vr0min = vr1min;
2135 else if (*vr0type == VR_ANTI_RANGE
2136 && vr1type == VR_RANGE)
2137 {
2138 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
2139 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
2140 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2140, __FUNCTION__))->typed.type)
, 1));
2141 else
2142 goto give_up;
2143 }
2144 else if (*vr0type == VR_RANGE
2145 && vr1type == VR_ANTI_RANGE)
2146 {
2147 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
2148 {
2149 *vr0type = vr1type;
2150 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
2151 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2151, __FUNCTION__))->typed.type)
, 1));
2152 *vr0max = vr1max;
2153 }
2154 else
2155 goto give_up;
2156 }
2157 else
2158 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2158, __FUNCTION__))
;
2159 }
2160 else if (cmpmin == 1
2161 && cmpmax == 1
2162 && (operand_less_p (*vr0min, vr1max) == 1
2163 || operand_equal_p (*vr0min, vr1max, 0)))
2164 {
2165 /* ( [ ) ] or ( )[ ] */
2166 if (*vr0type == VR_RANGE
2167 && vr1type == VR_RANGE)
2168 *vr0min = vr1min;
2169 else if (*vr0type == VR_ANTI_RANGE
2170 && vr1type == VR_ANTI_RANGE)
2171 *vr0max = vr1max;
2172 else if (*vr0type == VR_ANTI_RANGE
2173 && vr1type == VR_RANGE)
2174 {
2175 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
2176 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
2177 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2177, __FUNCTION__))->typed.type)
, 1));
2178 else
2179 goto give_up;
2180 }
2181 else if (*vr0type == VR_RANGE
2182 && vr1type == VR_ANTI_RANGE)
2183 {
2184 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
2185 {
2186 *vr0type = vr1type;
2187 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
2188 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2188, __FUNCTION__))->typed.type)
, 1));
2189 *vr0min = vr1min;
2190 }
2191 else
2192 goto give_up;
2193 }
2194 else
2195 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2195, __FUNCTION__))
;
2196 }
2197 else
2198 goto give_up;
2199
2200 return;
2201
2202give_up:
2203 *vr0type = VR_VARYING;
2204 *vr0min = NULL_TREE(tree) nullptr;
2205 *vr0max = NULL_TREE(tree) nullptr;
2206}
2207
2208/* Helper for meet operation for value ranges. Given two ranges VR0
2209 and VR1, set VR0 to the union of both ranges. This may not be the
2210 smallest possible such range. */
2211
2212void
2213irange::legacy_union (irange *vr0, const irange *vr1)
2214{
2215 gcc_checking_assert (vr0->legacy_mode_p ())((void)(!(vr0->legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2215, __FUNCTION__), 0 : 0))
;
2216 gcc_checking_assert (vr1->legacy_mode_p ())((void)(!(vr1->legacy_mode_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2216, __FUNCTION__), 0 : 0))
;
2217
2218 /* VR0 has the resulting range if VR1 is undefined or VR0 is varying. */
2219 if (vr1->undefined_p ()
2220 || vr0->varying_p ())
2221 return;
2222
2223 /* VR1 has the resulting range if VR0 is undefined or VR1 is varying. */
2224 if (vr0->undefined_p ())
2225 {
2226 vr0->set (vr1->min (), vr1->max (), vr1->kind ());
2227 return;
2228 }
2229
2230 if (vr1->varying_p ())
2231 {
2232 vr0->set_varying (vr1->type ());
2233 return;
2234 }
2235
2236 value_range_kind vr0kind = vr0->kind ();
2237 tree vr0min = vr0->min ();
2238 tree vr0max = vr0->max ();
2239
2240 union_ranges (&vr0kind, &vr0min, &vr0max,
2241 vr1->kind (), vr1->min (), vr1->max ());
2242
2243 if (vr0kind == VR_UNDEFINED)
2244 vr0->set_undefined ();
2245 else if (vr0kind == VR_VARYING)
2246 {
2247 /* Failed to find an efficient meet. Before giving up and
2248 setting the result to VARYING, see if we can at least derive
2249 a non-zero range. */
2250 if (range_includes_zero_p (vr0) == 0
2251 && range_includes_zero_p (vr1) == 0)
2252 vr0->set_nonzero (vr0->type ());
2253 else
2254 vr0->set_varying (vr0->type ());
2255 }
2256 else
2257 vr0->set (vr0min, vr0max, vr0kind);
2258}
2259
2260/* Meet operation for value ranges. Given two value ranges VR0 and
2261 VR1, store in VR0 a range that contains both VR0 and VR1. This
2262 may not be the smallest possible such range.
2263 Return TRUE if the original value changes. */
2264
2265bool
2266irange::legacy_verbose_union_ (const irange *other)
2267{
2268 if (legacy_mode_p ())
8
Taking false branch
2269 {
2270 if (!other->legacy_mode_p ())
2271 {
2272 int_range<1> tmp = *other;
2273 legacy_union (this, &tmp);
2274 return true;
2275 }
2276 if (dump_file && (dump_flags & TDF_DETAILS))
2277 {
2278 fprintf (dump_file, "Meeting\n ");
2279 dump_value_range (dump_file, this);
2280 fprintf (dump_file, "\nand\n ");
2281 dump_value_range (dump_file, other);
2282 fprintf (dump_file, "\n");
2283 }
2284
2285 legacy_union (this, other);
2286
2287 if (dump_file && (dump_flags & TDF_DETAILS))
2288 {
2289 fprintf (dump_file, "to\n ");
2290 dump_value_range (dump_file, this);
2291 fprintf (dump_file, "\n");
2292 }
2293 return true;
2294 }
2295
2296 if (other->legacy_mode_p ())
9
Taking false branch
2297 {
2298 int_range<2> wider = *other;
2299 return irange_union (wider);
2300 }
2301 else
2302 return irange_union (*other);
10
Calling 'irange::irange_union'
2303}
2304
2305bool
2306irange::legacy_verbose_intersect (const irange *other)
2307{
2308 if (legacy_mode_p ())
2309 {
2310 if (!other->legacy_mode_p ())
2311 {
2312 int_range<1> tmp = *other;
2313 legacy_intersect (this, &tmp);
2314 return true;
2315 }
2316 if (dump_file && (dump_flags & TDF_DETAILS))
2317 {
2318 fprintf (dump_file, "Intersecting\n ");
2319 dump_value_range (dump_file, this);
2320 fprintf (dump_file, "\nand\n ");
2321 dump_value_range (dump_file, other);
2322 fprintf (dump_file, "\n");
2323 }
2324
2325 legacy_intersect (this, other);
2326
2327 if (dump_file && (dump_flags & TDF_DETAILS))
2328 {
2329 fprintf (dump_file, "to\n ");
2330 dump_value_range (dump_file, this);
2331 fprintf (dump_file, "\n");
2332 }
2333 return true;
2334 }
2335
2336 if (other->legacy_mode_p ())
2337 {
2338 int_range<2> wider;
2339 wider = *other;
2340 return irange_intersect (wider);
2341 }
2342 else
2343 return irange_intersect (*other);
2344}
2345
2346// Perform an efficient union with R when both ranges have only a single pair.
2347// Excluded are VARYING and UNDEFINED ranges.
2348
2349bool
2350irange::irange_single_pair_union (const irange &r)
2351{
2352 gcc_checking_assert (!undefined_p () && !varying_p ())((void)(!(!undefined_p () && !varying_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2352, __FUNCTION__), 0 : 0))
;
2353 gcc_checking_assert (!r.undefined_p () && !varying_p ())((void)(!(!r.undefined_p () && !varying_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2353, __FUNCTION__), 0 : 0))
;
2354
2355 signop sign = TYPE_SIGN (TREE_TYPE (m_base[0]))((signop) ((tree_class_check ((((contains_struct_check ((m_base
[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2355, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2355, __FUNCTION__))->base.u.bits.unsigned_flag))
;
2356 // Check if current lower bound is also the new lower bound.
2357 if (wi::le_p (wi::to_wide (m_base[0]), wi::to_wide (r.m_base[0]), sign))
2358 {
2359 // If current upper bound is new upper bound, we're done.
2360 if (wi::le_p (wi::to_wide (r.m_base[1]), wi::to_wide (m_base[1]), sign))
2361 return union_nonzero_bits (r);
2362 // Otherwise R has the new upper bound.
2363 // Check for overlap/touching ranges, or single target range.
2364 if (m_max_ranges == 1
2365 || wi::to_widest (m_base[1]) + 1 >= wi::to_widest (r.m_base[0]))
2366 m_base[1] = r.m_base[1];
2367 else
2368 {
2369 // This is a dual range result.
2370 m_base[2] = r.m_base[0];
2371 m_base[3] = r.m_base[1];
2372 m_num_ranges = 2;
2373 }
2374 union_nonzero_bits (r);
2375 return true;
2376 }
2377
2378 // Set the new lower bound to R's lower bound.
2379 tree lb = m_base[0];
2380 m_base[0] = r.m_base[0];
2381
2382 // If R fully contains THIS range, just set the upper bound.
2383 if (wi::ge_p (wi::to_wide (r.m_base[1]), wi::to_wide (m_base[1]), sign))
2384 m_base[1] = r.m_base[1];
2385 // Check for overlapping ranges, or target limited to a single range.
2386 else if (m_max_ranges == 1
2387 || wi::to_widest (r.m_base[1]) + 1 >= wi::to_widest (lb))
2388 ;
2389 else
2390 {
2391 // Left with 2 pairs.
2392 m_num_ranges = 2;
2393 m_base[2] = lb;
2394 m_base[3] = m_base[1];
2395 m_base[1] = r.m_base[1];
2396 }
2397 union_nonzero_bits (r);
2398 return true;
2399}
2400
2401// union_ for multi-ranges.
2402
2403bool
2404irange::irange_union (const irange &r)
2405{
2406 gcc_checking_assert (!legacy_mode_p () && !r.legacy_mode_p ())((void)(!(!legacy_mode_p () && !r.legacy_mode_p ()) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2406, __FUNCTION__), 0 : 0))
;
11
'?' condition is false
2407
2408 if (r.undefined_p ())
12
Taking false branch
2409 return false;
2410
2411 if (undefined_p ())
13
Taking false branch
2412 {
2413 operator= (r);
2414 if (flag_checkingglobal_options.x_flag_checking)
2415 verify_range ();
2416 return true;
2417 }
2418
2419 if (varying_p ())
14
Taking false branch
2420 return false;
2421
2422 if (r.varying_p ())
15
Taking true branch
2423 {
2424 set_varying (type ());
16
Calling 'irange::type'
2425 return true;
2426 }
2427
2428 // Special case one range union one range.
2429 if (m_num_ranges == 1 && r.m_num_ranges == 1)
2430 return irange_single_pair_union (r);
2431
2432 // If this ranges fully contains R, then we need do nothing.
2433 if (irange_contains_p (r))
2434 return union_nonzero_bits (r);
2435
2436 // Do not worry about merging and such by reserving twice as many
2437 // pairs as needed, and then simply sort the 2 ranges into this
2438 // intermediate form.
2439 //
2440 // The intermediate result will have the property that the beginning
2441 // of each range is <= the beginning of the next range. There may
2442 // be overlapping ranges at this point. I.e. this would be valid
2443 // [-20, 10], [-10, 0], [0, 20], [40, 90] as it satisfies this
2444 // constraint : -20 < -10 < 0 < 40. When the range is rebuilt into r,
2445 // the merge is performed.
2446 //
2447 // [Xi,Yi]..[Xn,Yn] U [Xj,Yj]..[Xm,Ym] --> [Xk,Yk]..[Xp,Yp]
2448 auto_vec<tree, 20> res (m_num_ranges * 2 + r.m_num_ranges * 2);
2449 unsigned i = 0, j = 0, k = 0;
2450
2451 while (i < m_num_ranges * 2 && j < r.m_num_ranges * 2)
2452 {
2453 // lower of Xi and Xj is the lowest point.
2454 if (wi::to_widest (m_base[i]) <= wi::to_widest (r.m_base[j]))
2455 {
2456 res.quick_push (m_base[i]);
2457 res.quick_push (m_base[i + 1]);
2458 k += 2;
2459 i += 2;
2460 }
2461 else
2462 {
2463 res.quick_push (r.m_base[j]);
2464 res.quick_push (r.m_base[j + 1]);
2465 k += 2;
2466 j += 2;
2467 }
2468 }
2469 for ( ; i < m_num_ranges * 2; i += 2)
2470 {
2471 res.quick_push (m_base[i]);
2472 res.quick_push (m_base[i + 1]);
2473 k += 2;
2474 }
2475 for ( ; j < r.m_num_ranges * 2; j += 2)
2476 {
2477 res.quick_push (r.m_base[j]);
2478 res.quick_push (r.m_base[j + 1]);
2479 k += 2;
2480 }
2481
2482 // Now normalize the vector removing any overlaps.
2483 i = 2;
2484 for (j = 2; j < k ; j += 2)
2485 {
2486 // Current upper+1 is >= lower bound next pair, then we merge ranges.
2487 if (wi::to_widest (res[i - 1]) + 1 >= wi::to_widest (res[j]))
2488 {
2489 // New upper bounds is greater of current or the next one.
2490 if (wi::to_widest (res[j + 1]) > wi::to_widest (res[i - 1]))
2491 res[i - 1] = res[j + 1];
2492 }
2493 else
2494 {
2495 // This is a new distinct range, but no point in copying it
2496 // if it is already in the right place.
2497 if (i != j)
2498 {
2499 res[i++] = res[j];
2500 res[i++] = res[j + 1];
2501 }
2502 else
2503 i += 2;
2504 }
2505 }
2506
2507 // At this point, the vector should have i ranges, none overlapping.
2508 // Now it simply needs to be copied, and if there are too many
2509 // ranges, merge some. We wont do any analysis as to what the
2510 // "best" merges are, simply combine the final ranges into one.
2511 if (i > m_max_ranges * 2)
2512 {
2513 res[m_max_ranges * 2 - 1] = res[i - 1];
2514 i = m_max_ranges * 2;
2515 }
2516
2517 for (j = 0; j < i ; j++)
2518 m_base[j] = res [j];
2519 m_num_ranges = i / 2;
2520
2521 m_kind = VR_RANGE;
2522 union_nonzero_bits (r);
2523 return true;
2524}
2525
2526// Return TRUE if THIS fully contains R. No undefined or varying cases.
2527
2528bool
2529irange::irange_contains_p (const irange &r) const
2530{
2531 gcc_checking_assert (!undefined_p () && !varying_p ())((void)(!(!undefined_p () && !varying_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2531, __FUNCTION__), 0 : 0))
;
2532 gcc_checking_assert (!r.undefined_p () && !varying_p ())((void)(!(!r.undefined_p () && !varying_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2532, __FUNCTION__), 0 : 0))
;
2533
2534 // In order for THIS to fully contain R, all of the pairs within R must
2535 // be fully contained by the pairs in this object.
2536 signop sign = TYPE_SIGN (TREE_TYPE(m_base[0]))((signop) ((tree_class_check ((((contains_struct_check ((m_base
[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2536, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2536, __FUNCTION__))->base.u.bits.unsigned_flag))
;
2537 unsigned ri = 0;
2538 unsigned i = 0;
2539 tree rl = r.m_base[0];
2540 tree ru = r.m_base[1];
2541 tree l = m_base[0];
2542 tree u = m_base[1];
2543 while (1)
2544 {
2545 // If r is contained within this range, move to the next R
2546 if (wi::ge_p (wi::to_wide (rl), wi::to_wide (l), sign)
2547 && wi::le_p (wi::to_wide (ru), wi::to_wide (u), sign))
2548 {
2549 // This pair is OK, Either done, or bump to the next.
2550 if (++ri >= r.num_pairs ())
2551 return true;
2552 rl = r.m_base[ri * 2];
2553 ru = r.m_base[ri * 2 + 1];
2554 continue;
2555 }
2556 // Otherwise, check if this's pair occurs before R's.
2557 if (wi::lt_p (wi::to_wide (u), wi::to_wide (rl), sign))
2558 {
2559 // There's still at least one pair of R left.
2560 if (++i >= num_pairs ())
2561 return false;
2562 l = m_base[i * 2];
2563 u = m_base[i * 2 + 1];
2564 continue;
2565 }
2566 return false;
2567 }
2568 return false;
2569}
2570
2571
2572// Intersect for multi-ranges. Return TRUE if anything changes.
2573
2574bool
2575irange::irange_intersect (const irange &r)
2576{
2577 gcc_checking_assert (!legacy_mode_p () && !r.legacy_mode_p ())((void)(!(!legacy_mode_p () && !r.legacy_mode_p ()) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2577, __FUNCTION__), 0 : 0))
;
2578 gcc_checking_assert (undefined_p () || r.undefined_p ()((void)(!(undefined_p () || r.undefined_p () || range_compatible_p
(type (), r.type ())) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2579, __FUNCTION__), 0 : 0))
2579 || range_compatible_p (type (), r.type ()))((void)(!(undefined_p () || r.undefined_p () || range_compatible_p
(type (), r.type ())) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2579, __FUNCTION__), 0 : 0))
;
2580
2581 if (undefined_p ())
2582 return false;
2583 if (r.undefined_p ())
2584 {
2585 set_undefined ();
2586 return true;
2587 }
2588 if (r.varying_p ())
2589 return false;
2590 if (varying_p ())
2591 {
2592 operator= (r);
2593 return true;
2594 }
2595
2596 if (r.num_pairs () == 1)
2597 {
2598 bool res = intersect (r.lower_bound (), r.upper_bound ());
2599 if (undefined_p ())
2600 return true;
2601
2602 res |= intersect_nonzero_bits (r);
2603 return res;
2604 }
2605
2606 // If R fully contains this, then intersection will change nothing.
2607 if (r.irange_contains_p (*this))
2608 return intersect_nonzero_bits (r);
2609
2610 signop sign = TYPE_SIGN (TREE_TYPE(m_base[0]))((signop) ((tree_class_check ((((contains_struct_check ((m_base
[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2610, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2610, __FUNCTION__))->base.u.bits.unsigned_flag))
;
2611 unsigned bld_pair = 0;
2612 unsigned bld_lim = m_max_ranges;
2613 int_range_max r2 (*this);
2614 unsigned r2_lim = r2.num_pairs ();
2615 unsigned i2 = 0;
2616 for (unsigned i = 0; i < r.num_pairs (); )
2617 {
2618 // If r1's upper is < r2's lower, we can skip r1's pair.
2619 tree ru = r.m_base[i * 2 + 1];
2620 tree r2l = r2.m_base[i2 * 2];
2621 if (wi::lt_p (wi::to_wide (ru), wi::to_wide (r2l), sign))
2622 {
2623 i++;
2624 continue;
2625 }
2626 // Likewise, skip r2's pair if its excluded.
2627 tree r2u = r2.m_base[i2 * 2 + 1];
2628 tree rl = r.m_base[i * 2];
2629 if (wi::lt_p (wi::to_wide (r2u), wi::to_wide (rl), sign))
2630 {
2631 i2++;
2632 if (i2 < r2_lim)
2633 continue;
2634 // No more r2, break.
2635 break;
2636 }
2637
2638 // Must be some overlap. Find the highest of the lower bounds,
2639 // and set it, unless the build limits lower bounds is already
2640 // set.
2641 if (bld_pair < bld_lim)
2642 {
2643 if (wi::ge_p (wi::to_wide (rl), wi::to_wide (r2l), sign))
2644 m_base[bld_pair * 2] = rl;
2645 else
2646 m_base[bld_pair * 2] = r2l;
2647 }
2648 else
2649 // Decrease and set a new upper.
2650 bld_pair--;
2651
2652 // ...and choose the lower of the upper bounds.
2653 if (wi::le_p (wi::to_wide (ru), wi::to_wide (r2u), sign))
2654 {
2655 m_base[bld_pair * 2 + 1] = ru;
2656 bld_pair++;
2657 // Move past the r1 pair and keep trying.
2658 i++;
2659 continue;
2660 }
2661 else
2662 {
2663 m_base[bld_pair * 2 + 1] = r2u;
2664 bld_pair++;
2665 i2++;
2666 if (i2 < r2_lim)
2667 continue;
2668 // No more r2, break.
2669 break;
2670 }
2671 // r2 has the higher lower bound.
2672 }
2673
2674 // At the exit of this loop, it is one of 2 things:
2675 // ran out of r1, or r2, but either means we are done.
2676 m_num_ranges = bld_pair;
2677 if (m_num_ranges == 0)
2678 {
2679 set_undefined ();
2680 return true;
2681 }
2682
2683 m_kind = VR_RANGE;
2684 intersect_nonzero_bits (r);
2685 return true;
2686}
2687
2688
2689// Multirange intersect for a specified wide_int [lb, ub] range.
2690// Return TRUE if intersect changed anything.
2691//
2692// NOTE: It is the caller's responsibility to intersect the nonzero masks.
2693
2694bool
2695irange::intersect (const wide_int& lb, const wide_int& ub)
2696{
2697 // Undefined remains undefined.
2698 if (undefined_p ())
2699 return false;
2700
2701 if (legacy_mode_p ())
2702 {
2703 intersect (int_range<1> (type (), lb, ub));
2704 return true;
2705 }
2706
2707 tree range_type = type();
2708 signop sign = TYPE_SIGN (range_type)((signop) ((tree_class_check ((range_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2708, __FUNCTION__))->base.u.bits.unsigned_flag))
;
2709
2710 gcc_checking_assert (TYPE_PRECISION (range_type) == wi::get_precision (lb))((void)(!(((tree_class_check ((range_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2710, __FUNCTION__))->type_common.precision) == wi::get_precision
(lb)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2710, __FUNCTION__), 0 : 0))
;
2711 gcc_checking_assert (TYPE_PRECISION (range_type) == wi::get_precision (ub))((void)(!(((tree_class_check ((range_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2711, __FUNCTION__))->type_common.precision) == wi::get_precision
(ub)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2711, __FUNCTION__), 0 : 0))
;
2712
2713 // If this range is fully contained, then intersection will do nothing.
2714 if (wi::ge_p (lower_bound (), lb, sign)
2715 && wi::le_p (upper_bound (), ub, sign))
2716 return false;
2717
2718 unsigned bld_index = 0;
2719 unsigned pair_lim = num_pairs ();
2720 for (unsigned i = 0; i < pair_lim; i++)
2721 {
2722 tree pairl = m_base[i * 2];
2723 tree pairu = m_base[i * 2 + 1];
2724 // Once UB is less than a pairs lower bound, we're done.
2725 if (wi::lt_p (ub, wi::to_wide (pairl), sign))
2726 break;
2727 // if LB is greater than this pairs upper, this pair is excluded.
2728 if (wi::lt_p (wi::to_wide (pairu), lb, sign))
2729 continue;
2730
2731 // Must be some overlap. Find the highest of the lower bounds,
2732 // and set it
2733 if (wi::gt_p (lb, wi::to_wide (pairl), sign))
2734 m_base[bld_index * 2] = wide_int_to_tree (range_type, lb);
2735 else
2736 m_base[bld_index * 2] = pairl;
2737
2738 // ...and choose the lower of the upper bounds and if the base pair
2739 // has the lower upper bound, need to check next pair too.
2740 if (wi::lt_p (ub, wi::to_wide (pairu), sign))
2741 {
2742 m_base[bld_index++ * 2 + 1] = wide_int_to_tree (range_type, ub);
2743 break;
2744 }
2745 else
2746 m_base[bld_index++ * 2 + 1] = pairu;
2747 }
2748
2749 m_num_ranges = bld_index;
2750 if (m_num_ranges == 0)
2751 {
2752 set_undefined ();
2753 return true;
2754 }
2755
2756 m_kind = VR_RANGE;
2757 // No need to call normalize_kind(), as the caller will do this
2758 // while intersecting the nonzero mask.
2759 if (flag_checkingglobal_options.x_flag_checking)
2760 verify_range ();
2761 return true;
2762}
2763
2764
2765// Signed 1-bits are strange. You can't subtract 1, because you can't
2766// represent the number 1. This works around that for the invert routine.
2767
2768static wide_int inline
2769subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow)
2770{
2771 if (TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2771, __FUNCTION__))->base.u.bits.unsigned_flag))
== SIGNED)
2772 return wi::add (x, -1, SIGNED, &overflow);
2773 else
2774 return wi::sub (x, 1, UNSIGNED, &overflow);
2775}
2776
2777// The analogous function for adding 1.
2778
2779static wide_int inline
2780add_one (const wide_int &x, tree type, wi::overflow_type &overflow)
2781{
2782 if (TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2782, __FUNCTION__))->base.u.bits.unsigned_flag))
== SIGNED)
2783 return wi::sub (x, -1, SIGNED, &overflow);
2784 else
2785 return wi::add (x, 1, UNSIGNED, &overflow);
2786}
2787
2788// Return the inverse of a range.
2789
2790void
2791irange::invert ()
2792{
2793 if (legacy_mode_p ())
2794 {
2795 // We can't just invert VR_RANGE and VR_ANTI_RANGE because we may
2796 // create non-canonical ranges. Use the constructors instead.
2797 if (m_kind == VR_RANGE)
2798 *this = value_range (min (), max (), VR_ANTI_RANGE);
2799 else if (m_kind == VR_ANTI_RANGE)
2800 *this = value_range (min (), max ());
2801 else
2802 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2802, __FUNCTION__))
;
2803 return;
2804 }
2805
2806 gcc_checking_assert (!undefined_p () && !varying_p ())((void)(!(!undefined_p () && !varying_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2806, __FUNCTION__), 0 : 0))
;
2807
2808 // We always need one more set of bounds to represent an inverse, so
2809 // if we're at the limit, we can't properly represent things.
2810 //
2811 // For instance, to represent the inverse of a 2 sub-range set
2812 // [5, 10][20, 30], we would need a 3 sub-range set
2813 // [-MIN, 4][11, 19][31, MAX].
2814 //
2815 // In this case, return the most conservative thing.
2816 //
2817 // However, if any of the extremes of the range are -MIN/+MAX, we
2818 // know we will not need an extra bound. For example:
2819 //
2820 // INVERT([-MIN,20][30,40]) => [21,29][41,+MAX]
2821 // INVERT([-MIN,20][30,MAX]) => [21,29]
2822 tree ttype = type ();
2823 unsigned prec = TYPE_PRECISION (ttype)((tree_class_check ((ttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2823, __FUNCTION__))->type_common.precision)
;
2824 signop sign = TYPE_SIGN (ttype)((signop) ((tree_class_check ((ttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2824, __FUNCTION__))->base.u.bits.unsigned_flag))
;
2825 wide_int type_min = wi::min_value (prec, sign);
2826 wide_int type_max = wi::max_value (prec, sign);
2827 m_nonzero_mask = NULLnullptr;
2828 if (m_num_ranges == m_max_ranges
2829 && lower_bound () != type_min
2830 && upper_bound () != type_max)
2831 {
2832 m_base[1] = wide_int_to_tree (ttype, type_max);
2833 m_num_ranges = 1;
2834 return;
2835 }
2836 // The algorithm is as follows. To calculate INVERT ([a,b][c,d]), we
2837 // generate [-MIN, a-1][b+1, c-1][d+1, MAX].
2838 //
2839 // If there is an over/underflow in the calculation for any
2840 // sub-range, we eliminate that subrange. This allows us to easily
2841 // calculate INVERT([-MIN, 5]) with: [-MIN, -MIN-1][6, MAX]. And since
2842 // we eliminate the underflow, only [6, MAX] remains.
2843 unsigned i = 0;
2844 wi::overflow_type ovf;
2845 // Construct leftmost range.
2846 int_range_max orig_range (*this);
2847 unsigned nitems = 0;
2848 wide_int tmp;
2849 // If this is going to underflow on the MINUS 1, don't even bother
2850 // checking. This also handles subtracting one from an unsigned 0,
2851 // which doesn't set the underflow bit.
2852 if (type_min != orig_range.lower_bound ())
2853 {
2854 m_base[nitems++] = wide_int_to_tree (ttype, type_min);
2855 tmp = subtract_one (orig_range.lower_bound (), ttype, ovf);
2856 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
2857 if (ovf)
2858 nitems = 0;
2859 }
2860 i++;
2861 // Construct middle ranges if applicable.
2862 if (orig_range.num_pairs () > 1)
2863 {
2864 unsigned j = i;
2865 for (; j < (orig_range.num_pairs () * 2) - 1; j += 2)
2866 {
2867 // The middle ranges cannot have MAX/MIN, so there's no need
2868 // to check for unsigned overflow on the +1 and -1 here.
2869 tmp = wi::add (wi::to_wide (orig_range.m_base[j]), 1, sign, &ovf);
2870 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
2871 tmp = subtract_one (wi::to_wide (orig_range.m_base[j + 1]),
2872 ttype, ovf);
2873 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
2874 if (ovf)
2875 nitems -= 2;
2876 }
2877 i = j;
2878 }
2879 // Construct rightmost range.
2880 //
2881 // However, if this will overflow on the PLUS 1, don't even bother.
2882 // This also handles adding one to an unsigned MAX, which doesn't
2883 // set the overflow bit.
2884 if (type_max != wi::to_wide (orig_range.m_base[i]))
2885 {
2886 tmp = add_one (wi::to_wide (orig_range.m_base[i]), ttype, ovf);
2887 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
2888 m_base[nitems++] = wide_int_to_tree (ttype, type_max);
2889 if (ovf)
2890 nitems -= 2;
2891 }
2892 m_num_ranges = nitems / 2;
2893
2894 // We disallow undefined or varying coming in, so the result can
2895 // only be a VR_RANGE.
2896 gcc_checking_assert (m_kind == VR_RANGE)((void)(!(m_kind == VR_RANGE) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2896, __FUNCTION__), 0 : 0))
;
2897
2898 if (flag_checkingglobal_options.x_flag_checking)
2899 verify_range ();
2900}
2901
2902// Return the nonzero bits inherent in the range.
2903
2904wide_int
2905irange::get_nonzero_bits_from_range () const
2906{
2907 // For legacy symbolics.
2908 if (!constant_p ())
2909 return wi::shwi (-1, TYPE_PRECISION (type ())((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2909, __FUNCTION__))->type_common.precision)
);
2910
2911 wide_int min = lower_bound ();
2912 wide_int max = upper_bound ();
2913 wide_int xorv = min ^ max;
2914 if (xorv != 0)
2915 {
2916 unsigned prec = TYPE_PRECISION (type ())((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2916, __FUNCTION__))->type_common.precision)
;
2917 xorv = wi::mask (prec - wi::clz (xorv), false, prec);
2918 }
2919 return min | xorv;
2920}
2921
2922// If the the nonzero mask can be trivially converted to a range, do
2923// so and return TRUE.
2924
2925bool
2926irange::set_range_from_nonzero_bits ()
2927{
2928 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2928, __FUNCTION__), 0 : 0))
;
2929 if (!m_nonzero_mask)
2930 return false;
2931 unsigned popcount = wi::popcount (wi::to_wide (m_nonzero_mask));
2932
2933 // If we have only one bit set in the mask, we can figure out the
2934 // range immediately.
2935 if (popcount == 1)
2936 {
2937 // Make sure we don't pessimize the range.
2938 if (!contains_p (m_nonzero_mask))
2939 return false;
2940
2941 bool has_zero = contains_p (build_zero_cst (type ()));
2942 tree nz = m_nonzero_mask;
2943 set (nz, nz);
2944 m_nonzero_mask = nz;
2945 if (has_zero)
2946 {
2947 int_range<2> zero;
2948 zero.set_zero (type ());
2949 union_ (zero);
2950 }
2951 return true;
2952 }
2953 else if (popcount == 0)
2954 {
2955 set_zero (type ());
2956 return true;
2957 }
2958 return false;
2959}
2960
2961void
2962irange::set_nonzero_bits (const wide_int_ref &bits)
2963{
2964 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2964, __FUNCTION__), 0 : 0))
;
2965 unsigned prec = TYPE_PRECISION (type ())((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2965, __FUNCTION__))->type_common.precision)
;
2966
2967 if (bits == -1)
2968 {
2969 m_nonzero_mask = NULLnullptr;
2970 normalize_kind ();
2971 if (flag_checkingglobal_options.x_flag_checking)
2972 verify_range ();
2973 return;
2974 }
2975
2976 // Drop VARYINGs with a nonzero mask to a plain range.
2977 if (m_kind == VR_VARYING && bits != -1)
2978 m_kind = VR_RANGE;
2979
2980 wide_int nz = wide_int::from (bits, prec, TYPE_SIGN (type ())((signop) ((tree_class_check ((type ()), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2980, __FUNCTION__))->base.u.bits.unsigned_flag))
);
2981 m_nonzero_mask = wide_int_to_tree (type (), nz);
2982 if (set_range_from_nonzero_bits ())
2983 return;
2984
2985 normalize_kind ();
2986 if (flag_checkingglobal_options.x_flag_checking)
2987 verify_range ();
2988}
2989
2990// Return the nonzero bitmask. This will return the nonzero bits plus
2991// the nonzero bits inherent in the range.
2992
2993wide_int
2994irange::get_nonzero_bits () const
2995{
2996 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2996, __FUNCTION__), 0 : 0))
;
2997 // The nonzero mask inherent in the range is calculated on-demand.
2998 // For example, [0,255] does not have a 0xff nonzero mask by default
2999 // (unless manually set). This saves us considerable time, because
3000 // setting it at creation incurs a large penalty for irange::set.
3001 // At the time of writing there was a 5% slowdown in VRP if we kept
3002 // the mask precisely up to date at all times. Instead, we default
3003 // to -1 and set it when explicitly requested. However, this
3004 // function will always return the correct mask.
3005 if (m_nonzero_mask)
3006 return wi::to_wide (m_nonzero_mask) & get_nonzero_bits_from_range ();
3007 else
3008 return get_nonzero_bits_from_range ();
3009}
3010
3011// Convert tree mask to wide_int. Returns -1 for NULL masks.
3012
3013inline wide_int
3014mask_to_wi (tree mask, tree type)
3015{
3016 if (mask)
3017 return wi::to_wide (mask);
3018 else
3019 return wi::shwi (-1, TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3019, __FUNCTION__))->type_common.precision)
);
3020}
3021
3022// Intersect the nonzero bits in R into THIS and normalize the range.
3023// Return TRUE if the intersection changed anything.
3024
3025bool
3026irange::intersect_nonzero_bits (const irange &r)
3027{
3028 gcc_checking_assert (!undefined_p () && !r.undefined_p ())((void)(!(!undefined_p () && !r.undefined_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3028, __FUNCTION__), 0 : 0))
;
3029
3030 if (!m_nonzero_mask && !r.m_nonzero_mask)
3031 {
3032 normalize_kind ();
3033 if (flag_checkingglobal_options.x_flag_checking)
3034 verify_range ();
3035 return false;
3036 }
3037
3038 bool changed = false;
3039 tree t = type ();
3040 if (mask_to_wi (m_nonzero_mask, t) != mask_to_wi (r.m_nonzero_mask, t))
3041 {
3042 wide_int nz = get_nonzero_bits () & r.get_nonzero_bits ();
3043 // If the nonzero bits did not change, return false.
3044 if (nz == get_nonzero_bits ())
3045 return false;
3046
3047 m_nonzero_mask = wide_int_to_tree (t, nz);
3048 if (set_range_from_nonzero_bits ())
3049 return true;
3050 changed = true;
3051 }
3052 normalize_kind ();
3053 if (flag_checkingglobal_options.x_flag_checking)
3054 verify_range ();
3055 return changed;
3056}
3057
3058// Union the nonzero bits in R into THIS and normalize the range.
3059// Return TRUE if the union changed anything.
3060
3061bool
3062irange::union_nonzero_bits (const irange &r)
3063{
3064 gcc_checking_assert (!undefined_p () && !r.undefined_p ())((void)(!(!undefined_p () && !r.undefined_p ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3064, __FUNCTION__), 0 : 0))
;
3065
3066 if (!m_nonzero_mask && !r.m_nonzero_mask)
3067 {
3068 normalize_kind ();
3069 if (flag_checkingglobal_options.x_flag_checking)
3070 verify_range ();
3071 return false;
3072 }
3073
3074 bool changed = false;
3075 tree t = type ();
3076 if (mask_to_wi (m_nonzero_mask, t) != mask_to_wi (r.m_nonzero_mask, t))
3077 {
3078 wide_int nz = get_nonzero_bits () | r.get_nonzero_bits ();
3079 m_nonzero_mask = wide_int_to_tree (t, nz);
3080 // No need to call set_range_from_nonzero_bits, because we'll
3081 // never narrow the range. Besides, it would cause endless
3082 // recursion because of the union_ in
3083 // set_range_from_nonzero_bits.
3084 changed = true;
3085 }
3086 normalize_kind ();
3087 if (flag_checkingglobal_options.x_flag_checking)
3088 verify_range ();
3089 return changed;
3090}
3091
3092void
3093dump_value_range (FILE *file, const vrange *vr)
3094{
3095 vr->dump (file);
3096}
3097
3098DEBUG_FUNCTION__attribute__ ((__used__)) void
3099debug (const vrange *vr)
3100{
3101 dump_value_range (stderrstderr, vr);
3102 fprintf (stderrstderr, "\n");
3103}
3104
3105DEBUG_FUNCTION__attribute__ ((__used__)) void
3106debug (const vrange &vr)
3107{
3108 debug (&vr);
3109}
3110
3111DEBUG_FUNCTION__attribute__ ((__used__)) void
3112debug (const value_range *vr)
3113{
3114 dump_value_range (stderrstderr, vr);
3115 fprintf (stderrstderr, "\n");
3116}
3117
3118DEBUG_FUNCTION__attribute__ ((__used__)) void
3119debug (const value_range &vr)
3120{
3121 dump_value_range (stderrstderr, &vr);
3122 fprintf (stderrstderr, "\n");
3123}
3124
3125/* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
3126 so that *VR0 U *VR1 == *AR. Returns true if that is possible,
3127 false otherwise. If *AR can be represented with a single range
3128 *VR1 will be VR_UNDEFINED. */
3129
3130bool
3131ranges_from_anti_range (const value_range *ar,
3132 value_range *vr0, value_range *vr1)
3133{
3134 tree type = ar->type ();
3135
3136 vr0->set_undefined ();
3137 vr1->set_undefined ();
3138
3139 /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
3140 [A+1, +INF]. Not sure if this helps in practice, though. */
3141
3142 if (ar->kind () != VR_ANTI_RANGE
3143 || TREE_CODE (ar->min ())((enum tree_code) (ar->min ())->base.code) != INTEGER_CST
3144 || TREE_CODE (ar->max ())((enum tree_code) (ar->max ())->base.code) != INTEGER_CST
3145 || !vrp_val_min (type)
3146 || !vrp_val_max (type))
3147 return false;
3148
3149 if (tree_int_cst_lt (vrp_val_min (type), ar->min ()))
3150 vr0->set (vrp_val_min (type),
3151 wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
3152 if (tree_int_cst_lt (ar->max (), vrp_val_max (type)))
3153 vr1->set (wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
3154 vrp_val_max (type));
3155 if (vr0->undefined_p ())
3156 {
3157 *vr0 = *vr1;
3158 vr1->set_undefined ();
3159 }
3160
3161 return !vr0->undefined_p ();
3162}
3163
3164bool
3165range_has_numeric_bounds_p (const irange *vr)
3166{
3167 return (!vr->undefined_p ()
3168 && TREE_CODE (vr->min ())((enum tree_code) (vr->min ())->base.code) == INTEGER_CST
3169 && TREE_CODE (vr->max ())((enum tree_code) (vr->max ())->base.code) == INTEGER_CST);
3170}
3171
3172/* Return whether VAL is equal to the maximum value of its type.
3173 We can't do a simple equality comparison with TYPE_MAX_VALUE because
3174 C typedefs and Ada subtypes can produce types whose TYPE_MAX_VALUE
3175 is not == to the integer constant with the same value in the type. */
3176
3177bool
3178vrp_val_is_max (const_tree val)
3179{
3180 tree type_max = vrp_val_max (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3180, __FUNCTION__))->typed.type)
);
3181 return (val == type_max
3182 || (type_max != NULL_TREE(tree) nullptr
3183 && operand_equal_p (val, type_max, 0)));
3184}
3185
3186/* Return whether VAL is equal to the minimum value of its type. */
3187
3188bool
3189vrp_val_is_min (const_tree val)
3190{
3191 tree type_min = vrp_val_min (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3191, __FUNCTION__))->typed.type)
);
3192 return (val == type_min
3193 || (type_min != NULL_TREE(tree) nullptr
3194 && operand_equal_p (val, type_min, 0)));
3195}
3196
3197/* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
3198
3199bool
3200vrp_operand_equal_p (const_tree val1, const_tree val2)
3201{
3202 if (val1 == val2)
3203 return true;
3204 if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
3205 return false;
3206 return true;
3207}
3208
3209// ?? These stubs are for ipa-prop.cc which use a value_range in a
3210// hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
3211// instead of picking up the gt_ggc_mx (T *) version.
3212void
3213gt_pch_nx (int_range<1> *&x)
3214{
3215 return gt_pch_nx ((irange *) x);
3216}
3217
3218void
3219gt_ggc_mx (int_range<1> *&x)
3220{
3221 return gt_ggc_mx ((irange *) x);
3222}
3223
3224#define DEFINE_INT_RANGE_INSTANCE(N)template int_range<N>::int_range(tree, tree, value_range_kind
); template int_range<N>::int_range(tree_node *, const wide_int
&, const wide_int &, value_range_kind); template int_range
<N>::int_range(tree); template int_range<N>::int_range
(const irange &); template int_range<N>::int_range(
const int_range &); template int_range<N>& int_range
<N>::operator= (const int_range &);
\
3225 template int_range<N>::int_range(tree, tree, value_range_kind); \
3226 template int_range<N>::int_range(tree_node *, \
3227 const wide_int &, \
3228 const wide_int &, \
3229 value_range_kind); \
3230 template int_range<N>::int_range(tree); \
3231 template int_range<N>::int_range(const irange &); \
3232 template int_range<N>::int_range(const int_range &); \
3233 template int_range<N>& int_range<N>::operator= (const int_range &);
3234
3235DEFINE_INT_RANGE_INSTANCE(1)template int_range<1>::int_range(tree, tree, value_range_kind
); template int_range<1>::int_range(tree_node *, const wide_int
&, const wide_int &, value_range_kind); template int_range
<1>::int_range(tree); template int_range<1>::int_range
(const irange &); template int_range<1>::int_range(
const int_range &); template int_range<1>& int_range
<1>::operator= (const int_range &);
3236DEFINE_INT_RANGE_INSTANCE(2)template int_range<2>::int_range(tree, tree, value_range_kind
); template int_range<2>::int_range(tree_node *, const wide_int
&, const wide_int &, value_range_kind); template int_range
<2>::int_range(tree); template int_range<2>::int_range
(const irange &); template int_range<2>::int_range(
const int_range &); template int_range<2>& int_range
<2>::operator= (const int_range &);
3237DEFINE_INT_RANGE_INSTANCE(3)template int_range<3>::int_range(tree, tree, value_range_kind
); template int_range<3>::int_range(tree_node *, const wide_int
&, const wide_int &, value_range_kind); template int_range
<3>::int_range(tree); template int_range<3>::int_range
(const irange &); template int_range<3>::int_range(
const int_range &); template int_range<3>& int_range
<3>::operator= (const int_range &);
3238DEFINE_INT_RANGE_INSTANCE(255)template int_range<255>::int_range(tree, tree, value_range_kind
); template int_range<255>::int_range(tree_node *, const
wide_int &, const wide_int &, value_range_kind); template
int_range<255>::int_range(tree); template int_range<
255>::int_range(const irange &); template int_range<
255>::int_range(const int_range &); template int_range
<255>& int_range<255>::operator= (const int_range
&);
3239
3240#if CHECKING_P1
3241#include "selftest.h"
3242
3243namespace selftest
3244{
3245#define INT(N)build_int_cst (integer_types[itk_int], (N)) build_int_cst (integer_type_nodeinteger_types[itk_int], (N))
3246#define UINT(N)build_int_cstu (integer_types[itk_unsigned_int], (N)) build_int_cstu (unsigned_type_nodeinteger_types[itk_unsigned_int], (N))
3247#define UINT128(N)build_int_cstu (u128_type, (N)) build_int_cstu (u128_type, (N))
3248#define UCHAR(N)build_int_cstu (integer_types[itk_unsigned_char], (N)) build_int_cstu (unsigned_char_type_nodeinteger_types[itk_unsigned_char], (N))
3249#define SCHAR(N)build_int_cst (integer_types[itk_signed_char], (N)) build_int_cst (signed_char_type_nodeinteger_types[itk_signed_char], (N))
3250
3251static int_range<3>
3252build_range3 (int a, int b, int c, int d, int e, int f)
3253{
3254 int_range<3> i1 (INT (a)build_int_cst (integer_types[itk_int], (a)), INT (b)build_int_cst (integer_types[itk_int], (b)));
3255 int_range<3> i2 (INT (c)build_int_cst (integer_types[itk_int], (c)), INT (d)build_int_cst (integer_types[itk_int], (d)));
3256 int_range<3> i3 (INT (e)build_int_cst (integer_types[itk_int], (e)), INT (f)build_int_cst (integer_types[itk_int], (f)));
3257 i1.union_ (i2);
3258 i1.union_ (i3);
3259 return i1;
3260}
3261
3262static void
3263range_tests_irange3 ()
3264{
3265 typedef int_range<3> int_range3;
3266 int_range3 r0, r1, r2;
2
Calling default constructor for 'int_range<3U>'
5
Returning from default constructor for 'int_range<3U>'
3267 int_range3 i1, i2, i3;
3268
3269 // ([10,20] U [5,8]) U [1,3] ==> [1,3][5,8][10,20].
3270 r0 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3271 r1 = int_range3 (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (8)build_int_cst (integer_types[itk_int], (8)));
3272 r0.union_ (r1);
6
Calling 'irange::union_'
3273 r1 = int_range3 (INT (1)build_int_cst (integer_types[itk_int], (1)), INT (3)build_int_cst (integer_types[itk_int], (3)));
3274 r0.union_ (r1);
3275 ASSERT_TRUE (r0 == build_range3 (1, 3, 5, 8, 10, 20))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == build_range3 (1, 3, 5, 8, 10, 20))"
")"; bool actual_ = ((r0 == build_range3 (1, 3, 5, 8, 10, 20
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3275, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3275, __FUNCTION__))), desc_); } while (0)
;
3276
3277 // [1,3][5,8][10,20] U [-5,0] => [-5,3][5,8][10,20].
3278 r1 = int_range3 (INT (-5)build_int_cst (integer_types[itk_int], (-5)), INT (0)build_int_cst (integer_types[itk_int], (0)));
3279 r0.union_ (r1);
3280 ASSERT_TRUE (r0 == build_range3 (-5, 3, 5, 8, 10, 20))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == build_range3 (-5, 3, 5, 8, 10, 20))"
")"; bool actual_ = ((r0 == build_range3 (-5, 3, 5, 8, 10, 20
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3280, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3280, __FUNCTION__))), desc_); } while (0)
;
3281
3282 // [10,20][30,40] U [50,60] ==> [10,20][30,40][50,60].
3283 r1 = int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60)));
3284 r0 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3285 r0.union_ (int_range3 (INT (30)build_int_cst (integer_types[itk_int], (30)), INT (40)build_int_cst (integer_types[itk_int], (40))));
3286 r0.union_ (r1);
3287 ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == build_range3 (10, 20, 30, 40, 50, 60))"
")"; bool actual_ = ((r0 == build_range3 (10, 20, 30, 40, 50
, 60))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3287, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3287, __FUNCTION__))), desc_); } while (0)
;
3288 // [10,20][30,40][50,60] U [70, 80] ==> [10,20][30,40][50,60][70,80].
3289 r1 = int_range3 (INT (70)build_int_cst (integer_types[itk_int], (70)), INT (80)build_int_cst (integer_types[itk_int], (80)));
3290 r0.union_ (r1);
3291
3292 r2 = build_range3 (10, 20, 30, 40, 50, 60);
3293 r2.union_ (int_range3 (INT (70)build_int_cst (integer_types[itk_int], (70)), INT (80)build_int_cst (integer_types[itk_int], (80))));
3294 ASSERT_TRUE (r0 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r2)" ")"; bool
actual_ = ((r0 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3294, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3294, __FUNCTION__))), desc_); } while (0)
;
3295
3296 // [10,20][30,40][50,60] U [6,35] => [6,40][50,60].
3297 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3298 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (35)build_int_cst (integer_types[itk_int], (35)));
3299 r0.union_ (r1);
3300 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (40)build_int_cst (integer_types[itk_int], (40)));
3301 r1.union_ (int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60))));
3302 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3302, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3302, __FUNCTION__))), desc_); } while (0)
;
3303
3304 // [10,20][30,40][50,60] U [6,60] => [6,60].
3305 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3306 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (60)build_int_cst (integer_types[itk_int], (60)));
3307 r0.union_ (r1);
3308 ASSERT_TRUE (r0 == int_range3 (INT (6), INT (60)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range3 (build_int_cst (integer_types[itk_int], (6)), build_int_cst (integer_types[itk_int], (60))))"
")"; bool actual_ = ((r0 == int_range3 (build_int_cst (integer_types
[itk_int], (6)), build_int_cst (integer_types[itk_int], (60))
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3308, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3308, __FUNCTION__))), desc_); } while (0)
;
3309
3310 // [10,20][30,40][50,60] U [6,70] => [6,70].
3311 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3312 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (70)build_int_cst (integer_types[itk_int], (70)));
3313 r0.union_ (r1);
3314 ASSERT_TRUE (r0 == int_range3 (INT (6), INT (70)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range3 (build_int_cst (integer_types[itk_int], (6)), build_int_cst (integer_types[itk_int], (70))))"
")"; bool actual_ = ((r0 == int_range3 (build_int_cst (integer_types
[itk_int], (6)), build_int_cst (integer_types[itk_int], (70))
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3314, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3314, __FUNCTION__))), desc_); } while (0)
;
3315
3316 // [10,20][30,40][50,60] U [35,70] => [10,20][30,70].
3317 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3318 r1 = int_range3 (INT (35)build_int_cst (integer_types[itk_int], (35)), INT (70)build_int_cst (integer_types[itk_int], (70)));
3319 r0.union_ (r1);
3320 r1 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3321 r1.union_ (int_range3 (INT (30)build_int_cst (integer_types[itk_int], (30)), INT (70)build_int_cst (integer_types[itk_int], (70))));
3322 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3322, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3322, __FUNCTION__))), desc_); } while (0)
;
3323
3324 // [10,20][30,40][50,60] U [15,35] => [10,40][50,60].
3325 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3326 r1 = int_range3 (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (35)build_int_cst (integer_types[itk_int], (35)));
3327 r0.union_ (r1);
3328 r1 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (40)build_int_cst (integer_types[itk_int], (40)));
3329 r1.union_ (int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60))));
3330 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3330, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3330, __FUNCTION__))), desc_); } while (0)
;
3331
3332 // [10,20][30,40][50,60] U [35,35] => [10,20][30,40][50,60].
3333 r0 = build_range3 (10, 20, 30, 40, 50, 60);
3334 r1 = int_range3 (INT (35)build_int_cst (integer_types[itk_int], (35)), INT (35)build_int_cst (integer_types[itk_int], (35)));
3335 r0.union_ (r1);
3336 ASSERT_TRUE (r0 == build_range3 (10, 20, 30, 40, 50, 60))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == build_range3 (10, 20, 30, 40, 50, 60))"
")"; bool actual_ = ((r0 == build_range3 (10, 20, 30, 40, 50
, 60))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3336, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3336, __FUNCTION__))), desc_); } while (0)
;
3337}
3338
3339static void
3340range_tests_int_range_max ()
3341{
3342 int_range_max big;
3343 unsigned int nrange;
3344
3345 // Build a huge multi-range range.
3346 for (nrange = 0; nrange < 50; ++nrange)
3347 {
3348 int_range<1> tmp (INT (nrange*10)build_int_cst (integer_types[itk_int], (nrange*10)), INT (nrange*10 + 5)build_int_cst (integer_types[itk_int], (nrange*10 + 5)));
3349 big.union_ (tmp);
3350 }
3351 ASSERT_TRUE (big.num_pairs () == nrange)do { const char *desc_ = "ASSERT_TRUE (" "(big.num_pairs () == nrange)"
")"; bool actual_ = ((big.num_pairs () == nrange)); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3351, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3351, __FUNCTION__))), desc_); } while (0)
;
3352
3353 // Verify that we can copy it without loosing precision.
3354 int_range_max copy (big);
3355 ASSERT_TRUE (copy.num_pairs () == nrange)do { const char *desc_ = "ASSERT_TRUE (" "(copy.num_pairs () == nrange)"
")"; bool actual_ = ((copy.num_pairs () == nrange)); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3355, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3355, __FUNCTION__))), desc_); } while (0)
;
3356
3357 // Inverting it should produce one more sub-range.
3358 big.invert ();
3359 ASSERT_TRUE (big.num_pairs () == nrange + 1)do { const char *desc_ = "ASSERT_TRUE (" "(big.num_pairs () == nrange + 1)"
")"; bool actual_ = ((big.num_pairs () == nrange + 1)); if (
actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3359, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3359, __FUNCTION__))), desc_); } while (0)
;
3360
3361 int_range<1> tmp (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (37)build_int_cst (integer_types[itk_int], (37)));
3362 big.intersect (tmp);
3363 ASSERT_TRUE (big.num_pairs () == 4)do { const char *desc_ = "ASSERT_TRUE (" "(big.num_pairs () == 4)"
")"; bool actual_ = ((big.num_pairs () == 4)); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3363, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3363, __FUNCTION__))), desc_); } while (0)
;
3364
3365 // Test that [10,10][20,20] does NOT contain 15.
3366 {
3367 int_range_max i1 (build_int_cst (integer_type_nodeinteger_types[itk_int], 10),
3368 build_int_cst (integer_type_nodeinteger_types[itk_int], 10));
3369 int_range_max i2 (build_int_cst (integer_type_nodeinteger_types[itk_int], 20),
3370 build_int_cst (integer_type_nodeinteger_types[itk_int], 20));
3371 i1.union_ (i2);
3372 ASSERT_FALSE (i1.contains_p (build_int_cst (integer_type_node, 15)))do { const char *desc_ = "ASSERT_FALSE (" "(i1.contains_p (build_int_cst (integer_types[itk_int], 15)))"
")"; bool actual_ = ((i1.contains_p (build_int_cst (integer_types
[itk_int], 15)))); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3372, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3372, __FUNCTION__))), desc_); } while (0)
;
3373 }
3374}
3375
3376static void
3377range_tests_legacy ()
3378{
3379 // Test truncating copy to int_range<1>.
3380 int_range<3> big = build_range3 (10, 20, 30, 40, 50, 60);
3381 int_range<1> small = big;
3382 ASSERT_TRUE (small == int_range<1> (INT (10), INT (60)))do { const char *desc_ = "ASSERT_TRUE (" "(small == int_range<1> (build_int_cst (integer_types[itk_int], (10)), build_int_cst (integer_types[itk_int], (60))))"
")"; bool actual_ = ((small == int_range<1> (build_int_cst
(integer_types[itk_int], (10)), build_int_cst (integer_types
[itk_int], (60))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3382, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3382, __FUNCTION__))), desc_); } while (0)
;
3383
3384 // Test truncating copy to int_range<2>.
3385 int_range<2> medium = big;
3386 ASSERT_TRUE (!medium.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(!medium.undefined_p ())"
")"; bool actual_ = ((!medium.undefined_p ())); if (actual_)
::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3386, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3386, __FUNCTION__))), desc_); } while (0)
;
3387
3388 // Test that a truncating copy of [MIN,20][22,40][80,MAX]
3389 // ends up as a conservative anti-range of ~[21,21].
3390 big = int_range<3> (vrp_val_min (integer_type_nodeinteger_types[itk_int]), INT (20)build_int_cst (integer_types[itk_int], (20)));
3391 big.union_ (int_range<1> (INT (22)build_int_cst (integer_types[itk_int], (22)), INT (40)build_int_cst (integer_types[itk_int], (40))));
3392 big.union_ (int_range<1> (INT (80)build_int_cst (integer_types[itk_int], (80)), vrp_val_max (integer_type_nodeinteger_types[itk_int])));
3393 small = big;
3394 ASSERT_TRUE (small == int_range<1> (INT (21), INT (21), VR_ANTI_RANGE))do { const char *desc_ = "ASSERT_TRUE (" "(small == int_range<1> (build_int_cst (integer_types[itk_int], (21)), build_int_cst (integer_types[itk_int], (21)), VR_ANTI_RANGE))"
")"; bool actual_ = ((small == int_range<1> (build_int_cst
(integer_types[itk_int], (21)), build_int_cst (integer_types
[itk_int], (21)), VR_ANTI_RANGE))); if (actual_) ::selftest::
pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3394, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3394, __FUNCTION__))), desc_); } while (0)
;
3395
3396 // Copying a legacy symbolic to an int_range should normalize the
3397 // symbolic at copy time.
3398 {
3399 tree ssa = make_ssa_name (integer_type_nodeinteger_types[itk_int]);
3400 value_range legacy_range (ssa, INT (25)build_int_cst (integer_types[itk_int], (25)));
3401 int_range<2> copy = legacy_range;
3402 ASSERT_TRUE (copy == int_range<2> (vrp_val_min (integer_type_node),do { const char *desc_ = "ASSERT_TRUE (" "(copy == int_range<2> (vrp_val_min (integer_types[itk_int]), build_int_cst (integer_types[itk_int], (25))))"
")"; bool actual_ = ((copy == int_range<2> (vrp_val_min
(integer_types[itk_int]), build_int_cst (integer_types[itk_int
], (25))))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3403, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3403, __FUNCTION__))), desc_); } while (0)
3403 INT (25)))do { const char *desc_ = "ASSERT_TRUE (" "(copy == int_range<2> (vrp_val_min (integer_types[itk_int]), build_int_cst (integer_types[itk_int], (25))))"
")"; bool actual_ = ((copy == int_range<2> (vrp_val_min
(integer_types[itk_int]), build_int_cst (integer_types[itk_int
], (25))))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3403, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3403, __FUNCTION__))), desc_); } while (0)
;
3404
3405 // Test that copying ~[abc_23, abc_23] to a multi-range yields varying.
3406 legacy_range = value_range (ssa, ssa, VR_ANTI_RANGE);
3407 copy = legacy_range;
3408 ASSERT_TRUE (copy.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(copy.varying_p ())"
")"; bool actual_ = ((copy.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3408, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3408, __FUNCTION__))), desc_); } while (0)
;
3409 }
3410
3411 // VARYING of different sizes should not be equal.
3412 tree big_type = build_nonstandard_integer_type (32, 1);
3413 tree small_type = build_nonstandard_integer_type (16, 1);
3414 int_range_max r0 (big_type);
3415 int_range_max r1 (small_type);
3416 ASSERT_TRUE (r0 != r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 != r1)" ")"; bool
actual_ = ((r0 != r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3416, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3416, __FUNCTION__))), desc_); } while (0)
;
3417 value_range vr0 (big_type);
3418 int_range_max vr1 (small_type);
3419 ASSERT_TRUE (vr0 != vr1)do { const char *desc_ = "ASSERT_TRUE (" "(vr0 != vr1)" ")"; bool
actual_ = ((vr0 != vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3419, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3419, __FUNCTION__))), desc_); } while (0)
;
3420}
3421
3422// Simulate -fstrict-enums where the domain of a type is less than the
3423// underlying type.
3424
3425static void
3426range_tests_strict_enum ()
3427{
3428 // The enum can only hold [0, 3].
3429 tree rtype = copy_node (unsigned_type_nodeinteger_types[itk_unsigned_int]);
3430 TYPE_MIN_VALUE (rtype)((tree_check5 ((rtype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3430, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
= build_int_cstu (rtype, 0);
3431 TYPE_MAX_VALUE (rtype)((tree_check5 ((rtype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3431, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
= build_int_cstu (rtype, 3);
3432
3433 // Test that even though vr1 covers the strict enum domain ([0, 3]),
3434 // it does not cover the domain of the underlying type.
3435 int_range<1> vr1 (build_int_cstu (rtype, 0), build_int_cstu (rtype, 1));
3436 int_range<1> vr2 (build_int_cstu (rtype, 2), build_int_cstu (rtype, 3));
3437 vr1.union_ (vr2);
3438 ASSERT_TRUE (vr1 == int_range<1> (build_int_cstu (rtype, 0),do { const char *desc_ = "ASSERT_TRUE (" "(vr1 == int_range<1> (build_int_cstu (rtype, 0), build_int_cstu (rtype, 3)))"
")"; bool actual_ = ((vr1 == int_range<1> (build_int_cstu
(rtype, 0), build_int_cstu (rtype, 3)))); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3439, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3439, __FUNCTION__))), desc_); } while (0)
3439 build_int_cstu (rtype, 3)))do { const char *desc_ = "ASSERT_TRUE (" "(vr1 == int_range<1> (build_int_cstu (rtype, 0), build_int_cstu (rtype, 3)))"
")"; bool actual_ = ((vr1 == int_range<1> (build_int_cstu
(rtype, 0), build_int_cstu (rtype, 3)))); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3439, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3439, __FUNCTION__))), desc_); } while (0)
;
3440 ASSERT_FALSE (vr1.varying_p ())do { const char *desc_ = "ASSERT_FALSE (" "(vr1.varying_p ())"
")"; bool actual_ = ((vr1.varying_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3440, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3440, __FUNCTION__))), desc_); } while (0)
;
3441
3442 // Test that copying to a multi-range does not change things.
3443 int_range<2> ir1 (vr1);
3444 ASSERT_TRUE (ir1 == vr1)do { const char *desc_ = "ASSERT_TRUE (" "(ir1 == vr1)" ")"; bool
actual_ = ((ir1 == vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3444, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3444, __FUNCTION__))), desc_); } while (0)
;
3445 ASSERT_FALSE (ir1.varying_p ())do { const char *desc_ = "ASSERT_FALSE (" "(ir1.varying_p ())"
")"; bool actual_ = ((ir1.varying_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3445, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3445, __FUNCTION__))), desc_); } while (0)
;
3446
3447 // The same test as above, but using TYPE_{MIN,MAX}_VALUE instead of [0,3].
3448 vr1 = int_range<1> (TYPE_MIN_VALUE (rtype)((tree_check5 ((rtype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3448, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
, TYPE_MAX_VALUE (rtype)((tree_check5 ((rtype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3448, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
);
3449 ir1 = vr1;
3450 ASSERT_TRUE (ir1 == vr1)do { const char *desc_ = "ASSERT_TRUE (" "(ir1 == vr1)" ")"; bool
actual_ = ((ir1 == vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3450, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3450, __FUNCTION__))), desc_); } while (0)
;
3451 ASSERT_FALSE (ir1.varying_p ())do { const char *desc_ = "ASSERT_FALSE (" "(ir1.varying_p ())"
")"; bool actual_ = ((ir1.varying_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3451, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3451, __FUNCTION__))), desc_); } while (0)
;
3452}
3453
3454static void
3455range_tests_misc ()
3456{
3457 tree u128_type = build_nonstandard_integer_type (128, /*unsigned=*/1);
3458 int_range<1> i1, i2, i3;
3459 int_range<1> r0, r1, rold;
3460
3461 // Test 1-bit signed integer union.
3462 // [-1,-1] U [0,0] = VARYING.
3463 tree one_bit_type = build_nonstandard_integer_type (1, 0);
3464 tree one_bit_min = vrp_val_min (one_bit_type);
3465 tree one_bit_max = vrp_val_max (one_bit_type);
3466 {
3467 int_range<2> min (one_bit_min, one_bit_min);
3468 int_range<2> max (one_bit_max, one_bit_max);
3469 max.union_ (min);
3470 ASSERT_TRUE (max.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(max.varying_p ())"
")"; bool actual_ = ((max.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3470, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3470, __FUNCTION__))), desc_); } while (0)
;
3471 }
3472 // Test that we can set a range of true+false for a 1-bit signed int.
3473 r0 = range_true_and_false (one_bit_type);
3474
3475 // Test inversion of 1-bit signed integers.
3476 {
3477 int_range<2> min (one_bit_min, one_bit_min);
3478 int_range<2> max (one_bit_max, one_bit_max);
3479 int_range<2> t;
3480 t = min;
3481 t.invert ();
3482 ASSERT_TRUE (t == max)do { const char *desc_ = "ASSERT_TRUE (" "(t == max)" ")"; bool
actual_ = ((t == max)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3482, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3482, __FUNCTION__))), desc_); } while (0)
;
3483 t = max;
3484 t.invert ();
3485 ASSERT_TRUE (t == min)do { const char *desc_ = "ASSERT_TRUE (" "(t == min)" ")"; bool
actual_ = ((t == min)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3485, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3485, __FUNCTION__))), desc_); } while (0)
;
3486 }
3487
3488 // Test that NOT(255) is [0..254] in 8-bit land.
3489 int_range<1> not_255 (UCHAR (255)build_int_cstu (integer_types[itk_unsigned_char], (255)), UCHAR (255)build_int_cstu (integer_types[itk_unsigned_char], (255)), VR_ANTI_RANGE);
3490 ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254)))do { const char *desc_ = "ASSERT_TRUE (" "(not_255 == int_range<1> (build_int_cstu (integer_types[itk_unsigned_char], (0)), build_int_cstu (integer_types[itk_unsigned_char], (254))))"
")"; bool actual_ = ((not_255 == int_range<1> (build_int_cstu
(integer_types[itk_unsigned_char], (0)), build_int_cstu (integer_types
[itk_unsigned_char], (254))))); if (actual_) ::selftest::pass
(((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3490, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3490, __FUNCTION__))), desc_); } while (0)
;
3491
3492 // Test that NOT(0) is [1..255] in 8-bit land.
3493 int_range<1> not_zero = range_nonzero (unsigned_char_type_nodeinteger_types[itk_unsigned_char]);
3494 ASSERT_TRUE (not_zero == int_range<1> (UCHAR (1), UCHAR (255)))do { const char *desc_ = "ASSERT_TRUE (" "(not_zero == int_range<1> (build_int_cstu (integer_types[itk_unsigned_char], (1)), build_int_cstu (integer_types[itk_unsigned_char], (255))))"
")"; bool actual_ = ((not_zero == int_range<1> (build_int_cstu
(integer_types[itk_unsigned_char], (1)), build_int_cstu (integer_types
[itk_unsigned_char], (255))))); if (actual_) ::selftest::pass
(((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3494, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3494, __FUNCTION__))), desc_); } while (0)
;
3495
3496 // Check that [0,127][0x..ffffff80,0x..ffffff]
3497 // => ~[128, 0x..ffffff7f].
3498 r0 = int_range<1> (UINT128 (0)build_int_cstu (u128_type, (0)), UINT128 (127)build_int_cstu (u128_type, (127)));
3499 tree high = build_minus_one_cst (u128_type);
3500 // low = -1 - 127 => 0x..ffffff80.
3501 tree low = fold_build2 (MINUS_EXPR, u128_type, high, UINT128(127))fold_build2_loc (((location_t) 0), MINUS_EXPR, u128_type, high
, build_int_cstu (u128_type, (127)) )
;
3502 r1 = int_range<1> (low, high); // [0x..ffffff80, 0x..ffffffff]
3503 // r0 = [0,127][0x..ffffff80,0x..fffffff].
3504 r0.union_ (r1);
3505 // r1 = [128, 0x..ffffff7f].
3506 r1 = int_range<1> (UINT128(128)build_int_cstu (u128_type, (128)),
3507 fold_build2 (MINUS_EXPR, u128_type,fold_build2_loc (((location_t) 0), MINUS_EXPR, u128_type, build_minus_one_cst
(u128_type), build_int_cstu (u128_type, (128)) )
3508 build_minus_one_cst (u128_type),fold_build2_loc (((location_t) 0), MINUS_EXPR, u128_type, build_minus_one_cst
(u128_type), build_int_cstu (u128_type, (128)) )
3509 UINT128(128))fold_build2_loc (((location_t) 0), MINUS_EXPR, u128_type, build_minus_one_cst
(u128_type), build_int_cstu (u128_type, (128)) )
);
3510 r0.invert ();
3511 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3511, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3511, __FUNCTION__))), desc_); } while (0)
;
3512
3513 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
3514 tree minint = wide_int_to_tree (integer_type_nodeinteger_types[itk_int], r0.lower_bound ());
3515 tree maxint = wide_int_to_tree (integer_type_nodeinteger_types[itk_int], r0.upper_bound ());
3516
3517 r0.set_varying (short_integer_type_nodeinteger_types[itk_short]);
3518
3519 r0.set_varying (unsigned_type_nodeinteger_types[itk_unsigned_int]);
3520 tree maxuint = wide_int_to_tree (unsigned_type_nodeinteger_types[itk_unsigned_int], r0.upper_bound ());
3521
3522 // Check that ~[0,5] => [6,MAX] for unsigned int.
3523 r0 = int_range<1> (UINT (0)build_int_cstu (integer_types[itk_unsigned_int], (0)), UINT (5)build_int_cstu (integer_types[itk_unsigned_int], (5)));
3524 r0.invert ();
3525 ASSERT_TRUE (r0 == int_range<1> (UINT(6), maxuint))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cstu (integer_types[itk_unsigned_int], (6)), maxuint))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cstu
(integer_types[itk_unsigned_int], (6)), maxuint))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3525, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3525, __FUNCTION__))), desc_); } while (0)
;
3526
3527 // Check that ~[10,MAX] => [0,9] for unsigned int.
3528 r0 = int_range<1> (UINT(10)build_int_cstu (integer_types[itk_unsigned_int], (10)), maxuint);
3529 r0.invert ();
3530 ASSERT_TRUE (r0 == int_range<1> (UINT (0), UINT (9)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cstu (integer_types[itk_unsigned_int], (0)), build_int_cstu (integer_types[itk_unsigned_int], (9))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cstu
(integer_types[itk_unsigned_int], (0)), build_int_cstu (integer_types
[itk_unsigned_int], (9))))); if (actual_) ::selftest::pass ((
(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3530, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3530, __FUNCTION__))), desc_); } while (0)
;
3531
3532 // Check that ~[0,5] => [6,MAX] for unsigned 128-bit numbers.
3533 r0 = int_range<1> (UINT128 (0)build_int_cstu (u128_type, (0)), UINT128 (5)build_int_cstu (u128_type, (5)), VR_ANTI_RANGE);
3534 r1 = int_range<1> (UINT128(6)build_int_cstu (u128_type, (6)), build_minus_one_cst (u128_type));
3535 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3535, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3535, __FUNCTION__))), desc_); } while (0)
;
3536
3537 // Check that [~5] is really [-MIN,4][6,MAX].
3538 r0 = int_range<1> (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (5)build_int_cst (integer_types[itk_int], (5)), VR_ANTI_RANGE);
3539 r1 = int_range<1> (minint, INT (4)build_int_cst (integer_types[itk_int], (4)));
3540 r1.union_ (int_range<1> (INT (6)build_int_cst (integer_types[itk_int], (6)), maxint));
3541 ASSERT_FALSE (r1.undefined_p ())do { const char *desc_ = "ASSERT_FALSE (" "(r1.undefined_p ())"
")"; bool actual_ = ((r1.undefined_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3541, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3541, __FUNCTION__))), desc_); } while (0)
;
3542 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3542, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3542, __FUNCTION__))), desc_); } while (0)
;
3543
3544 r1 = int_range<1> (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (5)build_int_cst (integer_types[itk_int], (5)));
3545 int_range<1> r2 (r1);
3546 ASSERT_TRUE (r1 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r1 == r2)" ")"; bool
actual_ = ((r1 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3546, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3546, __FUNCTION__))), desc_); } while (0)
;
3547
3548 r1 = int_range<1> (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (10)build_int_cst (integer_types[itk_int], (10)));
3549
3550 r1 = int_range<1> (integer_type_nodeinteger_types[itk_int],
3551 wi::to_wide (INT (5)build_int_cst (integer_types[itk_int], (5))), wi::to_wide (INT (10)build_int_cst (integer_types[itk_int], (10))));
3552 ASSERT_TRUE (r1.contains_p (INT (7)))do { const char *desc_ = "ASSERT_TRUE (" "(r1.contains_p (build_int_cst (integer_types[itk_int], (7))))"
")"; bool actual_ = ((r1.contains_p (build_int_cst (integer_types
[itk_int], (7))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3552, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3552, __FUNCTION__))), desc_); } while (0)
;
3553
3554 r1 = int_range<1> (SCHAR (0)build_int_cst (integer_types[itk_signed_char], (0)), SCHAR (20)build_int_cst (integer_types[itk_signed_char], (20)));
3555 ASSERT_TRUE (r1.contains_p (SCHAR(15)))do { const char *desc_ = "ASSERT_TRUE (" "(r1.contains_p (build_int_cst (integer_types[itk_signed_char], (15))))"
")"; bool actual_ = ((r1.contains_p (build_int_cst (integer_types
[itk_signed_char], (15))))); if (actual_) ::selftest::pass ((
(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3555, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3555, __FUNCTION__))), desc_); } while (0)
;
3556 ASSERT_FALSE (r1.contains_p (SCHAR(300)))do { const char *desc_ = "ASSERT_FALSE (" "(r1.contains_p (build_int_cst (integer_types[itk_signed_char], (300))))"
")"; bool actual_ = ((r1.contains_p (build_int_cst (integer_types
[itk_signed_char], (300))))); if (actual_) ::selftest::fail (
((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3556, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3556, __FUNCTION__))), desc_); } while (0)
;
3557
3558 // NOT([10,20]) ==> [-MIN,9][21,MAX].
3559 r0 = r1 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3560 r2 = int_range<1> (minint, INT(9)build_int_cst (integer_types[itk_int], (9)));
3561 r2.union_ (int_range<1> (INT(21)build_int_cst (integer_types[itk_int], (21)), maxint));
3562 ASSERT_FALSE (r2.undefined_p ())do { const char *desc_ = "ASSERT_FALSE (" "(r2.undefined_p ())"
")"; bool actual_ = ((r2.undefined_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3562, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3562, __FUNCTION__))), desc_); } while (0)
;
3563 r1.invert ();
3564 ASSERT_TRUE (r1 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r1 == r2)" ")"; bool
actual_ = ((r1 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3564, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3564, __FUNCTION__))), desc_); } while (0)
;
3565 // Test that NOT(NOT(x)) == x.
3566 r2.invert ();
3567 ASSERT_TRUE (r0 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r2)" ")"; bool
actual_ = ((r0 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3567, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3567, __FUNCTION__))), desc_); } while (0)
;
3568
3569 // Test that booleans and their inverse work as expected.
3570 r0 = range_zero (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]);
3571 ASSERT_TRUE (r0 == int_range<1> (build_zero_cst (boolean_type_node),do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_zero_cst (global_trees[TI_BOOLEAN_TYPE]), build_zero_cst (global_trees[TI_BOOLEAN_TYPE])))"
")"; bool actual_ = ((r0 == int_range<1> (build_zero_cst
(global_trees[TI_BOOLEAN_TYPE]), build_zero_cst (global_trees
[TI_BOOLEAN_TYPE])))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3572, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3572, __FUNCTION__))), desc_); } while (0)
3572 build_zero_cst (boolean_type_node)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_zero_cst (global_trees[TI_BOOLEAN_TYPE]), build_zero_cst (global_trees[TI_BOOLEAN_TYPE])))"
")"; bool actual_ = ((r0 == int_range<1> (build_zero_cst
(global_trees[TI_BOOLEAN_TYPE]), build_zero_cst (global_trees
[TI_BOOLEAN_TYPE])))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3572, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3572, __FUNCTION__))), desc_); } while (0)
;
3573 r0.invert ();
3574 ASSERT_TRUE (r0 == int_range<1> (build_one_cst (boolean_type_node),do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_one_cst (global_trees[TI_BOOLEAN_TYPE]), build_one_cst (global_trees[TI_BOOLEAN_TYPE])))"
")"; bool actual_ = ((r0 == int_range<1> (build_one_cst
(global_trees[TI_BOOLEAN_TYPE]), build_one_cst (global_trees
[TI_BOOLEAN_TYPE])))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3575, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3575, __FUNCTION__))), desc_); } while (0)
3575 build_one_cst (boolean_type_node)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_one_cst (global_trees[TI_BOOLEAN_TYPE]), build_one_cst (global_trees[TI_BOOLEAN_TYPE])))"
")"; bool actual_ = ((r0 == int_range<1> (build_one_cst
(global_trees[TI_BOOLEAN_TYPE]), build_one_cst (global_trees
[TI_BOOLEAN_TYPE])))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3575, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3575, __FUNCTION__))), desc_); } while (0)
;
3576
3577 // Make sure NULL and non-NULL of pointer types work, and that
3578 // inverses of them are consistent.
3579 tree voidp = build_pointer_type (void_type_nodeglobal_trees[TI_VOID_TYPE]);
3580 r0 = range_zero (voidp);
3581 r1 = r0;
3582 r0.invert ();
3583 r0.invert ();
3584 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3584, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3584, __FUNCTION__))), desc_); } while (0)
;
3585
3586 // [10,20] U [15, 30] => [10, 30].
3587 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3588 r1 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (30)build_int_cst (integer_types[itk_int], (30)));
3589 r0.union_ (r1);
3590 ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (30)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cst (integer_types[itk_int], (10)), build_int_cst (integer_types[itk_int], (30))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cst
(integer_types[itk_int], (10)), build_int_cst (integer_types
[itk_int], (30))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3590, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3590, __FUNCTION__))), desc_); } while (0)
;
3591
3592 // [15,40] U [] => [15,40].
3593 r0 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (40)build_int_cst (integer_types[itk_int], (40)));
3594 r1.set_undefined ();
3595 r0.union_ (r1);
3596 ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (40)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cst (integer_types[itk_int], (15)), build_int_cst (integer_types[itk_int], (40))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cst
(integer_types[itk_int], (15)), build_int_cst (integer_types
[itk_int], (40))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3596, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3596, __FUNCTION__))), desc_); } while (0)
;
3597
3598 // [10,20] U [10,10] => [10,20].
3599 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3600 r1 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (10)build_int_cst (integer_types[itk_int], (10)));
3601 r0.union_ (r1);
3602 ASSERT_TRUE (r0 == int_range<1> (INT (10), INT (20)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cst (integer_types[itk_int], (10)), build_int_cst (integer_types[itk_int], (20))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cst
(integer_types[itk_int], (10)), build_int_cst (integer_types
[itk_int], (20))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3602, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3602, __FUNCTION__))), desc_); } while (0)
;
3603
3604 // [10,20] U [9,9] => [9,20].
3605 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3606 r1 = int_range<1> (INT (9)build_int_cst (integer_types[itk_int], (9)), INT (9)build_int_cst (integer_types[itk_int], (9)));
3607 r0.union_ (r1);
3608 ASSERT_TRUE (r0 == int_range<1> (INT (9), INT (20)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cst (integer_types[itk_int], (9)), build_int_cst (integer_types[itk_int], (20))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cst
(integer_types[itk_int], (9)), build_int_cst (integer_types[
itk_int], (20))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3608, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3608, __FUNCTION__))), desc_); } while (0)
;
3609
3610 // [10,20] ^ [15,30] => [15,20].
3611 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
3612 r1 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (30)build_int_cst (integer_types[itk_int], (30)));
3613 r0.intersect (r1);
3614 ASSERT_TRUE (r0 == int_range<1> (INT (15), INT (20)))do { const char *desc_ = "ASSERT_TRUE (" "(r0 == int_range<1> (build_int_cst (integer_types[itk_int], (15)), build_int_cst (integer_types[itk_int], (20))))"
")"; bool actual_ = ((r0 == int_range<1> (build_int_cst
(integer_types[itk_int], (15)), build_int_cst (integer_types
[itk_int], (20))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3614, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3614, __FUNCTION__))), desc_); } while (0)
;
3615
3616 // Test the internal sanity of wide_int's wrt HWIs.
3617 ASSERT_TRUE (wi::max_value (TYPE_PRECISION (boolean_type_node),do { const char *desc_ = "ASSERT_TRUE (" "(wi::max_value (((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3617, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3619, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3617, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); } while (0)
3618 TYPE_SIGN (boolean_type_node))do { const char *desc_ = "ASSERT_TRUE (" "(wi::max_value (((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3617, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3619, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3617, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); } while (0)
3619 == wi::uhwi (1, TYPE_PRECISION (boolean_type_node)))do { const char *desc_ = "ASSERT_TRUE (" "(wi::max_value (((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3617, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 3619, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3617, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3618, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3619, __FUNCTION__))), desc_); } while (0)
;
3620
3621 // Test zero_p().
3622 r0 = int_range<1> (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (0)build_int_cst (integer_types[itk_int], (0)));
3623 ASSERT_TRUE (r0.zero_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.zero_p ())" ")"
; bool actual_ = ((r0.zero_p ())); if (actual_) ::selftest::pass
(((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3623, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3623, __FUNCTION__))), desc_); } while (0)
;
3624
3625 // Test nonzero_p().
3626 r0 = int_range<1> (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (0)build_int_cst (integer_types[itk_int], (0)));
3627 r0.invert ();
3628 ASSERT_TRUE (r0.nonzero_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.nonzero_p ())" ")"
; bool actual_ = ((r0.nonzero_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3628, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3628, __FUNCTION__))), desc_); } while (0)
;
3629
3630 // test legacy interaction
3631 // r0 = ~[1,1]
3632 r0 = int_range<1> (UINT (1)build_int_cstu (integer_types[itk_unsigned_int], (1)), UINT (1)build_int_cstu (integer_types[itk_unsigned_int], (1)), VR_ANTI_RANGE);
3633 // r1 = ~[3,3]
3634 r1 = int_range<1> (UINT (3)build_int_cstu (integer_types[itk_unsigned_int], (3)), UINT (3)build_int_cstu (integer_types[itk_unsigned_int], (3)), VR_ANTI_RANGE);
3635
3636 // vv = [0,0][2,2][4, MAX]
3637 int_range<3> vv = r0;
3638 vv.intersect (r1);
3639
3640 ASSERT_TRUE (vv.contains_p (UINT (2)))do { const char *desc_ = "ASSERT_TRUE (" "(vv.contains_p (build_int_cstu (integer_types[itk_unsigned_int], (2))))"
")"; bool actual_ = ((vv.contains_p (build_int_cstu (integer_types
[itk_unsigned_int], (2))))); if (actual_) ::selftest::pass ((
(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3640, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3640, __FUNCTION__))), desc_); } while (0)
;
3641 ASSERT_TRUE (vv.num_pairs () == 3)do { const char *desc_ = "ASSERT_TRUE (" "(vv.num_pairs () == 3)"
")"; bool actual_ = ((vv.num_pairs () == 3)); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3641, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3641, __FUNCTION__))), desc_); } while (0)
;
3642
3643 // create r0 as legacy [1,1]
3644 r0 = int_range<1> (UINT (1)build_int_cstu (integer_types[itk_unsigned_int], (1)), UINT (1)build_int_cstu (integer_types[itk_unsigned_int], (1)));
3645 // And union it with [0,0][2,2][4,MAX] multi range
3646 r0.union_ (vv);
3647 // The result should be [0,2][4,MAX], or ~[3,3] but it must contain 2
3648 ASSERT_TRUE (r0.contains_p (UINT (2)))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (build_int_cstu (integer_types[itk_unsigned_int], (2))))"
")"; bool actual_ = ((r0.contains_p (build_int_cstu (integer_types
[itk_unsigned_int], (2))))); if (actual_) ::selftest::pass ((
(::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3648, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3648, __FUNCTION__))), desc_); } while (0)
;
3649}
3650
3651static void
3652range_tests_nonzero_bits ()
3653{
3654 int_range<2> r0, r1;
3655
3656 // Adding nonzero bits to a varying drops the varying.
3657 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
3658 r0.set_nonzero_bits (255);
3659 ASSERT_TRUE (!r0.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(!r0.varying_p ())"
")"; bool actual_ = ((!r0.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3659, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3659, __FUNCTION__))), desc_); } while (0)
;
3660 // Dropping the nonzero bits brings us back to varying.
3661 r0.set_nonzero_bits (-1);
3662 ASSERT_TRUE (r0.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.varying_p ())" ")"
; bool actual_ = ((r0.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3662, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3662, __FUNCTION__))), desc_); } while (0)
;
3663
3664 // Test contains_p with nonzero bits.
3665 r0.set_zero (integer_type_nodeinteger_types[itk_int]);
3666 ASSERT_TRUE (r0.contains_p (INT (0)))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (build_int_cst (integer_types[itk_int], (0))))"
")"; bool actual_ = ((r0.contains_p (build_int_cst (integer_types
[itk_int], (0))))); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3666, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3666, __FUNCTION__))), desc_); } while (0)
;
3667 ASSERT_FALSE (r0.contains_p (INT (1)))do { const char *desc_ = "ASSERT_FALSE (" "(r0.contains_p (build_int_cst (integer_types[itk_int], (1))))"
")"; bool actual_ = ((r0.contains_p (build_int_cst (integer_types
[itk_int], (1))))); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3667, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3667, __FUNCTION__))), desc_); } while (0)
;
3668 r0.set_nonzero_bits (0xfe);
3669 ASSERT_FALSE (r0.contains_p (INT (0x100)))do { const char *desc_ = "ASSERT_FALSE (" "(r0.contains_p (build_int_cst (integer_types[itk_int], (0x100))))"
")"; bool actual_ = ((r0.contains_p (build_int_cst (integer_types
[itk_int], (0x100))))); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3669, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3669, __FUNCTION__))), desc_); } while (0)
;
3670 ASSERT_FALSE (r0.contains_p (INT (0x3)))do { const char *desc_ = "ASSERT_FALSE (" "(r0.contains_p (build_int_cst (integer_types[itk_int], (0x3))))"
")"; bool actual_ = ((r0.contains_p (build_int_cst (integer_types
[itk_int], (0x3))))); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3670, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3670, __FUNCTION__))), desc_); } while (0)
;
3671
3672 // Union of nonzero bits.
3673 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
3674 r0.set_nonzero_bits (0xf0);
3675 r1.set_varying (integer_type_nodeinteger_types[itk_int]);
3676 r1.set_nonzero_bits (0xf);
3677 r0.union_ (r1);
3678 ASSERT_TRUE (r0.get_nonzero_bits () == 0xff)do { const char *desc_ = "ASSERT_TRUE (" "(r0.get_nonzero_bits () == 0xff)"
")"; bool actual_ = ((r0.get_nonzero_bits () == 0xff)); if (
actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3678, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3678, __FUNCTION__))), desc_); } while (0)
;
3679
3680 // Intersect of nonzero bits.
3681 r0.set (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (255)build_int_cst (integer_types[itk_int], (255)));
3682 r0.set_nonzero_bits (0xfe);
3683 r1.set_varying (integer_type_nodeinteger_types[itk_int]);
3684 r1.set_nonzero_bits (0xf0);
3685 r0.intersect (r1);
3686 ASSERT_TRUE (r0.get_nonzero_bits () == 0xf0)do { const char *desc_ = "ASSERT_TRUE (" "(r0.get_nonzero_bits () == 0xf0)"
")"; bool actual_ = ((r0.get_nonzero_bits () == 0xf0)); if (
actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3686, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3686, __FUNCTION__))), desc_); } while (0)
;
3687
3688 // Intersect where the mask of nonzero bits is implicit from the range.
3689 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
3690 r1.set (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (255)build_int_cst (integer_types[itk_int], (255)));
3691 r0.intersect (r1);
3692 ASSERT_TRUE (r0.get_nonzero_bits () == 0xff)do { const char *desc_ = "ASSERT_TRUE (" "(r0.get_nonzero_bits () == 0xff)"
")"; bool actual_ = ((r0.get_nonzero_bits () == 0xff)); if (
actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3692, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3692, __FUNCTION__))), desc_); } while (0)
;
3693
3694 // The union of a mask of 0xff..ffff00 with a mask of 0xff spans the
3695 // entire domain, and makes the range a varying.
3696 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
3697 wide_int x = wi::shwi (0xff, TYPE_PRECISION (integer_type_node)((tree_class_check ((integer_types[itk_int]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3697, __FUNCTION__))->type_common.precision)
);
3698 x = wi::bit_not (x);
3699 r0.set_nonzero_bits (x); // 0xff..ff00
3700 r1.set_varying (integer_type_nodeinteger_types[itk_int]);
3701 r1.set_nonzero_bits (0xff);
3702 r0.union_ (r1);
3703 ASSERT_TRUE (r0.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.varying_p ())" ")"
; bool actual_ = ((r0.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3703, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3703, __FUNCTION__))), desc_); } while (0)
;
3704
3705 // Test that setting a nonzero bit of 1 does not pessimize the range.
3706 r0.set_zero (integer_type_nodeinteger_types[itk_int]);
3707 r0.set_nonzero_bits (1);
3708 ASSERT_TRUE (r0.zero_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.zero_p ())" ")"
; bool actual_ = ((r0.zero_p ())); if (actual_) ::selftest::pass
(((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3708, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3708, __FUNCTION__))), desc_); } while (0)
;
3709}
3710
3711// Build an frange from string endpoints.
3712
3713static inline frange
3714frange_float (const char *lb, const char *ub, tree type = float_type_nodeglobal_trees[TI_FLOAT_TYPE])
3715{
3716 REAL_VALUE_TYPEstruct real_value min, max;
3717 gcc_assert (real_from_string (&min, lb) == 0)((void)(!(real_from_string (&min, lb) == 0) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3717, __FUNCTION__), 0 : 0))
;
3718 gcc_assert (real_from_string (&max, ub) == 0)((void)(!(real_from_string (&max, ub) == 0) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3718, __FUNCTION__), 0 : 0))
;
3719 return frange (type, min, max);
3720}
3721
3722static void
3723range_tests_nan ()
3724{
3725 frange r0, r1;
3726 REAL_VALUE_TYPEstruct real_value q, r;
3727 bool signbit;
3728
3729 // Equal ranges but with differing NAN bits are not equal.
3730 if (HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3731 {
3732 r1 = frange_float ("10", "12");
3733 r0 = r1;
3734 ASSERT_EQ (r0, r1)do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(r1)" ")"
; if (((r0)) == ((r1))) ::selftest::pass ((((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3734, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3734, __FUNCTION__)))), desc_); } while (0)
;
3735 r0.clear_nan ();
3736 ASSERT_NE (r0, r1)do { const char *desc_ = "ASSERT_NE (" "r0" ", " "r1" ")"; if
((r0) != (r1)) ::selftest::pass ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3736, __FUNCTION__)), desc_); else ::selftest::fail ((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3736, __FUNCTION__)), desc_); } while (0)
;
3737 r0.update_nan ();
3738 ASSERT_EQ (r0, r1)do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(r1)" ")"
; if (((r0)) == ((r1))) ::selftest::pass ((((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3738, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3738, __FUNCTION__)))), desc_); } while (0)
;
3739
3740 // [10, 20] NAN ^ [30, 40] NAN = NAN.
3741 r0 = frange_float ("10", "20");
3742 r1 = frange_float ("30", "40");
3743 r0.intersect (r1);
3744 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3744, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3744, __FUNCTION__))), desc_); } while (0)
;
3745
3746 // [3,5] U [5,10] NAN = ... NAN
3747 r0 = frange_float ("3", "5");
3748 r0.clear_nan ();
3749 r1 = frange_float ("5", "10");
3750 r0.union_ (r1);
3751 ASSERT_TRUE (r0.maybe_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.maybe_isnan ())"
")"; bool actual_ = ((r0.maybe_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3751, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3751, __FUNCTION__))), desc_); } while (0)
;
3752 }
3753
3754 // NAN ranges are not equal to each other.
3755 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3756 r1 = r0;
3757 ASSERT_FALSE (r0 == r1)do { const char *desc_ = "ASSERT_FALSE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3757, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3757, __FUNCTION__))), desc_); } while (0)
;
3758 ASSERT_FALSE (r0 == r0)do { const char *desc_ = "ASSERT_FALSE (" "(r0 == r0)" ")"; bool
actual_ = ((r0 == r0)); if (actual_) ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3758, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3758, __FUNCTION__))), desc_); } while (0)
;
3759 ASSERT_TRUE (r0 != r0)do { const char *desc_ = "ASSERT_TRUE (" "(r0 != r0)" ")"; bool
actual_ = ((r0 != r0)); if (actual_) ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3759, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3759, __FUNCTION__))), desc_); } while (0)
;
3760
3761 // [5,6] U NAN = [5,6] NAN.
3762 r0 = frange_float ("5", "6");
3763 r0.clear_nan ();
3764 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3765 r0.union_ (r1);
3766 real_from_string (&q, "5");
3767 real_from_string (&r, "6");
3768 ASSERT_TRUE (real_identical (&q, &r0.lower_bound ()))do { const char *desc_ = "ASSERT_TRUE (" "(real_identical (&q, &r0.lower_bound ()))"
")"; bool actual_ = ((real_identical (&q, &r0.lower_bound
()))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3768, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3768, __FUNCTION__))), desc_); } while (0)
;
3769 ASSERT_TRUE (real_identical (&r, &r0.upper_bound ()))do { const char *desc_ = "ASSERT_TRUE (" "(real_identical (&r, &r0.upper_bound ()))"
")"; bool actual_ = ((real_identical (&r, &r0.upper_bound
()))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3769, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3769, __FUNCTION__))), desc_); } while (0)
;
3770 ASSERT_TRUE (r0.maybe_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.maybe_isnan ())"
")"; bool actual_ = ((r0.maybe_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3770, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3770, __FUNCTION__))), desc_); } while (0)
;
3771
3772 // NAN U NAN = NAN
3773 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3774 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3775 r0.union_ (r1);
3776 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3776, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3776, __FUNCTION__))), desc_); } while (0)
;
3777
3778 // [INF, INF] NAN ^ NAN = NAN
3779 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3780 r1 = frange_float ("+Inf", "+Inf");
3781 if (!HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3782 r1.update_nan ();
3783 r0.intersect (r1);
3784 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3784, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3784, __FUNCTION__))), desc_); } while (0)
;
3785
3786 // NAN ^ NAN = NAN
3787 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3788 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3789 r0.intersect (r1);
3790 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3790, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3790, __FUNCTION__))), desc_); } while (0)
;
3791
3792 // +NAN ^ -NAN = UNDEFINED
3793 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE], false);
3794 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE], true);
3795 r0.intersect (r1);
3796 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3796, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3796, __FUNCTION__))), desc_); } while (0)
;
3797
3798 // VARYING ^ NAN = NAN.
3799 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3800 r1.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3801 r0.intersect (r1);
3802 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3802, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3802, __FUNCTION__))), desc_); } while (0)
;
3803
3804 // [3,4] ^ NAN = UNDEFINED.
3805 r0 = frange_float ("3", "4");
3806 r0.clear_nan ();
3807 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3808 r0.intersect (r1);
3809 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3809, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3809, __FUNCTION__))), desc_); } while (0)
;
3810
3811 // [-3, 5] ^ NAN = UNDEFINED
3812 r0 = frange_float ("-3", "5");
3813 r0.clear_nan ();
3814 r1.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3815 r0.intersect (r1);
3816 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3816, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3816, __FUNCTION__))), desc_); } while (0)
;
3817
3818 // Setting the NAN bit to yes does not make us a known NAN.
3819 r0.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3820 r0.update_nan ();
3821 ASSERT_FALSE (r0.known_isnan ())do { const char *desc_ = "ASSERT_FALSE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3821, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3821, __FUNCTION__))), desc_); } while (0)
;
3822
3823 // NAN is in a VARYING.
3824 r0.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3825 real_nan (&r, "", 1, TYPE_MODE (float_type_node)((((enum tree_code) ((tree_class_check ((global_trees[TI_FLOAT_TYPE
]), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3825, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(global_trees[TI_FLOAT_TYPE]) : (global_trees[TI_FLOAT_TYPE]
)->type_common.mode)
);
3826 tree nan = build_real (float_type_nodeglobal_trees[TI_FLOAT_TYPE], r);
3827 ASSERT_TRUE (r0.contains_p (nan))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (nan))"
")"; bool actual_ = ((r0.contains_p (nan))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3827, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3827, __FUNCTION__))), desc_); } while (0)
;
3828
3829 // -NAN is in a VARYING.
3830 r0.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3831 q = real_value_negate (&r);
3832 tree neg_nan = build_real (float_type_nodeglobal_trees[TI_FLOAT_TYPE], q);
3833 ASSERT_TRUE (r0.contains_p (neg_nan))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (neg_nan))"
")"; bool actual_ = ((r0.contains_p (neg_nan))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3833, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3833, __FUNCTION__))), desc_); } while (0)
;
3834
3835 // Clearing the NAN on a [] NAN is the empty set.
3836 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3837 r0.clear_nan ();
3838 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3838, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3838, __FUNCTION__))), desc_); } while (0)
;
3839
3840 // [10,20] NAN ^ [21,25] NAN = [NAN]
3841 r0 = frange_float ("10", "20");
3842 r0.update_nan ();
3843 r1 = frange_float ("21", "25");
3844 r1.update_nan ();
3845 r0.intersect (r1);
3846 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3846, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3846, __FUNCTION__))), desc_); } while (0)
;
3847
3848 // NAN U [5,6] should be [5,6] +-NAN.
3849 r0.set_nan (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3850 r1 = frange_float ("5", "6");
3851 r1.clear_nan ();
3852 r0.union_ (r1);
3853 real_from_string (&q, "5");
3854 real_from_string (&r, "6");
3855 ASSERT_TRUE (real_identical (&q, &r0.lower_bound ()))do { const char *desc_ = "ASSERT_TRUE (" "(real_identical (&q, &r0.lower_bound ()))"
")"; bool actual_ = ((real_identical (&q, &r0.lower_bound
()))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3855, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3855, __FUNCTION__))), desc_); } while (0)
;
3856 ASSERT_TRUE (real_identical (&r, &r0.upper_bound ()))do { const char *desc_ = "ASSERT_TRUE (" "(real_identical (&r, &r0.upper_bound ()))"
")"; bool actual_ = ((real_identical (&r, &r0.upper_bound
()))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3856, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3856, __FUNCTION__))), desc_); } while (0)
;
3857 ASSERT_TRUE (!r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(!r0.signbit_p (signbit))"
")"; bool actual_ = ((!r0.signbit_p (signbit))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3857, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3857, __FUNCTION__))), desc_); } while (0)
;
3858 ASSERT_TRUE (r0.maybe_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.maybe_isnan ())"
")"; bool actual_ = ((r0.maybe_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3858, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3858, __FUNCTION__))), desc_); } while (0)
;
3859}
3860
3861static void
3862range_tests_signed_zeros ()
3863{
3864 tree zero = build_zero_cst (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3865 tree neg_zero = fold_build1 (NEGATE_EXPR, float_type_node, zero)fold_build1_loc (((location_t) 0), NEGATE_EXPR, global_trees[
TI_FLOAT_TYPE], zero )
;
3866 frange r0, r1;
3867 bool signbit;
3868
3869 // [0,0] contains [0,0] but not [-0,-0] and vice versa.
3870 r0 = frange (zero, zero);
3871 r1 = frange (neg_zero, neg_zero);
3872 ASSERT_TRUE (r0.contains_p (zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (zero))"
")"; bool actual_ = ((r0.contains_p (zero))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3872, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3872, __FUNCTION__))), desc_); } while (0)
;
3873 ASSERT_TRUE (!r0.contains_p (neg_zero))do { const char *desc_ = "ASSERT_TRUE (" "(!r0.contains_p (neg_zero))"
")"; bool actual_ = ((!r0.contains_p (neg_zero))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3873, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3873, __FUNCTION__))), desc_); } while (0)
;
3874 ASSERT_TRUE (r1.contains_p (neg_zero))do { const char *desc_ = "ASSERT_TRUE (" "(r1.contains_p (neg_zero))"
")"; bool actual_ = ((r1.contains_p (neg_zero))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3874, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3874, __FUNCTION__))), desc_); } while (0)
;
3875 ASSERT_TRUE (!r1.contains_p (zero))do { const char *desc_ = "ASSERT_TRUE (" "(!r1.contains_p (zero))"
")"; bool actual_ = ((!r1.contains_p (zero))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3875, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3875, __FUNCTION__))), desc_); } while (0)
;
3876
3877 // Test contains_p() when we know the sign of the zero.
3878 r0 = frange (zero, zero);
3879 ASSERT_TRUE (r0.contains_p (zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (zero))"
")"; bool actual_ = ((r0.contains_p (zero))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3879, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3879, __FUNCTION__))), desc_); } while (0)
;
3880 ASSERT_FALSE (r0.contains_p (neg_zero))do { const char *desc_ = "ASSERT_FALSE (" "(r0.contains_p (neg_zero))"
")"; bool actual_ = ((r0.contains_p (neg_zero))); if (actual_
) ::selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3880, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3880, __FUNCTION__))), desc_); } while (0)
;
3881 r0 = frange (neg_zero, neg_zero);
3882 ASSERT_TRUE (r0.contains_p (neg_zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (neg_zero))"
")"; bool actual_ = ((r0.contains_p (neg_zero))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3882, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3882, __FUNCTION__))), desc_); } while (0)
;
3883 ASSERT_FALSE (r0.contains_p (zero))do { const char *desc_ = "ASSERT_FALSE (" "(r0.contains_p (zero))"
")"; bool actual_ = ((r0.contains_p (zero))); if (actual_) ::
selftest::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3883, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3883, __FUNCTION__))), desc_); } while (0)
;
3884
3885 r0 = frange (neg_zero, zero);
3886 ASSERT_TRUE (r0.contains_p (neg_zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (neg_zero))"
")"; bool actual_ = ((r0.contains_p (neg_zero))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3886, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3886, __FUNCTION__))), desc_); } while (0)
;
3887 ASSERT_TRUE (r0.contains_p (zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (zero))"
")"; bool actual_ = ((r0.contains_p (zero))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3887, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3887, __FUNCTION__))), desc_); } while (0)
;
3888
3889 r0 = frange_float ("-3", "5");
3890 ASSERT_TRUE (r0.contains_p (neg_zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (neg_zero))"
")"; bool actual_ = ((r0.contains_p (neg_zero))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3890, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3890, __FUNCTION__))), desc_); } while (0)
;
3891 ASSERT_TRUE (r0.contains_p (zero))do { const char *desc_ = "ASSERT_TRUE (" "(r0.contains_p (zero))"
")"; bool actual_ = ((r0.contains_p (zero))); if (actual_) ::
selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3891, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3891, __FUNCTION__))), desc_); } while (0)
;
3892
3893 // The intersection of zeros that differ in sign is a NAN (or
3894 // undefined if not honoring NANs).
3895 r0 = frange (neg_zero, neg_zero);
3896 r1 = frange (zero, zero);
3897 r0.intersect (r1);
3898 if (HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3899 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3899, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3899, __FUNCTION__))), desc_); } while (0)
;
3900 else
3901 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3901, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3901, __FUNCTION__))), desc_); } while (0)
;
3902
3903 // The union of zeros that differ in sign is a zero with unknown sign.
3904 r0 = frange (zero, zero);
3905 r1 = frange (neg_zero, neg_zero);
3906 r0.union_ (r1);
3907 ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(r0.zero_p () && !r0.signbit_p (signbit))"
")"; bool actual_ = ((r0.zero_p () && !r0.signbit_p (
signbit))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3907, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3907, __FUNCTION__))), desc_); } while (0)
;
3908
3909 // [-0, +0] has an unknown sign.
3910 r0 = frange (neg_zero, zero);
3911 ASSERT_TRUE (r0.zero_p () && !r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(r0.zero_p () && !r0.signbit_p (signbit))"
")"; bool actual_ = ((r0.zero_p () && !r0.signbit_p (
signbit))); if (actual_) ::selftest::pass (((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3911, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3911, __FUNCTION__))), desc_); } while (0)
;
3912
3913 // [-0, +0] ^ [0, 0] is [0, 0]
3914 r0 = frange (neg_zero, zero);
3915 r1 = frange (zero, zero);
3916 r0.intersect (r1);
3917 ASSERT_TRUE (r0.zero_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.zero_p ())" ")"
; bool actual_ = ((r0.zero_p ())); if (actual_) ::selftest::pass
(((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3917, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3917, __FUNCTION__))), desc_); } while (0)
;
3918
3919 r0 = frange_float ("+0", "5");
3920 r0.clear_nan ();
3921 ASSERT_TRUE (r0.signbit_p (signbit) && !signbit)do { const char *desc_ = "ASSERT_TRUE (" "(r0.signbit_p (signbit) && !signbit)"
")"; bool actual_ = ((r0.signbit_p (signbit) && !signbit
)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3921, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3921, __FUNCTION__))), desc_); } while (0)
;
3922
3923 r0 = frange_float ("-0", "5");
3924 r0.clear_nan ();
3925 ASSERT_TRUE (!r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(!r0.signbit_p (signbit))"
")"; bool actual_ = ((!r0.signbit_p (signbit))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3925, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3925, __FUNCTION__))), desc_); } while (0)
;
3926
3927 r0 = frange_float ("-0", "10");
3928 r1 = frange_float ("0", "5");
3929 r0.intersect (r1);
3930 ASSERT_TRUE (real_iszero (&r0.lower_bound (), false))do { const char *desc_ = "ASSERT_TRUE (" "(real_iszero (&r0.lower_bound (), false))"
")"; bool actual_ = ((real_iszero (&r0.lower_bound (), false
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3930, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3930, __FUNCTION__))), desc_); } while (0)
;
3931
3932 r0 = frange_float ("-0", "5");
3933 r1 = frange_float ("0", "5");
3934 r0.union_ (r1);
3935 ASSERT_TRUE (real_iszero (&r0.lower_bound (), true))do { const char *desc_ = "ASSERT_TRUE (" "(real_iszero (&r0.lower_bound (), true))"
")"; bool actual_ = ((real_iszero (&r0.lower_bound (), true
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3935, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3935, __FUNCTION__))), desc_); } while (0)
;
3936
3937 r0 = frange_float ("-5", "-0");
3938 r0.update_nan ();
3939 r1 = frange_float ("0", "0");
3940 r1.update_nan ();
3941 r0.intersect (r1);
3942 if (HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3943 ASSERT_TRUE (r0.known_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.known_isnan ())"
")"; bool actual_ = ((r0.known_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3943, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3943, __FUNCTION__))), desc_); } while (0)
;
3944 else
3945 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3945, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3945, __FUNCTION__))), desc_); } while (0)
;
3946
3947 r0.set_nonnegative (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3948 if (HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3949 ASSERT_TRUE (r0.maybe_isnan ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.maybe_isnan ())"
")"; bool actual_ = ((r0.maybe_isnan ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3949, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3949, __FUNCTION__))), desc_); } while (0)
;
3950
3951 // Numbers containing zero should have an unknown SIGNBIT.
3952 r0 = frange_float ("0", "10");
3953 r0.clear_nan ();
3954 ASSERT_TRUE (r0.signbit_p (signbit) && !signbit)do { const char *desc_ = "ASSERT_TRUE (" "(r0.signbit_p (signbit) && !signbit)"
")"; bool actual_ = ((r0.signbit_p (signbit) && !signbit
)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3954, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3954, __FUNCTION__))), desc_); } while (0)
;
3955}
3956
3957static void
3958range_tests_signbit ()
3959{
3960 frange r0, r1;
3961 bool signbit;
3962
3963 // Negative numbers should have the SIGNBIT set.
3964 r0 = frange_float ("-5", "-1");
3965 r0.clear_nan ();
3966 ASSERT_TRUE (r0.signbit_p (signbit) && signbit)do { const char *desc_ = "ASSERT_TRUE (" "(r0.signbit_p (signbit) && signbit)"
")"; bool actual_ = ((r0.signbit_p (signbit) && signbit
)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3966, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3966, __FUNCTION__))), desc_); } while (0)
;
3967 // Positive numbers should have the SIGNBIT clear.
3968 r0 = frange_float ("1", "10");
3969 r0.clear_nan ();
3970 ASSERT_TRUE (r0.signbit_p (signbit) && !signbit)do { const char *desc_ = "ASSERT_TRUE (" "(r0.signbit_p (signbit) && !signbit)"
")"; bool actual_ = ((r0.signbit_p (signbit) && !signbit
)); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3970, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3970, __FUNCTION__))), desc_); } while (0)
;
3971 // Numbers spanning both positive and negative should have an
3972 // unknown SIGNBIT.
3973 r0 = frange_float ("-10", "10");
3974 r0.clear_nan ();
3975 ASSERT_TRUE (!r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(!r0.signbit_p (signbit))"
")"; bool actual_ = ((!r0.signbit_p (signbit))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3975, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3975, __FUNCTION__))), desc_); } while (0)
;
3976 r0.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
3977 ASSERT_TRUE (!r0.signbit_p (signbit))do { const char *desc_ = "ASSERT_TRUE (" "(!r0.signbit_p (signbit))"
")"; bool actual_ = ((!r0.signbit_p (signbit))); if (actual_
) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3977, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3977, __FUNCTION__))), desc_); } while (0)
;
3978}
3979
3980static void
3981range_tests_floats ()
3982{
3983 frange r0, r1;
3984
3985 if (HONOR_NANS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3986 range_tests_nan ();
3987 range_tests_signbit ();
3988
3989 if (HONOR_SIGNED_ZEROS (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
3990 range_tests_signed_zeros ();
3991
3992 // A range of [-INF,+INF] is actually VARYING if no other properties
3993 // are set.
3994 r0 = frange_float ("-Inf", "+Inf");
3995 ASSERT_TRUE (r0.varying_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.varying_p ())" ")"
; bool actual_ = ((r0.varying_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3995, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 3995, __FUNCTION__))), desc_); } while (0)
;
3996 // ...unless it has some special property...
3997 if (HONOR_NANS (r0.type ()))
3998 {
3999 r0.clear_nan ();
4000 ASSERT_FALSE (r0.varying_p ())do { const char *desc_ = "ASSERT_FALSE (" "(r0.varying_p ())"
")"; bool actual_ = ((r0.varying_p ())); if (actual_) ::selftest
::fail (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4000, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4000, __FUNCTION__))), desc_); } while (0)
;
4001 }
4002
4003 // For most architectures, where float and double are different
4004 // sizes, having the same endpoints does not necessarily mean the
4005 // ranges are equal.
4006 if (!types_compatible_p (float_type_nodeglobal_trees[TI_FLOAT_TYPE], double_type_nodeglobal_trees[TI_DOUBLE_TYPE]))
4007 {
4008 r0 = frange_float ("3.0", "3.0", float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
4009 r1 = frange_float ("3.0", "3.0", double_type_nodeglobal_trees[TI_DOUBLE_TYPE]);
4010 ASSERT_NE (r0, r1)do { const char *desc_ = "ASSERT_NE (" "r0" ", " "r1" ")"; if
((r0) != (r1)) ::selftest::pass ((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4010, __FUNCTION__)), desc_); else ::selftest::fail ((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4010, __FUNCTION__)), desc_); } while (0)
;
4011 }
4012
4013 // [3,5] U [10,12] = [3,12].
4014 r0 = frange_float ("3", "5");
4015 r1 = frange_float ("10", "12");
4016 r0.union_ (r1);
4017 ASSERT_EQ (r0, frange_float ("3", "12"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"3\", \"12\"))"
")"; if (((r0)) == ((frange_float ("3", "12")))) ::selftest::
pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4017, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4017, __FUNCTION__)))), desc_); } while (0)
;
4018
4019 // [5,10] U [4,8] = [4,10]
4020 r0 = frange_float ("5", "10");
4021 r1 = frange_float ("4", "8");
4022 r0.union_ (r1);
4023 ASSERT_EQ (r0, frange_float ("4", "10"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"4\", \"10\"))"
")"; if (((r0)) == ((frange_float ("4", "10")))) ::selftest::
pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4023, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4023, __FUNCTION__)))), desc_); } while (0)
;
4024
4025 // [3,5] U [4,10] = [3,10]
4026 r0 = frange_float ("3", "5");
4027 r1 = frange_float ("4", "10");
4028 r0.union_ (r1);
4029 ASSERT_EQ (r0, frange_float ("3", "10"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"3\", \"10\"))"
")"; if (((r0)) == ((frange_float ("3", "10")))) ::selftest::
pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4029, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4029, __FUNCTION__)))), desc_); } while (0)
;
4030
4031 // [4,10] U [5,11] = [4,11]
4032 r0 = frange_float ("4", "10");
4033 r1 = frange_float ("5", "11");
4034 r0.union_ (r1);
4035 ASSERT_EQ (r0, frange_float ("4", "11"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"4\", \"11\"))"
")"; if (((r0)) == ((frange_float ("4", "11")))) ::selftest::
pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4035, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4035, __FUNCTION__)))), desc_); } while (0)
;
4036
4037 // [3,12] ^ [10,12] = [10,12].
4038 r0 = frange_float ("3", "12");
4039 r1 = frange_float ("10", "12");
4040 r0.intersect (r1);
4041 ASSERT_EQ (r0, frange_float ("10", "12"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"10\", \"12\"))"
")"; if (((r0)) == ((frange_float ("10", "12")))) ::selftest
::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4041, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4041, __FUNCTION__)))), desc_); } while (0)
;
4042
4043 // [10,12] ^ [11,11] = [11,11]
4044 r0 = frange_float ("10", "12");
4045 r1 = frange_float ("11", "11");
4046 r0.intersect (r1);
4047 ASSERT_EQ (r0, frange_float ("11", "11"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"11\", \"11\"))"
")"; if (((r0)) == ((frange_float ("11", "11")))) ::selftest
::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4047, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4047, __FUNCTION__)))), desc_); } while (0)
;
4048
4049 // [10,20] ^ [5,15] = [10,15]
4050 r0 = frange_float ("10", "20");
4051 r1 = frange_float ("5", "15");
4052 r0.intersect (r1);
4053 ASSERT_EQ (r0, frange_float ("10", "15"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"10\", \"15\"))"
")"; if (((r0)) == ((frange_float ("10", "15")))) ::selftest
::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4053, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4053, __FUNCTION__)))), desc_); } while (0)
;
4054
4055 // [10,20] ^ [15,25] = [15,20]
4056 r0 = frange_float ("10", "20");
4057 r1 = frange_float ("15", "25");
4058 r0.intersect (r1);
4059 ASSERT_EQ (r0, frange_float ("15", "20"))do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(frange_float (\"15\", \"20\"))"
")"; if (((r0)) == ((frange_float ("15", "20")))) ::selftest
::pass ((((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4059, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4059, __FUNCTION__)))), desc_); } while (0)
;
4060
4061 // [10,20] ^ [21,25] = []
4062 r0 = frange_float ("10", "20");
4063 r0.clear_nan ();
4064 r1 = frange_float ("21", "25");
4065 r1.clear_nan ();
4066 r0.intersect (r1);
4067 ASSERT_TRUE (r0.undefined_p ())do { const char *desc_ = "ASSERT_TRUE (" "(r0.undefined_p ())"
")"; bool actual_ = ((r0.undefined_p ())); if (actual_) ::selftest
::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4067, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4067, __FUNCTION__))), desc_); } while (0)
;
4068
4069 if (HONOR_INFINITIES (float_type_nodeglobal_trees[TI_FLOAT_TYPE]))
4070 {
4071 // Make sure [-Inf, -Inf] doesn't get normalized.
4072 r0 = frange_float ("-Inf", "-Inf");
4073 ASSERT_TRUE (real_isinf (&r0.lower_bound (), true))do { const char *desc_ = "ASSERT_TRUE (" "(real_isinf (&r0.lower_bound (), true))"
")"; bool actual_ = ((real_isinf (&r0.lower_bound (), true
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4073, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4073, __FUNCTION__))), desc_); } while (0)
;
4074 ASSERT_TRUE (real_isinf (&r0.upper_bound (), true))do { const char *desc_ = "ASSERT_TRUE (" "(real_isinf (&r0.upper_bound (), true))"
")"; bool actual_ = ((real_isinf (&r0.upper_bound (), true
))); if (actual_) ::selftest::pass (((::selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4074, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4074, __FUNCTION__))), desc_); } while (0)
;
4075 }
4076
4077 // Test that reading back a global range yields the same result as
4078 // what we wrote into it.
4079 tree ssa = make_temp_ssa_name (float_type_nodeglobal_trees[TI_FLOAT_TYPE], NULLnullptr, "blah");
4080 r0.set_varying (float_type_nodeglobal_trees[TI_FLOAT_TYPE]);
4081 r0.clear_nan ();
4082 set_range_info (ssa, r0);
4083 get_global_range_query ()->range_of_expr (r1, ssa);
4084 ASSERT_EQ (r0, r1)do { const char *desc_ = "ASSERT_EQ (" "(r0)" ", " "(r1)" ")"
; if (((r0)) == ((r1))) ::selftest::pass ((((::selftest::location
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4084, __FUNCTION__)))), desc_); else ::selftest::fail ((((::
selftest::location ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 4084, __FUNCTION__)))), desc_); } while (0)
;
4085}
4086
4087// Run floating range tests for various combinations of NAN and INF
4088// support.
4089
4090static void
4091range_tests_floats_various ()
4092{
4093 int save_finite_math_only = flag_finite_math_onlyglobal_options.x_flag_finite_math_only;
4094
4095 // Test -ffinite-math-only.
4096 flag_finite_math_onlyglobal_options.x_flag_finite_math_only = 1;
4097 range_tests_floats ();
4098 // Test -fno-finite-math-only.
4099 flag_finite_math_onlyglobal_options.x_flag_finite_math_only = 0;
4100 range_tests_floats ();
4101
4102 flag_finite_math_onlyglobal_options.x_flag_finite_math_only = save_finite_math_only;
4103}
4104
4105void
4106range_tests ()
4107{
4108 range_tests_legacy ();
4109 range_tests_irange3 ();
1
Calling 'range_tests_irange3'
4110 range_tests_int_range_max ();
4111 range_tests_strict_enum ();
4112 range_tests_nonzero_bits ();
4113 range_tests_floats_various ();
4114 range_tests_misc ();
4115}
4116
4117} // namespace selftest
4118
4119#endif // CHECKING_P

/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h

1/* Support routines for value ranges.
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew Macleod <amacleod@redhat.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GCC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#ifndef GCC_VALUE_RANGE_H
23#define GCC_VALUE_RANGE_H
24
25class irange;
26
27// Types of value ranges.
28enum value_range_kind
29{
30 /* Empty range. */
31 VR_UNDEFINED,
32 /* Range spans the entire domain. */
33 VR_VARYING,
34 /* Range is [MIN, MAX]. */
35 VR_RANGE,
36 /* Range is ~[MIN, MAX]. */
37 VR_ANTI_RANGE,
38 /* Range is a NAN. */
39 VR_NAN,
40 /* Range is a nice guy. */
41 VR_LAST
42};
43
44// Discriminator between different vrange types.
45
46enum value_range_discriminator
47{
48 // Range holds an integer or pointer.
49 VR_IRANGE,
50 // Floating point range.
51 VR_FRANGE,
52 // Range holds an unsupported type.
53 VR_UNKNOWN
54};
55
56// Abstract class for ranges of any of the supported types.
57//
58// To query what types ranger and the entire ecosystem can support,
59// use Value_Range::supports_type_p(tree type). This is a static
60// method available independently of any vrange object.
61//
62// To query what a given vrange variant can support, use:
63// irange::supports_p ()
64// frange::supports_p ()
65// etc
66//
67// To query what a range object can support, use:
68// void foo (vrange &v, irange &i, frange &f)
69// {
70// if (v.supports_type_p (type)) ...
71// if (i.supports_type_p (type)) ...
72// if (f.supports_type_p (type)) ...
73// }
74
75class vrange
76{
77 template <typename T> friend bool is_a (vrange &);
78 friend class Value_Range;
79public:
80 virtual void accept (const class vrange_visitor &v) const = 0;
81 virtual void set (tree, tree, value_range_kind = VR_RANGE);
82 virtual tree type () const;
83 virtual bool supports_type_p (const_tree type) const;
84 virtual void set_varying (tree type);
85 virtual void set_undefined ();
86 virtual bool union_ (const vrange &);
87 virtual bool intersect (const vrange &);
88 virtual bool singleton_p (tree *result = NULLnullptr) const;
89 virtual bool contains_p (tree cst) const;
90 virtual bool zero_p () const;
91 virtual bool nonzero_p () const;
92 virtual void set_nonzero (tree type);
93 virtual void set_zero (tree type);
94 virtual void set_nonnegative (tree type);
95 virtual bool fits_p (const vrange &r) const;
96
97 bool varying_p () const;
98 bool undefined_p () const;
99 vrange& operator= (const vrange &);
100 bool operator== (const vrange &) const;
101 bool operator!= (const vrange &r) const { return !(*this == r); }
102 void dump (FILE *) const;
103
104 enum value_range_kind kind () const; // DEPRECATED
105
106protected:
107 ENUM_BITFIELD(value_range_kind)enum value_range_kind m_kind : 8;
108 ENUM_BITFIELD(value_range_discriminator)enum value_range_discriminator m_discriminator : 4;
109};
110
111// An integer range without any storage.
112
113class GTY((user)) irange : public vrange
114{
115 friend class vrange_allocator;
116 friend class irange_storage_slot; // For legacy_mode_p checks.
117public:
118 // In-place setters.
119 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
120 void set (tree type, const wide_int_ref &, const wide_int_ref &,
121 value_range_kind = VR_RANGE);
122 virtual void set_nonzero (tree type) override;
123 virtual void set_zero (tree type) override;
124 virtual void set_nonnegative (tree type) override;
125 virtual void set_varying (tree type) override;
126 virtual void set_undefined () override;
127
128 // Range types.
129 static bool supports_p (const_tree type);
130 virtual bool supports_type_p (const_tree type) const override;
131 virtual tree type () const override;
132
133 // Iteration over sub-ranges.
134 unsigned num_pairs () const;
135 wide_int lower_bound (unsigned = 0) const;
136 wide_int upper_bound (unsigned) const;
137 wide_int upper_bound () const;
138
139 // Predicates.
140 virtual bool zero_p () const override;
141 virtual bool nonzero_p () const override;
142 virtual bool singleton_p (tree *result = NULLnullptr) const override;
143 virtual bool contains_p (tree cst) const override;
144
145 // In-place operators.
146 virtual bool union_ (const vrange &) override;
147 virtual bool intersect (const vrange &) override;
148 void invert ();
149
150 // Operator overloads.
151 irange& operator= (const irange &);
152 bool operator== (const irange &) const;
153 bool operator!= (const irange &r) const { return !(*this == r); }
154
155 // Misc methods.
156 virtual bool fits_p (const vrange &r) const override;
157 virtual void accept (const vrange_visitor &v) const override;
158
159 // Nonzero masks.
160 wide_int get_nonzero_bits () const;
161 void set_nonzero_bits (const wide_int_ref &bits);
162
163 // Deprecated legacy public methods.
164 tree min () const; // DEPRECATED
165 tree max () const; // DEPRECATED
166 bool symbolic_p () const; // DEPRECATED
167 bool constant_p () const; // DEPRECATED
168 void normalize_symbolics (); // DEPRECATED
169 void normalize_addresses (); // DEPRECATED
170 bool may_contain_p (tree) const; // DEPRECATED
171 bool legacy_verbose_union_ (const class irange *); // DEPRECATED
172 bool legacy_verbose_intersect (const irange *); // DEPRECATED
173
174protected:
175 irange (tree *, unsigned);
176 // potential promotion to public?
177 tree tree_lower_bound (unsigned = 0) const;
178 tree tree_upper_bound (unsigned) const;
179 tree tree_upper_bound () const;
180
181 // In-place operators.
182 bool irange_union (const irange &);
183 bool irange_intersect (const irange &);
184 void irange_set (tree, tree);
185 void irange_set_anti_range (tree, tree);
186 bool irange_contains_p (const irange &) const;
187 bool irange_single_pair_union (const irange &r);
188
189 void normalize_kind ();
190
191 bool legacy_mode_p () const;
192 bool legacy_equal_p (const irange &) const;
193 void legacy_union (irange *, const irange *);
194 void legacy_intersect (irange *, const irange *);
195 void verify_range ();
196 wide_int legacy_lower_bound (unsigned = 0) const;
197 wide_int legacy_upper_bound (unsigned) const;
198 int value_inside_range (tree) const;
199 bool maybe_anti_range () const;
200 void copy_to_legacy (const irange &);
201 void copy_legacy_to_multi_range (const irange &);
202
203private:
204 friend void gt_ggc_mx (irange *);
205 friend void gt_pch_nx (irange *);
206 friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
207
208 void irange_set_1bit_anti_range (tree, tree);
209 bool varying_compatible_p () const;
210 bool intersect_nonzero_bits (const irange &r);
211 bool union_nonzero_bits (const irange &r);
212 wide_int get_nonzero_bits_from_range () const;
213 bool set_range_from_nonzero_bits ();
214
215 bool intersect (const wide_int& lb, const wide_int& ub);
216 unsigned char m_num_ranges;
217 unsigned char m_max_ranges;
218 tree m_nonzero_mask;
219 tree *m_base;
220};
221
222// Here we describe an irange with N pairs of ranges. The storage for
223// the pairs is embedded in the class as an array.
224
225template<unsigned N>
226class GTY((user)) int_range : public irange
227{
228public:
229 int_range ();
230 int_range (tree, tree, value_range_kind = VR_RANGE);
231 int_range (tree type, const wide_int &, const wide_int &,
232 value_range_kind = VR_RANGE);
233 int_range (tree type);
234 int_range (const int_range &);
235 int_range (const irange &);
236 virtual ~int_range () = default;
237 int_range& operator= (const int_range &);
238private:
239 template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
240 template <unsigned X> friend void gt_pch_nx (int_range<X> *);
241 template <unsigned X> friend void gt_pch_nx (int_range<X> *,
242 gt_pointer_operator, void *);
243
244 // ?? These stubs are for ipa-prop.cc which use a value_range in a
245 // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
246 // instead of picking up the gt_ggc_mx (T *) version.
247 friend void gt_ggc_mx (int_range<1> *&);
248 friend void gt_pch_nx (int_range<1> *&);
249
250 tree m_ranges[N*2];
251};
252
253// Unsupported temporaries may be created by ranger before it's known
254// they're unsupported, or by vr_values::get_value_range.
255
256class unsupported_range : public vrange
257{
258public:
259 unsupported_range ()
260 {
261 m_discriminator = VR_UNKNOWN;
262 set_undefined ();
263 }
264 virtual void set_undefined () final override
265 {
266 m_kind = VR_UNDEFINED;
267 }
268 virtual void accept (const vrange_visitor &v) const override;
269};
270
271// The NAN state as an opaque object. The default constructor is +-NAN.
272
273class nan_state
274{
275public:
276 nan_state ();
277 nan_state (bool pos_nan, bool neg_nan);
278 bool neg_p () const;
279 bool pos_p () const;
280private:
281 bool m_pos_nan;
282 bool m_neg_nan;
283};
284
285// Default constructor initializing the object to +-NAN.
286
287inline
288nan_state::nan_state ()
289{
290 m_pos_nan = true;
291 m_neg_nan = true;
292}
293
294// Constructor initializing the object to +NAN if POS_NAN is set, -NAN
295// if NEG_NAN is set, or +-NAN if both are set. Otherwise POS_NAN and
296// NEG_NAN are clear, and the object cannot be a NAN.
297
298inline
299nan_state::nan_state (bool pos_nan, bool neg_nan)
300{
301 m_pos_nan = pos_nan;
302 m_neg_nan = neg_nan;
303}
304
305// Return if +NAN is possible.
306
307inline bool
308nan_state::pos_p () const
309{
310 return m_pos_nan;
311}
312
313// Return if -NAN is possible.
314
315inline bool
316nan_state::neg_p () const
317{
318 return m_neg_nan;
319}
320
321// A floating point range.
322//
323// The representation is a type with a couple of endpoints, unioned
324// with the set of { -NAN, +Nan }.
325
326class frange : public vrange
327{
328 friend class frange_storage_slot;
329 friend class vrange_printer;
330public:
331 frange ();
332 frange (const frange &);
333 frange (tree, tree, value_range_kind = VR_RANGE);
334 frange (tree type);
335 frange (tree type, const REAL_VALUE_TYPEstruct real_value &min, const REAL_VALUE_TYPEstruct real_value &max,
336 value_range_kind = VR_RANGE);
337 static bool supports_p (const_tree type)
338 {
339 // ?? Decimal floats can have multiple representations for the
340 // same number. Supporting them may be as simple as just
341 // disabling them in singleton_p. No clue.
342 return SCALAR_FLOAT_TYPE_P (type)(((enum tree_code) (type)->base.code) == REAL_TYPE) && !DECIMAL_FLOAT_TYPE_P (type)((((enum tree_code) (type)->base.code) == REAL_TYPE) &&
(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 342, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_DECIMAL_FLOAT
))
;
343 }
344 virtual tree type () const override;
345 virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
346 void set (tree type, const REAL_VALUE_TYPEstruct real_value &, const REAL_VALUE_TYPEstruct real_value &,
347 value_range_kind = VR_RANGE);
348 void set (tree type, const REAL_VALUE_TYPEstruct real_value &, const REAL_VALUE_TYPEstruct real_value &,
349 const nan_state &, value_range_kind = VR_RANGE);
350 void set_nan (tree type);
351 void set_nan (tree type, bool sign);
352 virtual void set_varying (tree type) override;
353 virtual void set_undefined () override;
354 virtual bool union_ (const vrange &) override;
355 virtual bool intersect (const vrange &) override;
356 virtual bool contains_p (tree) const override;
357 virtual bool singleton_p (tree *result = NULLnullptr) const override;
358 virtual bool supports_type_p (const_tree type) const override;
359 virtual void accept (const vrange_visitor &v) const override;
360 virtual bool zero_p () const override;
361 virtual bool nonzero_p () const override;
362 virtual void set_nonzero (tree type) override;
363 virtual void set_zero (tree type) override;
364 virtual void set_nonnegative (tree type) override;
365 frange& operator= (const frange &);
366 bool operator== (const frange &) const;
367 bool operator!= (const frange &r) const { return !(*this == r); }
368 const REAL_VALUE_TYPEstruct real_value &lower_bound () const;
369 const REAL_VALUE_TYPEstruct real_value &upper_bound () const;
370 nan_state get_nan_state () const;
371 void update_nan ();
372 void update_nan (bool sign);
373 void update_nan (tree) = delete; // Disallow silent conversion to bool.
374 void update_nan (const nan_state &);
375 void clear_nan ();
376
377 // fpclassify like API
378 bool known_isfinite () const;
379 bool known_isnan () const;
380 bool known_isinf () const;
381 bool maybe_isnan () const;
382 bool maybe_isnan (bool sign) const;
383 bool maybe_isinf () const;
384 bool signbit_p (bool &signbit) const;
385 bool nan_signbit_p (bool &signbit) const;
386private:
387 void verify_range ();
388 bool normalize_kind ();
389 bool union_nans (const frange &);
390 bool intersect_nans (const frange &);
391 bool combine_zeros (const frange &, bool union_p);
392 void flush_denormals_to_zero ();
393
394 tree m_type;
395 REAL_VALUE_TYPEstruct real_value m_min;
396 REAL_VALUE_TYPEstruct real_value m_max;
397 bool m_pos_nan;
398 bool m_neg_nan;
399};
400
401inline const REAL_VALUE_TYPEstruct real_value &
402frange::lower_bound () const
403{
404 gcc_checking_assert (!undefined_p () && !known_isnan ())((void)(!(!undefined_p () && !known_isnan ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 404, __FUNCTION__), 0 : 0))
;
405 return m_min;
406}
407
408inline const REAL_VALUE_TYPEstruct real_value &
409frange::upper_bound () const
410{
411 gcc_checking_assert (!undefined_p () && !known_isnan ())((void)(!(!undefined_p () && !known_isnan ()) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 411, __FUNCTION__), 0 : 0))
;
412 return m_max;
413}
414
415// Return the NAN state.
416
417inline nan_state
418frange::get_nan_state () const
419{
420 return nan_state (m_pos_nan, m_neg_nan);
421}
422
423// is_a<> and as_a<> implementation for vrange.
424
425// Anything we haven't specialized is a hard fail.
426template <typename T>
427inline bool
428is_a (vrange &)
429{
430 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 430, __FUNCTION__))
;
431 return false;
432}
433
434template <typename T>
435inline bool
436is_a (const vrange &v)
437{
438 // Reuse is_a <vrange> to implement the const version.
439 const T &derived = static_cast<const T &> (v);
440 return is_a <T> (const_cast<T &> (derived));
441}
442
443template <typename T>
444inline T &
445as_a (vrange &v)
446{
447 gcc_checking_assert (is_a <T> (v))((void)(!(is_a <T> (v)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 447, __FUNCTION__), 0 : 0))
;
448 return static_cast <T &> (v);
449}
450
451template <typename T>
452inline const T &
453as_a (const vrange &v)
454{
455 gcc_checking_assert (is_a <T> (v))((void)(!(is_a <T> (v)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 455, __FUNCTION__), 0 : 0))
;
456 return static_cast <const T &> (v);
457}
458
459// Specializations for the different range types.
460
461template <>
462inline bool
463is_a <irange> (vrange &v)
464{
465 return v.m_discriminator == VR_IRANGE;
466}
467
468template <>
469inline bool
470is_a <frange> (vrange &v)
471{
472 return v.m_discriminator == VR_FRANGE;
473}
474
475class vrange_visitor
476{
477public:
478 virtual void visit (const irange &) const { }
479 virtual void visit (const frange &) const { }
480 virtual void visit (const unsupported_range &) const { }
481};
482
483// This is a special int_range<1> with only one pair, plus
484// VR_ANTI_RANGE magic to describe slightly more than can be described
485// in one pair. It is described in the code as a "legacy range" (as
486// opposed to multi-ranges which have multiple sub-ranges). It is
487// provided for backward compatibility with code that has not been
488// converted to multi-range irange's.
489//
490// There are copy operators to seamlessly copy to/fro multi-ranges.
491typedef int_range<1> value_range;
492
493// This is an "infinite" precision irange for use in temporary
494// calculations.
495typedef int_range<255> int_range_max;
496
497// This is an "infinite" precision range object for use in temporary
498// calculations for any of the handled types. The object can be
499// transparently used as a vrange.
500
501class Value_Range
502{
503public:
504 Value_Range ();
505 Value_Range (const vrange &r);
506 Value_Range (tree type);
507 Value_Range (const Value_Range &);
508 void set_type (tree type);
509 vrange& operator= (const vrange &);
510 bool operator== (const Value_Range &r) const;
511 bool operator!= (const Value_Range &r) const;
512 operator vrange &();
513 operator const vrange &() const;
514 void dump (FILE *) const;
515 static bool supports_type_p (const_tree type);
516
517 // Convenience methods for vrange compatibility.
518 void set (tree min, tree max, value_range_kind kind = VR_RANGE)
519 { return m_vrange->set (min, max, kind); }
520 tree type () { return m_vrange->type (); }
521 enum value_range_kind kind () { return m_vrange->kind (); }
522 bool varying_p () const { return m_vrange->varying_p (); }
523 bool undefined_p () const { return m_vrange->undefined_p (); }
524 void set_varying (tree type) { m_vrange->set_varying (type); }
525 void set_undefined () { m_vrange->set_undefined (); }
526 bool union_ (const vrange &r) { return m_vrange->union_ (r); }
527 bool intersect (const vrange &r) { return m_vrange->intersect (r); }
528 bool singleton_p (tree *result = NULLnullptr) const
529 { return m_vrange->singleton_p (result); }
530 bool zero_p () const { return m_vrange->zero_p (); }
531 wide_int lower_bound () const; // For irange/prange comparability.
532 wide_int upper_bound () const; // For irange/prange comparability.
533 void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
534private:
535 void init (tree type);
536 unsupported_range m_unsupported;
537 vrange *m_vrange;
538 int_range_max m_irange;
539 frange m_frange;
540};
541
542inline
543Value_Range::Value_Range ()
544{
545 m_vrange = &m_unsupported;
546}
547
548// Copy constructor from a vrange.
549
550inline
551Value_Range::Value_Range (const vrange &r)
552{
553 *this = r;
554}
555
556// Copy constructor from a TYPE. The range of the temporary is set to
557// UNDEFINED.
558
559inline
560Value_Range::Value_Range (tree type)
561{
562 init (type);
563}
564
565inline
566Value_Range::Value_Range (const Value_Range &r)
567{
568 m_vrange = r.m_vrange;
569}
570
571// Initialize object so it is possible to store temporaries of TYPE
572// into it.
573
574inline void
575Value_Range::init (tree type)
576{
577 gcc_checking_assert (TYPE_P (type))((void)(!((tree_code_type_tmpl <0>::tree_code_type[(int
) (((enum tree_code) (type)->base.code))] == tcc_type)) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 577, __FUNCTION__), 0 : 0))
;
578
579 if (irange::supports_p (type))
580 m_vrange = &m_irange;
581 else if (frange::supports_p (type))
582 m_vrange = &m_frange;
583 else
584 m_vrange = &m_unsupported;
585}
586
587// Set the temporary to allow storing temporaries of TYPE. The range
588// of the temporary is set to UNDEFINED.
589
590inline void
591Value_Range::set_type (tree type)
592{
593 init (type);
594 m_vrange->set_undefined ();
595}
596
597// Assignment operator for temporaries. Copying incompatible types is
598// allowed.
599
600inline vrange &
601Value_Range::operator= (const vrange &r)
602{
603 if (is_a <irange> (r))
604 {
605 m_irange = as_a <irange> (r);
606 m_vrange = &m_irange;
607 }
608 else if (is_a <frange> (r))
609 {
610 m_frange = as_a <frange> (r);
611 m_vrange = &m_frange;
612 }
613 else
614 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 614, __FUNCTION__))
;
615
616 return *m_vrange;
617}
618
619inline bool
620Value_Range::operator== (const Value_Range &r) const
621{
622 return *m_vrange == *r.m_vrange;
623}
624
625inline bool
626Value_Range::operator!= (const Value_Range &r) const
627{
628 return *m_vrange != *r.m_vrange;
629}
630
631inline
632Value_Range::operator vrange &()
633{
634 return *m_vrange;
635}
636
637inline
638Value_Range::operator const vrange &() const
639{
640 return *m_vrange;
641}
642
643// Return TRUE if TYPE is supported by the vrange infrastructure.
644
645inline bool
646Value_Range::supports_type_p (const_tree type)
647{
648 return irange::supports_p (type) || frange::supports_p (type);
649}
650
651// Returns true for an old-school value_range as described above.
652inline bool
653irange::legacy_mode_p () const
654{
655 return m_max_ranges == 1;
656}
657
658extern bool range_has_numeric_bounds_p (const irange *);
659extern bool ranges_from_anti_range (const value_range *,
660 value_range *, value_range *);
661extern void dump_value_range (FILE *, const vrange *);
662extern bool vrp_val_is_min (const_tree);
663extern bool vrp_val_is_max (const_tree);
664extern bool vrp_operand_equal_p (const_tree, const_tree);
665inline REAL_VALUE_TYPEstruct real_value frange_val_min (const_tree type);
666inline REAL_VALUE_TYPEstruct real_value frange_val_max (const_tree type);
667
668inline value_range_kind
669vrange::kind () const
670{
671 return m_kind;
672}
673
674// Number of sub-ranges in a range.
675
676inline unsigned
677irange::num_pairs () const
678{
679 if (m_kind == VR_ANTI_RANGE)
680 return constant_p () ? 2 : 1;
681 else
682 return m_num_ranges;
683}
684
685inline tree
686irange::type () const
687{
688 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 688, __FUNCTION__), 0 : 0))
;
17
Assuming field 'm_num_ranges' is > 0
18
'?' condition is false
689 return TREE_TYPE (m_base[0])((contains_struct_check ((m_base[0]), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 689, __FUNCTION__))->typed.type)
;
19
1st function call argument is an uninitialized value
690}
691
692// Return the lower bound of a sub-range expressed as a tree. PAIR is
693// the sub-range in question.
694
695inline tree
696irange::tree_lower_bound (unsigned pair) const
697{
698 return m_base[pair * 2];
699}
700
701// Return the upper bound of a sub-range expressed as a tree. PAIR is
702// the sub-range in question.
703
704inline tree
705irange::tree_upper_bound (unsigned pair) const
706{
707 return m_base[pair * 2 + 1];
708}
709
710// Return the highest bound of a range expressed as a tree.
711
712inline tree
713irange::tree_upper_bound () const
714{
715 gcc_checking_assert (m_num_ranges)((void)(!(m_num_ranges) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 715, __FUNCTION__), 0 : 0))
;
716 return tree_upper_bound (m_num_ranges - 1);
717}
718
719inline tree
720irange::min () const
721{
722 return tree_lower_bound (0);
723}
724
725inline tree
726irange::max () const
727{
728 if (m_num_ranges)
729 return tree_upper_bound ();
730 else
731 return NULLnullptr;
732}
733
734inline bool
735irange::varying_compatible_p () const
736{
737 if (m_num_ranges != 1)
738 return false;
739
740 tree l = m_base[0];
741 tree u = m_base[1];
742 tree t = TREE_TYPE (l)((contains_struct_check ((l), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 742, __FUNCTION__))->typed.type)
;
743
744 if (m_kind == VR_VARYING && t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
745 return true;
746
747 unsigned prec = TYPE_PRECISION (t)((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 747, __FUNCTION__))->type_common.precision)
;
748 signop sign = TYPE_SIGN (t)((signop) ((tree_class_check ((t), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 748, __FUNCTION__))->base.u.bits.unsigned_flag))
;
749 if (INTEGRAL_TYPE_P (t)(((enum tree_code) (t)->base.code) == ENUMERAL_TYPE || ((enum
tree_code) (t)->base.code) == BOOLEAN_TYPE || ((enum tree_code
) (t)->base.code) == INTEGER_TYPE)
)
750 return (wi::to_wide (l) == wi::min_value (prec, sign)
751 && wi::to_wide (u) == wi::max_value (prec, sign)
752 && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1));
753 if (POINTER_TYPE_P (t)(((enum tree_code) (t)->base.code) == POINTER_TYPE || ((enum
tree_code) (t)->base.code) == REFERENCE_TYPE)
)
754 return (wi::to_wide (l) == 0
755 && wi::to_wide (u) == wi::max_value (prec, sign)
756 && (!m_nonzero_mask || wi::to_wide (m_nonzero_mask) == -1));
757 return true;
758}
759
760inline void
761irange::set (tree type, const wide_int_ref &min, const wide_int_ref &max,
762 value_range_kind kind)
763{
764 set (wide_int_to_tree (type, min), wide_int_to_tree (type, max), kind);
765}
766
767inline bool
768vrange::varying_p () const
769{
770 return m_kind == VR_VARYING;
771}
772
773inline bool
774vrange::undefined_p () const
775{
776 return m_kind == VR_UNDEFINED;
777}
778
779inline bool
780irange::zero_p () const
781{
782 return (m_kind == VR_RANGE && m_num_ranges == 1
783 && integer_zerop (tree_lower_bound (0))
784 && integer_zerop (tree_upper_bound (0)));
785}
786
787inline bool
788irange::nonzero_p () const
789{
790 if (undefined_p ())
791 return false;
792
793 tree zero = build_zero_cst (type ());
794 return *this == int_range<1> (zero, zero, VR_ANTI_RANGE);
795}
796
797inline bool
798irange::supports_p (const_tree type)
799{
800 return INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum
tree_code) (type)->base.code) == INTEGER_TYPE)
|| POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
;
801}
802
803inline bool
804range_includes_zero_p (const irange *vr)
805{
806 if (vr->undefined_p ())
807 return false;
808
809 if (vr->varying_p ())
810 return true;
811
812 return vr->may_contain_p (build_zero_cst (vr->type ()));
813}
814
815inline void
816gt_ggc_mx (irange *x)
817{
818 for (unsigned i = 0; i < x->m_num_ranges; ++i)
819 {
820 gt_ggc_mx (x->m_base[i * 2]);
821 gt_ggc_mx (x->m_base[i * 2 + 1]);
822 }
823 if (x->m_nonzero_mask)
824 gt_ggc_mx (x->m_nonzero_mask);
825}
826
827inline void
828gt_pch_nx (irange *x)
829{
830 for (unsigned i = 0; i < x->m_num_ranges; ++i)
831 {
832 gt_pch_nx (x->m_base[i * 2]);
833 gt_pch_nx (x->m_base[i * 2 + 1]);
834 }
835 if (x->m_nonzero_mask)
836 gt_pch_nx (x->m_nonzero_mask);
837}
838
839inline void
840gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
841{
842 for (unsigned i = 0; i < x->m_num_ranges; ++i)
843 {
844 op (&x->m_base[i * 2], NULLnullptr, cookie);
845 op (&x->m_base[i * 2 + 1], NULLnullptr, cookie);
846 }
847 if (x->m_nonzero_mask)
848 op (&x->m_nonzero_mask, NULLnullptr, cookie);
849}
850
851template<unsigned N>
852inline void
853gt_ggc_mx (int_range<N> *x)
854{
855 gt_ggc_mx ((irange *) x);
856}
857
858template<unsigned N>
859inline void
860gt_pch_nx (int_range<N> *x)
861{
862 gt_pch_nx ((irange *) x);
863}
864
865template<unsigned N>
866inline void
867gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
868{
869 gt_pch_nx ((irange *) x, op, cookie);
870}
871
872// Constructors for irange
873
874inline
875irange::irange (tree *base, unsigned nranges)
876{
877 m_discriminator = VR_IRANGE;
878 m_base = base;
879 m_max_ranges = nranges;
880 set_undefined ();
881}
882
883// Constructors for int_range<>.
884
885template<unsigned N>
886inline
887int_range<N>::int_range ()
888 : irange (m_ranges, N)
3
Calling constructor for 'irange'
4
Returning from constructor for 'irange'
889{
890}
891
892template<unsigned N>
893int_range<N>::int_range (const int_range &other)
894 : irange (m_ranges, N)
895{
896 irange::operator= (other);
897}
898
899template<unsigned N>
900int_range<N>::int_range (tree min, tree max, value_range_kind kind)
901 : irange (m_ranges, N)
902{
903 irange::set (min, max, kind);
904}
905
906template<unsigned N>
907int_range<N>::int_range (tree type)
908 : irange (m_ranges, N)
909{
910 set_varying (type);
911}
912
913template<unsigned N>
914int_range<N>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
915 value_range_kind kind)
916 : irange (m_ranges, N)
917{
918 tree min = wide_int_to_tree (type, wmin);
919 tree max = wide_int_to_tree (type, wmax);
920 set (min, max, kind);
921}
922
923template<unsigned N>
924int_range<N>::int_range (const irange &other)
925 : irange (m_ranges, N)
926{
927 irange::operator= (other);
928}
929
930template<unsigned N>
931int_range<N>&
932int_range<N>::operator= (const int_range &src)
933{
934 irange::operator= (src);
935 return *this;
936}
937
938inline void
939irange::set_undefined ()
940{
941 m_kind = VR_UNDEFINED;
942 m_num_ranges = 0;
943 m_nonzero_mask = NULLnullptr;
944}
945
946inline void
947irange::set_varying (tree type)
948{
949 m_kind = VR_VARYING;
950 m_num_ranges = 1;
951 m_nonzero_mask = NULLnullptr;
952
953 if (INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum
tree_code) (type)->base.code) == INTEGER_TYPE)
)
954 {
955 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
956 // min_value and max_value.
957 wide_int min = wi::min_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 957, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 957, __FUNCTION__))->base.u.bits.unsigned_flag))
);
958 wide_int max = wi::max_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 958, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 958, __FUNCTION__))->base.u.bits.unsigned_flag))
);
959 if (wi::eq_p (max, wi::to_wide (TYPE_MAX_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 959, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
))
960 && wi::eq_p (min, wi::to_wide (TYPE_MIN_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 960, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
)))
961 {
962 m_base[0] = TYPE_MIN_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 962, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
;
963 m_base[1] = TYPE_MAX_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 963, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
;
964 }
965 else
966 {
967 m_base[0] = wide_int_to_tree (type, min);
968 m_base[1] = wide_int_to_tree (type, max);
969 }
970 }
971 else if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
972 {
973 m_base[0] = build_int_cst (type, 0);
974 m_base[1] = build_int_cst (type, -1);
975 }
976 else
977 m_base[0] = m_base[1] = error_mark_nodeglobal_trees[TI_ERROR_MARK];
978}
979
980// Return the lower bound of a sub-range. PAIR is the sub-range in
981// question.
982
983inline wide_int
984irange::lower_bound (unsigned pair) const
985{
986 if (legacy_mode_p ())
987 return legacy_lower_bound (pair);
988 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 988, __FUNCTION__), 0 : 0))
;
989 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 989, __FUNCTION__), 0 : 0))
;
990 return wi::to_wide (tree_lower_bound (pair));
991}
992
993// Return the upper bound of a sub-range. PAIR is the sub-range in
994// question.
995
996inline wide_int
997irange::upper_bound (unsigned pair) const
998{
999 if (legacy_mode_p ())
1000 return legacy_upper_bound (pair);
1001 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1001, __FUNCTION__), 0 : 0))
;
1002 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1002, __FUNCTION__), 0 : 0))
;
1003 return wi::to_wide (tree_upper_bound (pair));
1004}
1005
1006// Return the highest bound of a range.
1007
1008inline wide_int
1009irange::upper_bound () const
1010{
1011 unsigned pairs = num_pairs ();
1012 gcc_checking_assert (pairs > 0)((void)(!(pairs > 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1012, __FUNCTION__), 0 : 0))
;
1013 return upper_bound (pairs - 1);
1014}
1015
1016inline bool
1017irange::union_ (const vrange &r)
1018{
1019 dump_flags_t m_flags = dump_flags;
1020 dump_flags &= ~TDF_DETAILS;
1021 bool ret = irange::legacy_verbose_union_ (&as_a <irange> (r));
7
Calling 'irange::legacy_verbose_union_'
1022 dump_flags = m_flags;
1023 return ret;
1024}
1025
1026inline bool
1027irange::intersect (const vrange &r)
1028{
1029 dump_flags_t m_flags = dump_flags;
1030 dump_flags &= ~TDF_DETAILS;
1031 bool ret = irange::legacy_verbose_intersect (&as_a <irange> (r));
1032 dump_flags = m_flags;
1033 return ret;
1034}
1035
1036// Set value range VR to a nonzero range of type TYPE.
1037
1038inline void
1039irange::set_nonzero (tree type)
1040{
1041 tree zero = build_int_cst (type, 0);
1042 if (legacy_mode_p ())
1043 set (zero, zero, VR_ANTI_RANGE);
1044 else
1045 irange_set_anti_range (zero, zero);
1046}
1047
1048// Set value range VR to a ZERO range of type TYPE.
1049
1050inline void
1051irange::set_zero (tree type)
1052{
1053 tree z = build_int_cst (type, 0);
1054 if (legacy_mode_p ())
1055 set (z, z);
1056 else
1057 irange_set (z, z);
1058}
1059
1060// Normalize a range to VARYING or UNDEFINED if possible.
1061
1062inline void
1063irange::normalize_kind ()
1064{
1065 if (m_num_ranges == 0)
1066 set_undefined ();
1067 else if (varying_compatible_p ())
1068 {
1069 if (m_kind == VR_RANGE)
1070 m_kind = VR_VARYING;
1071 else if (m_kind == VR_ANTI_RANGE)
1072 set_undefined ();
1073 }
1074}
1075
1076// Return the maximum value for TYPE.
1077
1078inline tree
1079vrp_val_max (const_tree type)
1080{
1081 if (INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum
tree_code) (type)->base.code) == INTEGER_TYPE)
)
1082 return TYPE_MAX_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1082, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
;
1083 if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
1084 {
1085 wide_int max = wi::max_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1085, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1085, __FUNCTION__))->base.u.bits.unsigned_flag))
);
1086 return wide_int_to_tree (const_cast<tree> (type), max);
1087 }
1088 if (frange::supports_p (type))
1089 {
1090 REAL_VALUE_TYPEstruct real_value r = frange_val_max (type);
1091 return build_real (const_cast <tree> (type), r);
1092 }
1093 return NULL_TREE(tree) nullptr;
1094}
1095
1096// Return the minimum value for TYPE.
1097
1098inline tree
1099vrp_val_min (const_tree type)
1100{
1101 if (INTEGRAL_TYPE_P (type)(((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOOLEAN_TYPE || ((enum
tree_code) (type)->base.code) == INTEGER_TYPE)
)
1102 return TYPE_MIN_VALUE (type)((tree_check5 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1102, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
;
1103 if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
1104 return build_zero_cst (const_cast<tree> (type));
1105 if (frange::supports_p (type))
1106 {
1107 REAL_VALUE_TYPEstruct real_value r = frange_val_min (type);
1108 return build_real (const_cast <tree> (type), r);
1109 }
1110 return NULL_TREE(tree) nullptr;
1111}
1112
1113inline
1114frange::frange ()
1115{
1116 m_discriminator = VR_FRANGE;
1117 set_undefined ();
1118}
1119
1120inline
1121frange::frange (const frange &src)
1122{
1123 m_discriminator = VR_FRANGE;
1124 *this = src;
1125}
1126
1127inline
1128frange::frange (tree type)
1129{
1130 m_discriminator = VR_FRANGE;
1131 set_varying (type);
1132}
1133
1134// frange constructor from REAL_VALUE_TYPE endpoints.
1135
1136inline
1137frange::frange (tree type,
1138 const REAL_VALUE_TYPEstruct real_value &min, const REAL_VALUE_TYPEstruct real_value &max,
1139 value_range_kind kind)
1140{
1141 m_discriminator = VR_FRANGE;
1142 set (type, min, max, kind);
1143}
1144
1145// frange constructor from trees.
1146
1147inline
1148frange::frange (tree min, tree max, value_range_kind kind)
1149{
1150 m_discriminator = VR_FRANGE;
1151 set (min, max, kind);
1152}
1153
1154inline tree
1155frange::type () const
1156{
1157 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1157, __FUNCTION__), 0 : 0))
;
1158 return m_type;
1159}
1160
1161inline void
1162frange::set_varying (tree type)
1163{
1164 m_kind = VR_VARYING;
1165 m_type = type;
1166 m_min = frange_val_min (type);
1167 m_max = frange_val_max (type);
1168 if (HONOR_NANS (m_type))
1169 {
1170 m_pos_nan = true;
1171 m_neg_nan = true;
1172 }
1173 else
1174 {
1175 m_pos_nan = false;
1176 m_neg_nan = false;
1177 }
1178}
1179
1180inline void
1181frange::set_undefined ()
1182{
1183 m_kind = VR_UNDEFINED;
1184 m_type = NULLnullptr;
1185 m_pos_nan = false;
1186 m_neg_nan = false;
1187 // m_min and m_min are uninitialized as they are REAL_VALUE_TYPE ??.
1188 if (flag_checkingglobal_options.x_flag_checking)
1189 verify_range ();
1190}
1191
1192// Set the NAN bit and adjust the range.
1193
1194inline void
1195frange::update_nan ()
1196{
1197 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1197, __FUNCTION__), 0 : 0))
;
1198 if (HONOR_NANS (m_type))
1199 {
1200 m_pos_nan = true;
1201 m_neg_nan = true;
1202 normalize_kind ();
1203 if (flag_checkingglobal_options.x_flag_checking)
1204 verify_range ();
1205 }
1206}
1207
1208// Like above, but set the sign of the NAN.
1209
1210inline void
1211frange::update_nan (bool sign)
1212{
1213 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1213, __FUNCTION__), 0 : 0))
;
1214 if (HONOR_NANS (m_type))
1215 {
1216 m_pos_nan = !sign;
1217 m_neg_nan = sign;
1218 normalize_kind ();
1219 if (flag_checkingglobal_options.x_flag_checking)
1220 verify_range ();
1221 }
1222}
1223
1224// Clear the NAN bit and adjust the range.
1225
1226inline void
1227frange::clear_nan ()
1228{
1229 gcc_checking_assert (!undefined_p ())((void)(!(!undefined_p ()) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1229, __FUNCTION__), 0 : 0))
;
1230 m_pos_nan = false;
1231 m_neg_nan = false;
1232 normalize_kind ();
1233 if (flag_checkingglobal_options.x_flag_checking)
1234 verify_range ();
1235}
1236
1237// Set R to maximum representable value for TYPE.
1238
1239inline REAL_VALUE_TYPEstruct real_value
1240real_max_representable (const_tree type)
1241{
1242 REAL_VALUE_TYPEstruct real_value r;
1243 char buf[128];
1244 get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type))(real_format_for_mode[(((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1244, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_DECIMAL_FLOAT
) ? (((((((enum tree_code) ((tree_class_check ((type), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1244, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)) - MIN_MODE_DECIMAL_FLOAT
) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class
) mode_class[((((enum tree_code) ((tree_class_check ((type), (
tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1244, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_FLOAT ? ((((
((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1244, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)) - MIN_MODE_FLOAT) : (
(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1244, __FUNCTION__)), 0)])
,
1245 buf, sizeof (buf), false);
1246 int res = real_from_string (&r, buf);
1247 gcc_checking_assert (!res)((void)(!(!res) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 1247, __FUNCTION__), 0 : 0))
;
1248 return r;
1249}
1250
1251// Return the minimum representable value for TYPE.
1252
1253inline REAL_VALUE_TYPEstruct real_value
1254real_min_representable (const_tree type)
1255{
1256 REAL_VALUE_TYPEstruct real_value r = real_max_representable (type);
1257 r = real_value_negate (&r);
1258 return r;
1259}
1260
1261// Return the minimum value for TYPE.
1262
1263inline REAL_VALUE_TYPEstruct real_value
1264frange_val_min (const_tree type)
1265{
1266 if (HONOR_INFINITIES (type))
1267 return dconstninf;
1268 else
1269 return real_min_representable (type);
1270}
1271
1272// Return the maximum value for TYPE.
1273
1274inline REAL_VALUE_TYPEstruct real_value
1275frange_val_max (const_tree type)
1276{
1277 if (HONOR_INFINITIES (type))
1278 return dconstinf;
1279 else
1280 return real_max_representable (type);
1281}
1282
1283// Return TRUE if R is the minimum value for TYPE.
1284
1285inline bool
1286frange_val_is_min (const REAL_VALUE_TYPEstruct real_value &r, const_tree type)
1287{
1288 REAL_VALUE_TYPEstruct real_value min = frange_val_min (type);
1289 return real_identical (&min, &r);
1290}
1291
1292// Return TRUE if R is the max value for TYPE.
1293
1294inline bool
1295frange_val_is_max (const REAL_VALUE_TYPEstruct real_value &r, const_tree type)
1296{
1297 REAL_VALUE_TYPEstruct real_value max = frange_val_max (type);
1298 return real_identical (&max, &r);
1299}
1300
1301// Build a signless NAN of type TYPE.
1302
1303inline void
1304frange::set_nan (tree type)
1305{
1306 if (HONOR_NANS (type))
1307 {
1308 m_kind = VR_NAN;
1309 m_type = type;
1310 m_pos_nan = true;
1311 m_neg_nan = true;
1312 if (flag_checkingglobal_options.x_flag_checking)
1313 verify_range ();
1314 }
1315 else
1316 set_undefined ();
1317}
1318
1319// Build a NAN of type TYPE with SIGN.
1320
1321inline void
1322frange::set_nan (tree type, bool sign)
1323{
1324 if (HONOR_NANS (type))
1325 {
1326 m_kind = VR_NAN;
1327 m_type = type;
1328 m_neg_nan = sign;
1329 m_pos_nan = !sign;
1330 if (flag_checkingglobal_options.x_flag_checking)
1331 verify_range ();
1332 }
1333 else
1334 set_undefined ();
1335}
1336
1337// Return TRUE if range is known to be finite.
1338
1339inline bool
1340frange::known_isfinite () const
1341{
1342 if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
1343 return false;
1344 return (!maybe_isnan () && !real_isinf (&m_min) && !real_isinf (&m_max