Bug Summary

File:build/gcc/value-range.h
Warning:line 233, column 3
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name value-range.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/13.0.0 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/backward -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-error=format-diag -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/home/marxin/BIG/buildbot/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 /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2021-11-20-133755-20252-1/report-NbRCZW.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc

1/* Support routines for value ranges.
2 Copyright (C) 2019-2021 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 "fold-const.h"
31#include "gimple-range.h"
32
33// Here we copy between any two irange's. The ranges can be legacy or
34// multi-ranges, and copying between any combination works correctly.
35
36irange &
37irange::operator= (const irange &src)
38{
39 if (legacy_mode_p ())
40 {
41 copy_to_legacy (src);
42 return *this;
43 }
44 if (src.legacy_mode_p ())
45 {
46 copy_legacy_to_multi_range (src);
47 return *this;
48 }
49
50 unsigned x;
51 unsigned lim = src.m_num_ranges;
52 if (lim > m_max_ranges)
53 lim = m_max_ranges;
54
55 for (x = 0; x < lim * 2; ++x)
56 m_base[x] = src.m_base[x];
57
58 // If the range didn't fit, the last range should cover the rest.
59 if (lim != src.m_num_ranges)
60 m_base[x - 1] = src.m_base[src.m_num_ranges * 2 - 1];
61
62 m_num_ranges = lim;
63 m_kind = src.m_kind;
64 return *this;
65}
66
67// Return TRUE if range is a multi-range that can be represented as a
68// VR_ANTI_RANGE.
69
70bool
71irange::maybe_anti_range () const
72{
73 tree ttype = type ();
74 unsigned int precision = TYPE_PRECISION (ttype)((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 74, __FUNCTION__))->type_common.precision)
;
75 signop sign = TYPE_SIGN (ttype)((signop) ((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 75, __FUNCTION__))->base.u.bits.unsigned_flag))
;
76 return (num_pairs () > 1
77 && precision > 1
78 && lower_bound () == wi::min_value (precision, sign)
79 && upper_bound () == wi::max_value (precision, sign));
80}
81
82void
83irange::copy_legacy_to_multi_range (const irange &src)
84{
85 gcc_checking_assert (src.legacy_mode_p ())((void)(!(src.legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 85, __FUNCTION__), 0 : 0))
;
86 gcc_checking_assert (!legacy_mode_p ())((void)(!(!legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 86, __FUNCTION__), 0 : 0))
;
87 if (src.undefined_p ())
88 set_undefined ();
89 else if (src.varying_p ())
90 set_varying (src.type ());
91 else
92 {
93 if (range_has_numeric_bounds_p (&src))
94 set (src.min (), src.max (), src.kind ());
95 else
96 {
97 value_range cst (src);
98 cst.normalize_symbolics ();
99 gcc_checking_assert (cst.varying_p () || cst.kind () == VR_RANGE)((void)(!(cst.varying_p () || cst.kind () == VR_RANGE) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 99, __FUNCTION__), 0 : 0))
;
100 set (cst.min (), cst.max ());
101 }
102 }
103}
104
105// Copy any type of irange into a legacy.
106
107void
108irange::copy_to_legacy (const irange &src)
109{
110 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 110, __FUNCTION__), 0 : 0))
;
111 // Handle legacy to legacy and other things that are easy to copy.
112 if (src.legacy_mode_p () || src.varying_p () || src.undefined_p ())
113 {
114 m_num_ranges = src.m_num_ranges;
115 m_base[0] = src.m_base[0];
116 m_base[1] = src.m_base[1];
117 m_kind = src.m_kind;
118 return;
119 }
120 // Copy multi-range to legacy.
121 if (src.maybe_anti_range ())
122 {
123 int_range<3> r (src);
124 r.invert ();
125 // Use tree variants to save on tree -> wi -> tree conversions.
126 set (r.tree_lower_bound (0), r.tree_upper_bound (0), VR_ANTI_RANGE);
127 }
128 else
129 set (src.tree_lower_bound (), src.tree_upper_bound ());
130}
131
132// Swap MIN/MAX if they are out of order and adjust KIND appropriately.
133
134static void
135swap_out_of_order_endpoints (tree &min, tree &max, value_range_kind &kind)
136{
137 gcc_checking_assert (kind != VR_UNDEFINED)((void)(!(kind != VR_UNDEFINED) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 137, __FUNCTION__), 0 : 0))
;
138 if (kind == VR_VARYING)
139 return;
140 /* Wrong order for min and max, to swap them and the VR type we need
141 to adjust them. */
142 if (tree_int_cst_lt (max, min))
143 {
144 tree one, tmp;
145
146 /* For one bit precision if max < min, then the swapped
147 range covers all values, so for VR_RANGE it is varying and
148 for VR_ANTI_RANGE empty range, so drop to varying as well. */
149 if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 149, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 149, __FUNCTION__))->type_common.precision)
== 1)
150 {
151 kind = VR_VARYING;
152 return;
153 }
154
155 one = build_int_cst (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 155, __FUNCTION__))->typed.type)
, 1);
156 tmp = int_const_binop (PLUS_EXPR, max, one);
157 max = int_const_binop (MINUS_EXPR, min, one);
158 min = tmp;
159
160 /* There's one corner case, if we had [C+1, C] before we now have
161 that again. But this represents an empty value range, so drop
162 to varying in this case. */
163 if (tree_int_cst_lt (max, min))
164 {
165 kind = VR_VARYING;
166 return;
167 }
168 kind = kind == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
169 }
170}
171
172void
173irange::irange_set (tree min, tree max)
174{
175 gcc_checking_assert (!POLY_INT_CST_P (min))((void)(!(!(1 > 1 && ((enum tree_code) (min)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 175, __FUNCTION__), 0 : 0))
;
176 gcc_checking_assert (!POLY_INT_CST_P (max))((void)(!(!(1 > 1 && ((enum tree_code) (max)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 176, __FUNCTION__), 0 : 0))
;
177
178 m_base[0] = min;
179 m_base[1] = max;
180 m_num_ranges = 1;
181 m_kind = VR_RANGE;
182 normalize_kind ();
183
184 if (flag_checkingglobal_options.x_flag_checking)
185 verify_range ();
186}
187
188void
189irange::irange_set_1bit_anti_range (tree min, tree max)
190{
191 tree type = TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 191, __FUNCTION__))->typed.type)
;
192 gcc_checking_assert (TYPE_PRECISION (type) == 1)((void)(!(((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 192, __FUNCTION__))->type_common.precision) == 1) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 192, __FUNCTION__), 0 : 0))
;
193
194 if (operand_equal_p (min, max))
195 {
196 // Since these are 1-bit quantities, they can only be [MIN,MIN]
197 // or [MAX,MAX].
198 if (vrp_val_is_min (min))
199 min = max = vrp_val_max (type);
200 else
201 min = max = vrp_val_min (type);
202 set (min, max);
203 }
204 else
205 {
206 // The only alternative is [MIN,MAX], which is the empty range.
207 gcc_checking_assert (vrp_val_is_min (min))((void)(!(vrp_val_is_min (min)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 207, __FUNCTION__), 0 : 0))
;
208 gcc_checking_assert (vrp_val_is_max (max))((void)(!(vrp_val_is_max (max)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 208, __FUNCTION__), 0 : 0))
;
209 set_undefined ();
210 }
211 if (flag_checkingglobal_options.x_flag_checking)
212 verify_range ();
213}
214
215void
216irange::irange_set_anti_range (tree min, tree max)
217{
218 gcc_checking_assert (!POLY_INT_CST_P (min))((void)(!(!(1 > 1 && ((enum tree_code) (min)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 218, __FUNCTION__), 0 : 0))
;
219 gcc_checking_assert (!POLY_INT_CST_P (max))((void)(!(!(1 > 1 && ((enum tree_code) (max)->base
.code) == POLY_INT_CST)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 219, __FUNCTION__), 0 : 0))
;
220
221 if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 221, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 221, __FUNCTION__))->type_common.precision)
== 1)
222 {
223 irange_set_1bit_anti_range (min, max);
224 return;
225 }
226
227 // set an anti-range
228 tree type = TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 228, __FUNCTION__))->typed.type)
;
229 signop sign = TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 229, __FUNCTION__))->base.u.bits.unsigned_flag))
;
230 int_range<2> type_range (type);
231 // Calculate INVERSE([I,J]) as [-MIN, I-1][J+1, +MAX].
232 m_num_ranges = 0;
233 wi::overflow_type ovf;
234
235 wide_int w_min = wi::to_wide (min);
236 if (wi::ne_p (w_min, type_range.lower_bound ()))
237 {
238 wide_int lim1 = wi::sub (w_min, 1, sign, &ovf);
239 gcc_checking_assert (ovf != wi::OVF_OVERFLOW)((void)(!(ovf != wi::OVF_OVERFLOW) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 239, __FUNCTION__), 0 : 0))
;
240 m_base[0] = type_range.tree_lower_bound (0);
241 m_base[1] = wide_int_to_tree (type, lim1);
242 m_num_ranges = 1;
243 }
244 wide_int w_max = wi::to_wide (max);
245 if (wi::ne_p (w_max, type_range.upper_bound ()))
246 {
247 wide_int lim2 = wi::add (w_max, 1, sign, &ovf);
248 gcc_checking_assert (ovf != wi::OVF_OVERFLOW)((void)(!(ovf != wi::OVF_OVERFLOW) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 248, __FUNCTION__), 0 : 0))
;
249 m_base[m_num_ranges * 2] = wide_int_to_tree (type, lim2);
250 m_base[m_num_ranges * 2 + 1] = type_range.tree_upper_bound (0);
251 ++m_num_ranges;
252 }
253
254 m_kind = VR_RANGE;
255 normalize_kind ();
256
257 if (flag_checkingglobal_options.x_flag_checking)
258 verify_range ();
259}
260
261/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
262 This means adjusting VRTYPE, MIN and MAX representing the case of a
263 wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
264 as anti-rage ~[MAX+1, MIN-1]. Likewise for wrapping anti-ranges.
265 In corner cases where MAX+1 or MIN-1 wraps this will fall back
266 to varying.
267 This routine exists to ease canonicalization in the case where we
268 extract ranges from var + CST op limit. */
269
270void
271irange::set (tree min, tree max, value_range_kind kind)
272{
273 if (kind != VR_UNDEFINED)
274 {
275 if (TREE_OVERFLOW_P (min)((tree_code_type[(int) (((enum tree_code) (min)->base.code
))] == tcc_constant) && ((tree_class_check ((min), (tcc_constant
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 275, __FUNCTION__))->base.public_flag))
)
276 min = drop_tree_overflow (min);
277 if (TREE_OVERFLOW_P (max)((tree_code_type[(int) (((enum tree_code) (max)->base.code
))] == tcc_constant) && ((tree_class_check ((max), (tcc_constant
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 277, __FUNCTION__))->base.public_flag))
)
278 max = drop_tree_overflow (max);
279 }
280
281 if (!legacy_mode_p ())
282 {
283 if (kind == VR_RANGE)
284 irange_set (min, max);
285 else
286 {
287 gcc_checking_assert (kind == VR_ANTI_RANGE)((void)(!(kind == VR_ANTI_RANGE) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 287, __FUNCTION__), 0 : 0))
;
288 irange_set_anti_range (min, max);
289 }
290 return;
291 }
292 if (kind == VR_UNDEFINED)
293 {
294 set_undefined ();
295 return;
296 }
297
298 if (kind == VR_VARYING
299 || POLY_INT_CST_P (min)(1 > 1 && ((enum tree_code) (min)->base.code) ==
POLY_INT_CST)
300 || POLY_INT_CST_P (max)(1 > 1 && ((enum tree_code) (max)->base.code) ==
POLY_INT_CST)
)
301 {
302 set_varying (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 302, __FUNCTION__))->typed.type)
);
303 return;
304 }
305
306 // Nothing to canonicalize for symbolic ranges.
307 if (TREE_CODE (min)((enum tree_code) (min)->base.code) != INTEGER_CST
308 || TREE_CODE (max)((enum tree_code) (max)->base.code) != INTEGER_CST)
309 {
310 m_kind = kind;
311 m_base[0] = min;
312 m_base[1] = max;
313 m_num_ranges = 1;
314 return;
315 }
316
317 swap_out_of_order_endpoints (min, max, kind);
318 if (kind == VR_VARYING)
319 {
320 set_varying (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 320, __FUNCTION__))->typed.type)
);
321 return;
322 }
323
324 // Anti-ranges that can be represented as ranges should be so.
325 if (kind == VR_ANTI_RANGE)
326 {
327 bool is_min = vrp_val_is_min (min);
328 bool is_max = vrp_val_is_max (max);
329
330 if (is_min && is_max)
331 {
332 // Fall through. This will either be normalized as
333 // VR_UNDEFINED if the anti-range spans the entire
334 // precision, or it will remain an VR_ANTI_RANGE in the case
335 // of an -fstrict-enum where [MIN,MAX] is less than the span
336 // of underlying precision.
337 }
338 else if (TYPE_PRECISION (TREE_TYPE (min))((tree_class_check ((((contains_struct_check ((min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 338, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 338, __FUNCTION__))->type_common.precision)
== 1)
339 {
340 irange_set_1bit_anti_range (min, max);
341 return;
342 }
343 else if (is_min)
344 {
345 tree one = build_int_cst (TREE_TYPE (max)((contains_struct_check ((max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 345, __FUNCTION__))->typed.type)
, 1);
346 min = int_const_binop (PLUS_EXPR, max, one);
347 max = vrp_val_max (TREE_TYPE (max)((contains_struct_check ((max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 347, __FUNCTION__))->typed.type)
);
348 kind = VR_RANGE;
349 }
350 else if (is_max)
351 {
352 tree one = build_int_cst (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 352, __FUNCTION__))->typed.type)
, 1);
353 max = int_const_binop (MINUS_EXPR, min, one);
354 min = vrp_val_min (TREE_TYPE (min)((contains_struct_check ((min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 354, __FUNCTION__))->typed.type)
);
355 kind = VR_RANGE;
356 }
357 }
358
359 m_kind = kind;
360 m_base[0] = min;
361 m_base[1] = max;
362 m_num_ranges = 1;
363 normalize_kind ();
364 if (flag_checkingglobal_options.x_flag_checking)
365 verify_range ();
366}
367
368// Check the validity of the range.
369
370void
371irange::verify_range ()
372{
373 if (m_kind == VR_UNDEFINED)
374 {
375 gcc_checking_assert (m_num_ranges == 0)((void)(!(m_num_ranges == 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 375, __FUNCTION__), 0 : 0))
;
376 return;
377 }
378 if (m_kind == VR_VARYING)
379 {
380 gcc_checking_assert (m_num_ranges == 1)((void)(!(m_num_ranges == 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 380, __FUNCTION__), 0 : 0))
;
381 gcc_checking_assert (varying_compatible_p ())((void)(!(varying_compatible_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 381, __FUNCTION__), 0 : 0))
;
382 return;
383 }
384 if (!legacy_mode_p ())
385 {
386 gcc_checking_assert (m_num_ranges != 0)((void)(!(m_num_ranges != 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 386, __FUNCTION__), 0 : 0))
;
387 gcc_checking_assert (!varying_compatible_p ())((void)(!(!varying_compatible_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 387, __FUNCTION__), 0 : 0))
;
388 for (unsigned i = 0; i < m_num_ranges; ++i)
389 {
390 tree lb = tree_lower_bound (i);
391 tree ub = tree_upper_bound (i);
392 int c = compare_values (lb, ub);
393 gcc_checking_assert (c == 0 || c == -1)((void)(!(c == 0 || c == -1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 393, __FUNCTION__), 0 : 0))
;
394 }
395 return;
396 }
397 if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
398 {
399 gcc_checking_assert (m_num_ranges == 1)((void)(!(m_num_ranges == 1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 399, __FUNCTION__), 0 : 0))
;
400 int cmp = compare_values (tree_lower_bound (0), tree_upper_bound (0));
401 gcc_checking_assert (cmp == 0 || cmp == -1 || cmp == -2)((void)(!(cmp == 0 || cmp == -1 || cmp == -2) ? fancy_abort (
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 401, __FUNCTION__), 0 : 0))
;
402 }
403}
404
405// Return the lower bound for a sub-range. PAIR is the sub-range in
406// question.
407
408wide_int
409irange::legacy_lower_bound (unsigned pair) const
410{
411 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 411, __FUNCTION__), 0 : 0))
;
412 if (symbolic_p ())
413 {
414 value_range numeric_range (*this);
415 numeric_range.normalize_symbolics ();
416 return numeric_range.legacy_lower_bound (pair);
417 }
418 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 418, __FUNCTION__), 0 : 0))
;
419 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 419, __FUNCTION__), 0 : 0))
;
420 if (m_kind == VR_ANTI_RANGE)
421 {
422 tree typ = type (), t;
423 if (pair == 1 || vrp_val_is_min (min ()))
424 t = wide_int_to_tree (typ, wi::to_wide (max ()) + 1);
425 else
426 t = vrp_val_min (typ);
427 return wi::to_wide (t);
428 }
429 return wi::to_wide (tree_lower_bound (pair));
430}
431
432// Return the upper bound for a sub-range. PAIR is the sub-range in
433// question.
434
435wide_int
436irange::legacy_upper_bound (unsigned pair) const
437{
438 gcc_checking_assert (legacy_mode_p ())((void)(!(legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 438, __FUNCTION__), 0 : 0))
;
439 if (symbolic_p ())
440 {
441 value_range numeric_range (*this);
442 numeric_range.normalize_symbolics ();
443 return numeric_range.legacy_upper_bound (pair);
444 }
445 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 445, __FUNCTION__), 0 : 0))
;
446 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 446, __FUNCTION__), 0 : 0))
;
447 if (m_kind == VR_ANTI_RANGE)
448 {
449 tree typ = type (), t;
450 if (pair == 1 || vrp_val_is_min (min ()))
451 t = vrp_val_max (typ);
452 else
453 t = wide_int_to_tree (typ, wi::to_wide (min ()) - 1);
454 return wi::to_wide (t);
455 }
456 return wi::to_wide (tree_upper_bound (pair));
457}
458
459bool
460irange::legacy_equal_p (const irange &other) const
461{
462 gcc_checking_assert (legacy_mode_p () && other.legacy_mode_p ())((void)(!(legacy_mode_p () && other.legacy_mode_p ())
? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 462, __FUNCTION__), 0 : 0))
;
463
464 if (m_kind != other.m_kind)
465 return false;
466 if (m_kind == VR_UNDEFINED)
467 return true;
468 if (m_kind == VR_VARYING)
469 return range_compatible_p (type (), other.type ());
470 return (vrp_operand_equal_p (tree_lower_bound (0),
471 other.tree_lower_bound (0))
472 && vrp_operand_equal_p (tree_upper_bound (0),
473 other.tree_upper_bound (0)));
474}
475
476bool
477irange::equal_p (const irange &other) const
478{
479 if (legacy_mode_p ())
14
Calling 'irange::legacy_mode_p'
16
Returning from 'irange::legacy_mode_p'
17
Taking false branch
480 {
481 if (other.legacy_mode_p ())
482 return legacy_equal_p (other);
483 value_range tmp (other);
484 return legacy_equal_p (tmp);
485 }
486 if (other.legacy_mode_p ())
18
Calling 'irange::legacy_mode_p'
21
Returning from 'irange::legacy_mode_p'
22
Taking false branch
487 {
488 value_range tmp2 (*this);
489 return tmp2.legacy_equal_p (other);
490 }
491
492 if (m_num_ranges != other.m_num_ranges)
23
Assuming 'm_num_ranges' is equal to 'other.m_num_ranges'
24
Taking false branch
493 return false;
494
495 for (unsigned i = 0; i < m_num_ranges; ++i)
25
'i' initialized to 0
26
Assuming 'i' is < field 'm_num_ranges'
27
Loop condition is true. Entering loop body
496 {
497 tree lb = tree_lower_bound (i);
28
Passing the value 0 via 1st parameter 'pair'
29
Calling 'irange::tree_lower_bound'
498 tree ub = tree_upper_bound (i);
499 tree lb_other = other.tree_lower_bound (i);
500 tree ub_other = other.tree_upper_bound (i);
501 if (!operand_equal_p (lb, lb_other, 0)
502 || !operand_equal_p (ub, ub_other, 0))
503 return false;
504 }
505 return true;
506}
507
508/* Return TRUE if this is a symbolic range. */
509
510bool
511irange::symbolic_p () const
512{
513 return (m_num_ranges > 0
514 && (!is_gimple_min_invariant (min ())
515 || !is_gimple_min_invariant (max ())));
516}
517
518/* Return TRUE if this is a constant range. */
519
520bool
521irange::constant_p () const
522{
523 return (m_num_ranges > 0
524 && TREE_CODE (min ())((enum tree_code) (min ())->base.code) == INTEGER_CST
525 && TREE_CODE (max ())((enum tree_code) (max ())->base.code) == INTEGER_CST);
526}
527
528/* If range is a singleton, place it in RESULT and return TRUE.
529 Note: A singleton can be any gimple invariant, not just constants.
530 So, [&x, &x] counts as a singleton. */
531
532bool
533irange::singleton_p (tree *result) const
534{
535 if (!legacy_mode_p ())
536 {
537 if (num_pairs () == 1 && (wi::to_wide (tree_lower_bound ())
538 == wi::to_wide (tree_upper_bound ())))
539 {
540 if (result)
541 *result = tree_lower_bound ();
542 return true;
543 }
544 return false;
545 }
546 if (m_kind == VR_ANTI_RANGE)
547 {
548 if (nonzero_p ())
549 {
550 if (TYPE_PRECISION (type ())((tree_class_check ((type ()), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 550, __FUNCTION__))->type_common.precision)
== 1)
551 {
552 if (result)
553 *result = max ();
554 return true;
555 }
556 return false;
557 }
558 if (num_pairs () == 1)
559 {
560 value_range vr0, vr1;
561 ranges_from_anti_range ((const value_range *) this, &vr0, &vr1);
562 return vr0.singleton_p (result);
563 }
564 }
565 // Catches non-numeric extremes as well.
566 if (m_kind == VR_RANGE
567 && vrp_operand_equal_p (min (), max ())
568 && is_gimple_min_invariant (min ()))
569 {
570 if (result)
571 *result = min ();
572 return true;
573 }
574 return false;
575}
576
577/* Return 1 if VAL is inside value range.
578 0 if VAL is not inside value range.
579 -2 if we cannot tell either way.
580
581 Benchmark compile/20001226-1.c compilation time after changing this
582 function. */
583
584int
585irange::value_inside_range (tree val) const
586{
587 if (varying_p ())
588 return 1;
589
590 if (undefined_p ())
591 return 0;
592
593 if (!legacy_mode_p () && TREE_CODE (val)((enum tree_code) (val)->base.code) == INTEGER_CST)
594 return contains_p (val);
595
596 int cmp1 = operand_less_p (val, min ());
597 if (cmp1 == -2)
598 return -2;
599 if (cmp1 == 1)
600 return m_kind != VR_RANGE;
601
602 int cmp2 = operand_less_p (max (), val);
603 if (cmp2 == -2)
604 return -2;
605
606 if (m_kind == VR_RANGE)
607 return !cmp2;
608 else
609 return !!cmp2;
610}
611
612/* Return TRUE if it is possible that range contains VAL. */
613
614bool
615irange::may_contain_p (tree val) const
616{
617 return value_inside_range (val) != 0;
618}
619
620/* Return TRUE if range contains INTEGER_CST. */
621/* Return 1 if VAL is inside value range.
622 0 if VAL is not inside value range.
623
624 Benchmark compile/20001226-1.c compilation time after changing this
625 function. */
626
627
628bool
629irange::contains_p (tree cst) const
630{
631 if (undefined_p ())
632 return false;
633
634 if (legacy_mode_p ())
635 {
636 gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST)((void)(!(((enum tree_code) (cst)->base.code) == INTEGER_CST
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 636, __FUNCTION__), 0 : 0))
;
637 if (symbolic_p ())
638 {
639 value_range numeric_range (*this);
640 numeric_range.normalize_symbolics ();
641 return numeric_range.contains_p (cst);
642 }
643 return value_inside_range (cst) == 1;
644 }
645
646 gcc_checking_assert (TREE_CODE (cst) == INTEGER_CST)((void)(!(((enum tree_code) (cst)->base.code) == INTEGER_CST
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 646, __FUNCTION__), 0 : 0))
;
647 signop sign = TYPE_SIGN (TREE_TYPE (cst))((signop) ((tree_class_check ((((contains_struct_check ((cst)
, (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 647, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 647, __FUNCTION__))->base.u.bits.unsigned_flag))
;
648 wide_int v = wi::to_wide (cst);
649 for (unsigned r = 0; r < m_num_ranges; ++r)
650 {
651 if (wi::lt_p (v, lower_bound (r), sign))
652 return false;
653 if (wi::le_p (v, upper_bound (r), sign))
654 return true;
655 }
656
657 return false;
658}
659
660
661/* Normalize addresses into constants. */
662
663void
664irange::normalize_addresses ()
665{
666 if (undefined_p ())
667 return;
668
669 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))
670 return;
671
672 if (!range_includes_zero_p (this))
673 {
674 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 675, __FUNCTION__), 0 : 0))
675 || TREE_CODE (max ()) == ADDR_EXPR)((void)(!(((enum tree_code) (min ())->base.code) == ADDR_EXPR
|| ((enum tree_code) (max ())->base.code) == ADDR_EXPR) ?
fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 675, __FUNCTION__), 0 : 0))
;
676 set_nonzero (type ());
677 return;
678 }
679 set_varying (type ());
680}
681
682/* Normalize symbolics and addresses into constants. */
683
684void
685irange::normalize_symbolics ()
686{
687 if (varying_p () || undefined_p ())
688 return;
689
690 tree ttype = type ();
691 bool min_symbolic = !is_gimple_min_invariant (min ());
692 bool max_symbolic = !is_gimple_min_invariant (max ());
693 if (!min_symbolic && !max_symbolic)
694 {
695 normalize_addresses ();
696 return;
697 }
698
699 // [SYM, SYM] -> VARYING
700 if (min_symbolic && max_symbolic)
701 {
702 set_varying (ttype);
703 return;
704 }
705 if (kind () == VR_RANGE)
706 {
707 // [SYM, NUM] -> [-MIN, NUM]
708 if (min_symbolic)
709 {
710 set (vrp_val_min (ttype), max ());
711 return;
712 }
713 // [NUM, SYM] -> [NUM, +MAX]
714 set (min (), vrp_val_max (ttype));
715 return;
716 }
717 gcc_checking_assert (kind () == VR_ANTI_RANGE)((void)(!(kind () == VR_ANTI_RANGE) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 717, __FUNCTION__), 0 : 0))
;
718 // ~[SYM, NUM] -> [NUM + 1, +MAX]
719 if (min_symbolic)
720 {
721 if (!vrp_val_is_max (max ()))
722 {
723 tree n = wide_int_to_tree (ttype, wi::to_wide (max ()) + 1);
724 set (n, vrp_val_max (ttype));
725 return;
726 }
727 set_varying (ttype);
728 return;
729 }
730 // ~[NUM, SYM] -> [-MIN, NUM - 1]
731 if (!vrp_val_is_min (min ()))
732 {
733 tree n = wide_int_to_tree (ttype, wi::to_wide (min ()) - 1);
734 set (vrp_val_min (ttype), n);
735 return;
736 }
737 set_varying (ttype);
738}
739
740/* Intersect the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
741 { VR1TYPE, VR0MIN, VR0MAX } and store the result
742 in { *VR0TYPE, *VR0MIN, *VR0MAX }. This may not be the smallest
743 possible such range. The resulting range is not canonicalized. */
744
745static void
746intersect_ranges (enum value_range_kind *vr0type,
747 tree *vr0min, tree *vr0max,
748 enum value_range_kind vr1type,
749 tree vr1min, tree vr1max)
750{
751 bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
752 bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
753
754 /* [] is vr0, () is vr1 in the following classification comments. */
755 if (mineq && maxeq)
756 {
757 /* [( )] */
758 if (*vr0type == vr1type)
759 /* Nothing to do for equal ranges. */
760 ;
761 else if ((*vr0type == VR_RANGE
762 && vr1type == VR_ANTI_RANGE)
763 || (*vr0type == VR_ANTI_RANGE
764 && vr1type == VR_RANGE))
765 {
766 /* For anti-range with range intersection the result is empty. */
767 *vr0type = VR_UNDEFINED;
768 *vr0min = NULL_TREE(tree) nullptr;
769 *vr0max = NULL_TREE(tree) nullptr;
770 }
771 else
772 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 772, __FUNCTION__))
;
773 }
774 else if (operand_less_p (*vr0max, vr1min) == 1
775 || operand_less_p (vr1max, *vr0min) == 1)
776 {
777 /* [ ] ( ) or ( ) [ ]
778 If the ranges have an empty intersection, the result of the
779 intersect operation is the range for intersecting an
780 anti-range with a range or empty when intersecting two ranges. */
781 if (*vr0type == VR_RANGE
782 && vr1type == VR_ANTI_RANGE)
783 ;
784 else if (*vr0type == VR_ANTI_RANGE
785 && vr1type == VR_RANGE)
786 {
787 *vr0type = vr1type;
788 *vr0min = vr1min;
789 *vr0max = vr1max;
790 }
791 else if (*vr0type == VR_RANGE
792 && vr1type == VR_RANGE)
793 {
794 *vr0type = VR_UNDEFINED;
795 *vr0min = NULL_TREE(tree) nullptr;
796 *vr0max = NULL_TREE(tree) nullptr;
797 }
798 else if (*vr0type == VR_ANTI_RANGE
799 && vr1type == VR_ANTI_RANGE)
800 {
801 /* If the anti-ranges are adjacent to each other merge them. */
802 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST
803 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
804 && operand_less_p (*vr0max, vr1min) == 1
805 && integer_onep (int_const_binop (MINUS_EXPR,
806 vr1min, *vr0max)))
807 *vr0max = vr1max;
808 else if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
809 && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST
810 && operand_less_p (vr1max, *vr0min) == 1
811 && integer_onep (int_const_binop (MINUS_EXPR,
812 *vr0min, vr1max)))
813 *vr0min = vr1min;
814 /* Else arbitrarily take VR0. */
815 }
816 }
817 else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1)
818 && (mineq || operand_less_p (*vr0min, vr1min) == 1))
819 {
820 /* [ ( ) ] or [( ) ] or [ ( )] */
821 if (*vr0type == VR_RANGE
822 && vr1type == VR_RANGE)
823 {
824 /* If both are ranges the result is the inner one. */
825 *vr0type = vr1type;
826 *vr0min = vr1min;
827 *vr0max = vr1max;
828 }
829 else if (*vr0type == VR_RANGE
830 && vr1type == VR_ANTI_RANGE)
831 {
832 /* Choose the right gap if the left one is empty. */
833 if (mineq)
834 {
835 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) != INTEGER_CST)
836 *vr0min = vr1max;
837 else if (TYPE_PRECISION (TREE_TYPE (vr1max))((tree_class_check ((((contains_struct_check ((vr1max), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 837, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 837, __FUNCTION__))->type_common.precision)
== 1
838 && !TYPE_UNSIGNED (TREE_TYPE (vr1max))((tree_class_check ((((contains_struct_check ((vr1max), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 838, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 838, __FUNCTION__))->base.u.bits.unsigned_flag)
)
839 *vr0min
840 = int_const_binop (MINUS_EXPR, vr1max,
841 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 841, __FUNCTION__))->typed.type)
, -1));
842 else
843 *vr0min
844 = int_const_binop (PLUS_EXPR, vr1max,
845 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 845, __FUNCTION__))->typed.type)
, 1));
846 }
847 /* Choose the left gap if the right one is empty. */
848 else if (maxeq)
849 {
850 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) != INTEGER_CST)
851 *vr0max = vr1min;
852 else if (TYPE_PRECISION (TREE_TYPE (vr1min))((tree_class_check ((((contains_struct_check ((vr1min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 852, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 852, __FUNCTION__))->type_common.precision)
== 1
853 && !TYPE_UNSIGNED (TREE_TYPE (vr1min))((tree_class_check ((((contains_struct_check ((vr1min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 853, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 853, __FUNCTION__))->base.u.bits.unsigned_flag)
)
854 *vr0max
855 = int_const_binop (PLUS_EXPR, vr1min,
856 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 856, __FUNCTION__))->typed.type)
, -1));
857 else
858 *vr0max
859 = int_const_binop (MINUS_EXPR, vr1min,
860 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 860, __FUNCTION__))->typed.type)
, 1));
861 }
862 /* Choose the anti-range if the range is effectively varying. */
863 else if (vrp_val_is_min (*vr0min)
864 && vrp_val_is_max (*vr0max))
865 {
866 *vr0type = vr1type;
867 *vr0min = vr1min;
868 *vr0max = vr1max;
869 }
870 /* Else choose the range. */
871 }
872 else if (*vr0type == VR_ANTI_RANGE
873 && vr1type == VR_ANTI_RANGE)
874 /* If both are anti-ranges the result is the outer one. */
875 ;
876 else if (*vr0type == VR_ANTI_RANGE
877 && vr1type == VR_RANGE)
878 {
879 /* The intersection is empty. */
880 *vr0type = VR_UNDEFINED;
881 *vr0min = NULL_TREE(tree) nullptr;
882 *vr0max = NULL_TREE(tree) nullptr;
883 }
884 else
885 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 885, __FUNCTION__))
;
886 }
887 else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1)
888 && (mineq || operand_less_p (vr1min, *vr0min) == 1))
889 {
890 /* ( [ ] ) or ([ ] ) or ( [ ]) */
891 if (*vr0type == VR_RANGE
892 && vr1type == VR_RANGE)
893 /* Choose the inner range. */
894 ;
895 else if (*vr0type == VR_ANTI_RANGE
896 && vr1type == VR_RANGE)
897 {
898 /* Choose the right gap if the left is empty. */
899 if (mineq)
900 {
901 *vr0type = VR_RANGE;
902 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) != INTEGER_CST)
903 *vr0min = *vr0max;
904 else if (TYPE_PRECISION (TREE_TYPE (*vr0max))((tree_class_check ((((contains_struct_check ((*vr0max), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 904, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 904, __FUNCTION__))->type_common.precision)
== 1
905 && !TYPE_UNSIGNED (TREE_TYPE (*vr0max))((tree_class_check ((((contains_struct_check ((*vr0max), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 905, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 905, __FUNCTION__))->base.u.bits.unsigned_flag)
)
906 *vr0min
907 = int_const_binop (MINUS_EXPR, *vr0max,
908 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 908, __FUNCTION__))->typed.type)
, -1));
909 else
910 *vr0min
911 = int_const_binop (PLUS_EXPR, *vr0max,
912 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 912, __FUNCTION__))->typed.type)
, 1));
913 *vr0max = vr1max;
914 }
915 /* Choose the left gap if the right is empty. */
916 else if (maxeq)
917 {
918 *vr0type = VR_RANGE;
919 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) != INTEGER_CST)
920 *vr0max = *vr0min;
921 else if (TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 921, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 921, __FUNCTION__))->type_common.precision)
== 1
922 && !TYPE_UNSIGNED (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 922, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 922, __FUNCTION__))->base.u.bits.unsigned_flag)
)
923 *vr0max
924 = int_const_binop (PLUS_EXPR, *vr0min,
925 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 925, __FUNCTION__))->typed.type)
, -1));
926 else
927 *vr0max
928 = int_const_binop (MINUS_EXPR, *vr0min,
929 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 929, __FUNCTION__))->typed.type)
, 1));
930 *vr0min = vr1min;
931 }
932 /* Choose the anti-range if the range is effectively varying. */
933 else if (vrp_val_is_min (vr1min)
934 && vrp_val_is_max (vr1max))
935 ;
936 /* Choose the anti-range if it is ~[0,0], that range is special
937 enough to special case when vr1's range is relatively wide.
938 At least for types bigger than int - this covers pointers
939 and arguments to functions like ctz. */
940 else if (*vr0min == *vr0max
941 && integer_zerop (*vr0min)
942 && ((TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 942, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 942, __FUNCTION__))->type_common.precision)
943 >= TYPE_PRECISION (integer_type_node)((tree_class_check ((integer_types[itk_int]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 943, __FUNCTION__))->type_common.precision)
)
944 || POINTER_TYPE_P (TREE_TYPE (*vr0min))(((enum tree_code) (((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 944, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 944, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
945 && TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
946 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
947 && (wi::clz (wi::to_wide (vr1max) - wi::to_wide (vr1min))
948 < TYPE_PRECISION (TREE_TYPE (*vr0min))((tree_class_check ((((contains_struct_check ((*vr0min), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 948, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 948, __FUNCTION__))->type_common.precision)
/ 2))
949 ;
950 /* Else choose the range. */
951 else
952 {
953 *vr0type = vr1type;
954 *vr0min = vr1min;
955 *vr0max = vr1max;
956 }
957 }
958 else if (*vr0type == VR_ANTI_RANGE
959 && vr1type == VR_ANTI_RANGE)
960 {
961 /* If both are anti-ranges the result is the outer one. */
962 *vr0type = vr1type;
963 *vr0min = vr1min;
964 *vr0max = vr1max;
965 }
966 else if (vr1type == VR_ANTI_RANGE
967 && *vr0type == VR_RANGE)
968 {
969 /* The intersection is empty. */
970 *vr0type = VR_UNDEFINED;
971 *vr0min = NULL_TREE(tree) nullptr;
972 *vr0max = NULL_TREE(tree) nullptr;
973 }
974 else
975 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 975, __FUNCTION__))
;
976 }
977 else if ((operand_less_p (vr1min, *vr0max) == 1
978 || operand_equal_p (vr1min, *vr0max, 0))
979 && operand_less_p (*vr0min, vr1min) == 1
980 && operand_less_p (*vr0max, vr1max) == 1)
981 {
982 /* [ ( ] ) or [ ]( ) */
983 if (*vr0type == VR_ANTI_RANGE
984 && vr1type == VR_ANTI_RANGE)
985 *vr0max = vr1max;
986 else if (*vr0type == VR_RANGE
987 && vr1type == VR_RANGE)
988 *vr0min = vr1min;
989 else if (*vr0type == VR_RANGE
990 && vr1type == VR_ANTI_RANGE)
991 {
992 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
993 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
994 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 994, __FUNCTION__))->typed.type)
, 1));
995 else
996 *vr0max = vr1min;
997 }
998 else if (*vr0type == VR_ANTI_RANGE
999 && vr1type == VR_RANGE)
1000 {
1001 *vr0type = VR_RANGE;
1002 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
1003 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
1004 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1004, __FUNCTION__))->typed.type)
, 1));
1005 else
1006 *vr0min = *vr0max;
1007 *vr0max = vr1max;
1008 }
1009 else
1010 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1010, __FUNCTION__))
;
1011 }
1012 else if ((operand_less_p (*vr0min, vr1max) == 1
1013 || operand_equal_p (*vr0min, vr1max, 0))
1014 && operand_less_p (vr1min, *vr0min) == 1
1015 && operand_less_p (vr1max, *vr0max) == 1)
1016 {
1017 /* ( [ ) ] or ( )[ ] */
1018 if (*vr0type == VR_ANTI_RANGE
1019 && vr1type == VR_ANTI_RANGE)
1020 *vr0min = vr1min;
1021 else if (*vr0type == VR_RANGE
1022 && vr1type == VR_RANGE)
1023 *vr0max = vr1max;
1024 else if (*vr0type == VR_RANGE
1025 && vr1type == VR_ANTI_RANGE)
1026 {
1027 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
1028 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
1029 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1029, __FUNCTION__))->typed.type)
, 1));
1030 else
1031 *vr0min = vr1max;
1032 }
1033 else if (*vr0type == VR_ANTI_RANGE
1034 && vr1type == VR_RANGE)
1035 {
1036 *vr0type = VR_RANGE;
1037 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
1038 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
1039 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1039, __FUNCTION__))->typed.type)
, 1));
1040 else
1041 *vr0max = *vr0min;
1042 *vr0min = vr1min;
1043 }
1044 else
1045 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1045, __FUNCTION__))
;
1046 }
1047
1048 /* If we know the intersection is empty, there's no need to
1049 conservatively add anything else to the set. */
1050 if (*vr0type == VR_UNDEFINED)
1051 return;
1052
1053 /* As a fallback simply use { *VRTYPE, *VR0MIN, *VR0MAX } as
1054 result for the intersection. That's always a conservative
1055 correct estimate unless VR1 is a constant singleton range
1056 in which case we choose that. */
1057 if (vr1type == VR_RANGE
1058 && is_gimple_min_invariant (vr1min)
1059 && vrp_operand_equal_p (vr1min, vr1max))
1060 {
1061 *vr0type = vr1type;
1062 *vr0min = vr1min;
1063 *vr0max = vr1max;
1064 }
1065}
1066
1067/* Helper for the intersection operation for value ranges. Given two
1068 ranges VR0 and VR1, set VR0 to the intersection of both ranges.
1069 This may not be the smallest possible such range. */
1070
1071void
1072irange::legacy_intersect (irange *vr0, const irange *vr1)
1073{
1074 gcc_checking_assert (vr0->legacy_mode_p ())((void)(!(vr0->legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1074, __FUNCTION__), 0 : 0))
;
1075 gcc_checking_assert (vr1->legacy_mode_p ())((void)(!(vr1->legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1075, __FUNCTION__), 0 : 0))
;
1076 /* If either range is VR_VARYING the other one wins. */
1077 if (vr1->varying_p ())
1078 return;
1079 if (vr0->varying_p ())
1080 {
1081 vr0->set (vr1->min (), vr1->max (), vr1->kind ());
1082 return;
1083 }
1084
1085 /* When either range is VR_UNDEFINED the resulting range is
1086 VR_UNDEFINED, too. */
1087 if (vr0->undefined_p ())
1088 return;
1089 if (vr1->undefined_p ())
1090 {
1091 vr0->set_undefined ();
1092 return;
1093 }
1094
1095 value_range_kind vr0kind = vr0->kind ();
1096 tree vr0min = vr0->min ();
1097 tree vr0max = vr0->max ();
1098
1099 intersect_ranges (&vr0kind, &vr0min, &vr0max,
1100 vr1->kind (), vr1->min (), vr1->max ());
1101
1102 /* Make sure to canonicalize the result though as the inversion of a
1103 VR_RANGE can still be a VR_RANGE. */
1104 if (vr0kind == VR_UNDEFINED)
1105 vr0->set_undefined ();
1106 else if (vr0kind == VR_VARYING)
1107 {
1108 /* If we failed, use the original VR0. */
1109 return;
1110 }
1111 else
1112 vr0->set (vr0min, vr0max, vr0kind);
1113}
1114
1115/* Union the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
1116 { VR1TYPE, VR0MIN, VR0MAX } and store the result
1117 in { *VR0TYPE, *VR0MIN, *VR0MAX }. This may not be the smallest
1118 possible such range. The resulting range is not canonicalized. */
1119
1120static void
1121union_ranges (enum value_range_kind *vr0type,
1122 tree *vr0min, tree *vr0max,
1123 enum value_range_kind vr1type,
1124 tree vr1min, tree vr1max)
1125{
1126 int cmpmin = compare_values (*vr0min, vr1min);
1127 int cmpmax = compare_values (*vr0max, vr1max);
1128 bool mineq = cmpmin == 0;
1129 bool maxeq = cmpmax == 0;
1130
1131 /* [] is vr0, () is vr1 in the following classification comments. */
1132 if (mineq && maxeq)
1133 {
1134 /* [( )] */
1135 if (*vr0type == vr1type)
1136 /* Nothing to do for equal ranges. */
1137 ;
1138 else if ((*vr0type == VR_RANGE
1139 && vr1type == VR_ANTI_RANGE)
1140 || (*vr0type == VR_ANTI_RANGE
1141 && vr1type == VR_RANGE))
1142 {
1143 /* For anti-range with range union the result is varying. */
1144 goto give_up;
1145 }
1146 else
1147 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1147, __FUNCTION__))
;
1148 }
1149 else if (operand_less_p (*vr0max, vr1min) == 1
1150 || operand_less_p (vr1max, *vr0min) == 1)
1151 {
1152 /* [ ] ( ) or ( ) [ ]
1153 If the ranges have an empty intersection, result of the union
1154 operation is the anti-range or if both are anti-ranges
1155 it covers all. */
1156 if (*vr0type == VR_ANTI_RANGE
1157 && vr1type == VR_ANTI_RANGE)
1158 goto give_up;
1159 else if (*vr0type == VR_ANTI_RANGE
1160 && vr1type == VR_RANGE)
1161 ;
1162 else if (*vr0type == VR_RANGE
1163 && vr1type == VR_ANTI_RANGE)
1164 {
1165 *vr0type = vr1type;
1166 *vr0min = vr1min;
1167 *vr0max = vr1max;
1168 }
1169 else if (*vr0type == VR_RANGE
1170 && vr1type == VR_RANGE)
1171 {
1172 /* The result is the convex hull of both ranges. */
1173 if (operand_less_p (*vr0max, vr1min) == 1)
1174 {
1175 /* If the result can be an anti-range, create one. */
1176 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST
1177 && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST
1178 && vrp_val_is_min (*vr0min)
1179 && vrp_val_is_max (vr1max))
1180 {
1181 tree min = int_const_binop (PLUS_EXPR,
1182 *vr0max,
1183 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1183, __FUNCTION__))->typed.type)
, 1));
1184 tree max = int_const_binop (MINUS_EXPR,
1185 vr1min,
1186 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1186, __FUNCTION__))->typed.type)
, 1));
1187 if (!operand_less_p (max, min))
1188 {
1189 *vr0type = VR_ANTI_RANGE;
1190 *vr0min = min;
1191 *vr0max = max;
1192 }
1193 else
1194 *vr0max = vr1max;
1195 }
1196 else
1197 *vr0max = vr1max;
1198 }
1199 else
1200 {
1201 /* If the result can be an anti-range, create one. */
1202 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST
1203 && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST
1204 && vrp_val_is_min (vr1min)
1205 && vrp_val_is_max (*vr0max))
1206 {
1207 tree min = int_const_binop (PLUS_EXPR,
1208 vr1max,
1209 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1209, __FUNCTION__))->typed.type)
, 1));
1210 tree max = int_const_binop (MINUS_EXPR,
1211 *vr0min,
1212 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1212, __FUNCTION__))->typed.type)
, 1));
1213 if (!operand_less_p (max, min))
1214 {
1215 *vr0type = VR_ANTI_RANGE;
1216 *vr0min = min;
1217 *vr0max = max;
1218 }
1219 else
1220 *vr0min = vr1min;
1221 }
1222 else
1223 *vr0min = vr1min;
1224 }
1225 }
1226 else
1227 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1227, __FUNCTION__))
;
1228 }
1229 else if ((maxeq || cmpmax == 1)
1230 && (mineq || cmpmin == -1))
1231 {
1232 /* [ ( ) ] or [( ) ] or [ ( )] */
1233 if (*vr0type == VR_RANGE
1234 && vr1type == VR_RANGE)
1235 ;
1236 else if (*vr0type == VR_ANTI_RANGE
1237 && vr1type == VR_ANTI_RANGE)
1238 {
1239 *vr0type = vr1type;
1240 *vr0min = vr1min;
1241 *vr0max = vr1max;
1242 }
1243 else if (*vr0type == VR_ANTI_RANGE
1244 && vr1type == VR_RANGE)
1245 {
1246 /* Arbitrarily choose the right or left gap. */
1247 if (!mineq && TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
1248 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
1249 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1249, __FUNCTION__))->typed.type)
, 1));
1250 else if (!maxeq && TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
1251 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
1252 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1252, __FUNCTION__))->typed.type)
, 1));
1253 else
1254 goto give_up;
1255 }
1256 else if (*vr0type == VR_RANGE
1257 && vr1type == VR_ANTI_RANGE)
1258 /* The result covers everything. */
1259 goto give_up;
1260 else
1261 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1261, __FUNCTION__))
;
1262 }
1263 else if ((maxeq || cmpmax == -1)
1264 && (mineq || cmpmin == 1))
1265 {
1266 /* ( [ ] ) or ([ ] ) or ( [ ]) */
1267 if (*vr0type == VR_RANGE
1268 && vr1type == VR_RANGE)
1269 {
1270 *vr0type = vr1type;
1271 *vr0min = vr1min;
1272 *vr0max = vr1max;
1273 }
1274 else if (*vr0type == VR_ANTI_RANGE
1275 && vr1type == VR_ANTI_RANGE)
1276 ;
1277 else if (*vr0type == VR_RANGE
1278 && vr1type == VR_ANTI_RANGE)
1279 {
1280 *vr0type = VR_ANTI_RANGE;
1281 if (!mineq && TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
1282 {
1283 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
1284 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1284, __FUNCTION__))->typed.type)
, 1));
1285 *vr0min = vr1min;
1286 }
1287 else if (!maxeq && TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
1288 {
1289 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
1290 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1290, __FUNCTION__))->typed.type)
, 1));
1291 *vr0max = vr1max;
1292 }
1293 else
1294 goto give_up;
1295 }
1296 else if (*vr0type == VR_ANTI_RANGE
1297 && vr1type == VR_RANGE)
1298 /* The result covers everything. */
1299 goto give_up;
1300 else
1301 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1301, __FUNCTION__))
;
1302 }
1303 else if (cmpmin == -1
1304 && cmpmax == -1
1305 && (operand_less_p (vr1min, *vr0max) == 1
1306 || operand_equal_p (vr1min, *vr0max, 0)))
1307 {
1308 /* [ ( ] ) or [ ]( ) */
1309 if (*vr0type == VR_RANGE
1310 && vr1type == VR_RANGE)
1311 *vr0max = vr1max;
1312 else if (*vr0type == VR_ANTI_RANGE
1313 && vr1type == VR_ANTI_RANGE)
1314 *vr0min = vr1min;
1315 else if (*vr0type == VR_ANTI_RANGE
1316 && vr1type == VR_RANGE)
1317 {
1318 if (TREE_CODE (vr1min)((enum tree_code) (vr1min)->base.code) == INTEGER_CST)
1319 *vr0max = int_const_binop (MINUS_EXPR, vr1min,
1320 build_int_cst (TREE_TYPE (vr1min)((contains_struct_check ((vr1min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1320, __FUNCTION__))->typed.type)
, 1));
1321 else
1322 goto give_up;
1323 }
1324 else if (*vr0type == VR_RANGE
1325 && vr1type == VR_ANTI_RANGE)
1326 {
1327 if (TREE_CODE (*vr0max)((enum tree_code) (*vr0max)->base.code) == INTEGER_CST)
1328 {
1329 *vr0type = vr1type;
1330 *vr0min = int_const_binop (PLUS_EXPR, *vr0max,
1331 build_int_cst (TREE_TYPE (*vr0max)((contains_struct_check ((*vr0max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1331, __FUNCTION__))->typed.type)
, 1));
1332 *vr0max = vr1max;
1333 }
1334 else
1335 goto give_up;
1336 }
1337 else
1338 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1338, __FUNCTION__))
;
1339 }
1340 else if (cmpmin == 1
1341 && cmpmax == 1
1342 && (operand_less_p (*vr0min, vr1max) == 1
1343 || operand_equal_p (*vr0min, vr1max, 0)))
1344 {
1345 /* ( [ ) ] or ( )[ ] */
1346 if (*vr0type == VR_RANGE
1347 && vr1type == VR_RANGE)
1348 *vr0min = vr1min;
1349 else if (*vr0type == VR_ANTI_RANGE
1350 && vr1type == VR_ANTI_RANGE)
1351 *vr0max = vr1max;
1352 else if (*vr0type == VR_ANTI_RANGE
1353 && vr1type == VR_RANGE)
1354 {
1355 if (TREE_CODE (vr1max)((enum tree_code) (vr1max)->base.code) == INTEGER_CST)
1356 *vr0min = int_const_binop (PLUS_EXPR, vr1max,
1357 build_int_cst (TREE_TYPE (vr1max)((contains_struct_check ((vr1max), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1357, __FUNCTION__))->typed.type)
, 1));
1358 else
1359 goto give_up;
1360 }
1361 else if (*vr0type == VR_RANGE
1362 && vr1type == VR_ANTI_RANGE)
1363 {
1364 if (TREE_CODE (*vr0min)((enum tree_code) (*vr0min)->base.code) == INTEGER_CST)
1365 {
1366 *vr0type = vr1type;
1367 *vr0max = int_const_binop (MINUS_EXPR, *vr0min,
1368 build_int_cst (TREE_TYPE (*vr0min)((contains_struct_check ((*vr0min), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1368, __FUNCTION__))->typed.type)
, 1));
1369 *vr0min = vr1min;
1370 }
1371 else
1372 goto give_up;
1373 }
1374 else
1375 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1375, __FUNCTION__))
;
1376 }
1377 else
1378 goto give_up;
1379
1380 return;
1381
1382give_up:
1383 *vr0type = VR_VARYING;
1384 *vr0min = NULL_TREE(tree) nullptr;
1385 *vr0max = NULL_TREE(tree) nullptr;
1386}
1387
1388/* Helper for meet operation for value ranges. Given two ranges VR0
1389 and VR1, set VR0 to the union of both ranges. This may not be the
1390 smallest possible such range. */
1391
1392void
1393irange::legacy_union (irange *vr0, const irange *vr1)
1394{
1395 gcc_checking_assert (vr0->legacy_mode_p ())((void)(!(vr0->legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1395, __FUNCTION__), 0 : 0))
;
1396 gcc_checking_assert (vr1->legacy_mode_p ())((void)(!(vr1->legacy_mode_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1396, __FUNCTION__), 0 : 0))
;
1397
1398 /* VR0 has the resulting range if VR1 is undefined or VR0 is varying. */
1399 if (vr1->undefined_p ()
1400 || vr0->varying_p ())
1401 return;
1402
1403 /* VR1 has the resulting range if VR0 is undefined or VR1 is varying. */
1404 if (vr0->undefined_p ())
1405 {
1406 vr0->set (vr1->min (), vr1->max (), vr1->kind ());
1407 return;
1408 }
1409
1410 if (vr1->varying_p ())
1411 {
1412 vr0->set_varying (vr1->type ());
1413 return;
1414 }
1415
1416 value_range_kind vr0kind = vr0->kind ();
1417 tree vr0min = vr0->min ();
1418 tree vr0max = vr0->max ();
1419
1420 union_ranges (&vr0kind, &vr0min, &vr0max,
1421 vr1->kind (), vr1->min (), vr1->max ());
1422
1423 if (vr0kind == VR_UNDEFINED)
1424 vr0->set_undefined ();
1425 else if (vr0kind == VR_VARYING)
1426 {
1427 /* Failed to find an efficient meet. Before giving up and
1428 setting the result to VARYING, see if we can at least derive
1429 a non-zero range. */
1430 if (range_includes_zero_p (vr0) == 0
1431 && range_includes_zero_p (vr1) == 0)
1432 vr0->set_nonzero (vr0->type ());
1433 else
1434 vr0->set_varying (vr0->type ());
1435 }
1436 else
1437 vr0->set (vr0min, vr0max, vr0kind);
1438}
1439
1440/* Meet operation for value ranges. Given two value ranges VR0 and
1441 VR1, store in VR0 a range that contains both VR0 and VR1. This
1442 may not be the smallest possible such range. */
1443
1444void
1445irange::union_ (const irange *other)
1446{
1447 if (legacy_mode_p ())
1448 {
1449 if (!other->legacy_mode_p ())
1450 {
1451 int_range<1> tmp = *other;
1452 legacy_union (this, &tmp);
1453 return;
1454 }
1455 if (dump_file && (dump_flags & TDF_DETAILS))
1456 {
1457 fprintf (dump_file, "Meeting\n ");
1458 dump_value_range (dump_file, this);
1459 fprintf (dump_file, "\nand\n ");
1460 dump_value_range (dump_file, other);
1461 fprintf (dump_file, "\n");
1462 }
1463
1464 legacy_union (this, other);
1465
1466 if (dump_file && (dump_flags & TDF_DETAILS))
1467 {
1468 fprintf (dump_file, "to\n ");
1469 dump_value_range (dump_file, this);
1470 fprintf (dump_file, "\n");
1471 }
1472 return;
1473 }
1474
1475 if (other->legacy_mode_p ())
1476 {
1477 int_range<2> wider = *other;
1478 irange_union (wider);
1479 }
1480 else
1481 irange_union (*other);
1482}
1483
1484void
1485irange::intersect (const irange *other)
1486{
1487 if (legacy_mode_p ())
1488 {
1489 if (!other->legacy_mode_p ())
1490 {
1491 int_range<1> tmp = *other;
1492 legacy_intersect (this, &tmp);
1493 return;
1494 }
1495 if (dump_file && (dump_flags & TDF_DETAILS))
1496 {
1497 fprintf (dump_file, "Intersecting\n ");
1498 dump_value_range (dump_file, this);
1499 fprintf (dump_file, "\nand\n ");
1500 dump_value_range (dump_file, other);
1501 fprintf (dump_file, "\n");
1502 }
1503
1504 legacy_intersect (this, other);
1505
1506 if (dump_file && (dump_flags & TDF_DETAILS))
1507 {
1508 fprintf (dump_file, "to\n ");
1509 dump_value_range (dump_file, this);
1510 fprintf (dump_file, "\n");
1511 }
1512 return;
1513 }
1514
1515 if (other->legacy_mode_p ())
1516 {
1517 int_range<2> wider;
1518 wider = *other;
1519 irange_intersect (wider);
1520 }
1521 else
1522 irange_intersect (*other);
1523}
1524
1525// union_ for multi-ranges.
1526
1527void
1528irange::irange_union (const irange &r)
1529{
1530 gcc_checking_assert (!legacy_mode_p () && !r.legacy_mode_p ())((void)(!(!legacy_mode_p () && !r.legacy_mode_p ()) ?
fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1530, __FUNCTION__), 0 : 0))
;
1531
1532 if (r.undefined_p () || varying_p ())
1533 return;
1534
1535 if (undefined_p () || r.varying_p ())
1536 {
1537 operator= (r);
1538 return;
1539 }
1540
1541 // Do not worry about merging and such by reserving twice as many
1542 // pairs as needed, and then simply sort the 2 ranges into this
1543 // intermediate form.
1544 //
1545 // The intermediate result will have the property that the beginning
1546 // of each range is <= the beginning of the next range. There may
1547 // be overlapping ranges at this point. I.e. this would be valid
1548 // [-20, 10], [-10, 0], [0, 20], [40, 90] as it satisfies this
1549 // contraint : -20 < -10 < 0 < 40. When the range is rebuilt into r,
1550 // the merge is performed.
1551 //
1552 // [Xi,Yi]..[Xn,Yn] U [Xj,Yj]..[Xm,Ym] --> [Xk,Yk]..[Xp,Yp]
1553 tree ttype = r.type ();
1554 signop sign = TYPE_SIGN (ttype)((signop) ((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1554, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1555
1556 auto_vec<tree, 20> res;
1557 wide_int u1 ;
1558 wi::overflow_type ovf;
1559 unsigned i = 0, j = 0, k = 0;
1560
1561 while (i < m_num_ranges * 2 && j < r.m_num_ranges * 2)
1562 {
1563 // lower of Xi and Xj is the lowest point.
1564 if (wi::le_p (wi::to_wide (m_base[i]), wi::to_wide (r.m_base[j]), sign))
1565 {
1566 res.safe_push (m_base[i]);
1567 res.safe_push (m_base[i + 1]);
1568 k += 2;
1569 i += 2;
1570 }
1571 else
1572 {
1573 res.safe_push (r.m_base[j]);
1574 res.safe_push (r.m_base[j + 1]);
1575 k += 2;
1576 j += 2;
1577 }
1578 }
1579 for ( ; i < m_num_ranges * 2; i += 2)
1580 {
1581 res.safe_push (m_base[i]);
1582 res.safe_push (m_base[i + 1]);
1583 k += 2;
1584 }
1585 for ( ; j < r.m_num_ranges * 2; j += 2)
1586 {
1587 res.safe_push (r.m_base[j]);
1588 res.safe_push (r.m_base[j + 1]);
1589 k += 2;
1590 }
1591
1592 // Now normalize the vector removing any overlaps.
1593 i = 2;
1594 int prec = TYPE_PRECISION (ttype)((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1594, __FUNCTION__))->type_common.precision)
;
1595 wide_int max_val = wi::max_value (prec, sign);
1596 for (j = 2; j < k ; j += 2)
1597 {
1598 wide_int val_im1 = wi::to_wide (res[i - 1]);
1599 if (val_im1 == max_val)
1600 break;
1601 u1 = wi::add (val_im1, 1, sign, &ovf);
1602
1603 // Overflow indicates we are at MAX already.
1604 // A wide int bug requires the previous max_val check
1605 // trigger: gcc.c-torture/compile/pr80443.c with -O3
1606 if (ovf == wi::OVF_OVERFLOW)
1607 break;
1608
1609 wide_int val_j = wi::to_wide (res[j]);
1610 wide_int val_jp1 = wi::to_wide (res[j+1]);
1611 // Current upper+1 is >= lower bound next pair, then we merge ranges.
1612 if (wi::ge_p (u1, val_j, sign))
1613 {
1614 // New upper bounds is greater of current or the next one.
1615 if (wi::gt_p (val_jp1, val_im1, sign))
1616 res [i - 1] = res[j + 1];
1617 }
1618 else
1619 {
1620 // This is a new distinct range, but no point in copying it
1621 // if it is already in the right place.
1622 if (i != j)
1623 {
1624 res[i++] = res[j];
1625 res[i++] = res[j + 1];
1626 }
1627 else
1628 i += 2;
1629 }
1630 }
1631
1632 // At this point, the vector should have i ranges, none overlapping.
1633 // Now it simply needs to be copied, and if there are too many
1634 // ranges, merge some. We wont do any analysis as to what the
1635 // "best" merges are, simply combine the final ranges into one.
1636 if (i > m_max_ranges * 2)
1637 {
1638 res[m_max_ranges * 2 - 1] = res[i - 1];
1639 i = m_max_ranges * 2;
1640 }
1641
1642 for (j = 0; j < i ; j++)
1643 m_base[j] = res [j];
1644 m_num_ranges = i / 2;
1645
1646 m_kind = VR_RANGE;
1647 normalize_kind ();
1648
1649 if (flag_checkingglobal_options.x_flag_checking)
1650 verify_range ();
1651}
1652
1653// intersect for multi-ranges.
1654
1655void
1656irange::irange_intersect (const irange &r)
1657{
1658 gcc_checking_assert (!legacy_mode_p () && !r.legacy_mode_p ())((void)(!(!legacy_mode_p () && !r.legacy_mode_p ()) ?
fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1658, __FUNCTION__), 0 : 0))
;
1659 gcc_checking_assert (undefined_p () || r.undefined_p ()((void)(!(undefined_p () || r.undefined_p () || range_compatible_p
(type (), r.type ())) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1660, __FUNCTION__), 0 : 0))
1660 || range_compatible_p (type (), r.type ()))((void)(!(undefined_p () || r.undefined_p () || range_compatible_p
(type (), r.type ())) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1660, __FUNCTION__), 0 : 0))
;
1661
1662 if (undefined_p () || r.varying_p ())
1663 return;
1664 if (r.undefined_p ())
1665 {
1666 set_undefined ();
1667 return;
1668 }
1669 if (varying_p ())
1670 {
1671 operator= (r);
1672 return;
1673 }
1674
1675 if (r.num_pairs () == 1)
1676 {
1677 // R cannot be undefined, use more efficent pair routine.
1678 intersect (r.lower_bound(), r.upper_bound ());
1679 return;
1680 }
1681
1682 signop sign = TYPE_SIGN (TREE_TYPE(m_base[0]))((signop) ((tree_class_check ((((contains_struct_check ((m_base
[0]), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1682, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1682, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1683 unsigned bld_pair = 0;
1684 unsigned bld_lim = m_max_ranges;
1685 int_range_max r2 (*this);
1686 unsigned r2_lim = r2.num_pairs ();
1687 unsigned i2 = 0;
1688 for (unsigned i = 0; i < r.num_pairs (); )
1689 {
1690 // If r1's upper is < r2's lower, we can skip r1's pair.
1691 tree ru = r.m_base[i * 2 + 1];
1692 tree r2l = r2.m_base[i2 * 2];
1693 if (wi::lt_p (wi::to_wide (ru), wi::to_wide (r2l), sign))
1694 {
1695 i++;
1696 continue;
1697 }
1698 // Likewise, skip r2's pair if its excluded.
1699 tree r2u = r2.m_base[i2 * 2 + 1];
1700 tree rl = r.m_base[i * 2];
1701 if (wi::lt_p (wi::to_wide (r2u), wi::to_wide (rl), sign))
1702 {
1703 i2++;
1704 if (i2 < r2_lim)
1705 continue;
1706 // No more r2, break.
1707 break;
1708 }
1709
1710 // Must be some overlap. Find the highest of the lower bounds,
1711 // and set it, unless the build limits lower bounds is already
1712 // set.
1713 if (bld_pair < bld_lim)
1714 {
1715 if (wi::ge_p (wi::to_wide (rl), wi::to_wide (r2l), sign))
1716 m_base[bld_pair * 2] = rl;
1717 else
1718 m_base[bld_pair * 2] = r2l;
1719 }
1720 else
1721 // Decrease and set a new upper.
1722 bld_pair--;
1723
1724 // ...and choose the lower of the upper bounds.
1725 if (wi::le_p (wi::to_wide (ru), wi::to_wide (r2u), sign))
1726 {
1727 m_base[bld_pair * 2 + 1] = ru;
1728 bld_pair++;
1729 // Move past the r1 pair and keep trying.
1730 i++;
1731 continue;
1732 }
1733 else
1734 {
1735 m_base[bld_pair * 2 + 1] = r2u;
1736 bld_pair++;
1737 i2++;
1738 if (i2 < r2_lim)
1739 continue;
1740 // No more r2, break.
1741 break;
1742 }
1743 // r2 has the higher lower bound.
1744 }
1745
1746 // At the exit of this loop, it is one of 2 things:
1747 // ran out of r1, or r2, but either means we are done.
1748 m_num_ranges = bld_pair;
1749
1750 m_kind = VR_RANGE;
1751 normalize_kind ();
1752
1753 if (flag_checkingglobal_options.x_flag_checking)
1754 verify_range ();
1755}
1756
1757// Multirange intersect for a specified wide_int [lb, ub] range.
1758
1759void
1760irange::intersect (const wide_int& lb, const wide_int& ub)
1761{
1762 // Undefined remains undefined.
1763 if (undefined_p ())
1764 return;
1765
1766 if (legacy_mode_p ())
1767 {
1768 intersect (int_range<1> (type (), lb, ub));
1769 return;
1770 }
1771
1772 tree range_type = type();
1773 signop sign = TYPE_SIGN (range_type)((signop) ((tree_class_check ((range_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1773, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1774
1775 gcc_checking_assert (TYPE_PRECISION (range_type) == wi::get_precision (lb))((void)(!(((tree_class_check ((range_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1775, __FUNCTION__))->type_common.precision) == wi::get_precision
(lb)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1775, __FUNCTION__), 0 : 0))
;
1776 gcc_checking_assert (TYPE_PRECISION (range_type) == wi::get_precision (ub))((void)(!(((tree_class_check ((range_type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1776, __FUNCTION__))->type_common.precision) == wi::get_precision
(ub)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1776, __FUNCTION__), 0 : 0))
;
1777
1778 unsigned bld_index = 0;
1779 unsigned pair_lim = num_pairs ();
1780 for (unsigned i = 0; i < pair_lim; i++)
1781 {
1782 tree pairl = m_base[i * 2];
1783 tree pairu = m_base[i * 2 + 1];
1784 // Once UB is less than a pairs lower bound, we're done.
1785 if (wi::lt_p (ub, wi::to_wide (pairl), sign))
1786 break;
1787 // if LB is greater than this pairs upper, this pair is excluded.
1788 if (wi::lt_p (wi::to_wide (pairu), lb, sign))
1789 continue;
1790
1791 // Must be some overlap. Find the highest of the lower bounds,
1792 // and set it
1793 if (wi::gt_p (lb, wi::to_wide (pairl), sign))
1794 m_base[bld_index * 2] = wide_int_to_tree (range_type, lb);
1795 else
1796 m_base[bld_index * 2] = pairl;
1797
1798 // ...and choose the lower of the upper bounds and if the base pair
1799 // has the lower upper bound, need to check next pair too.
1800 if (wi::lt_p (ub, wi::to_wide (pairu), sign))
1801 {
1802 m_base[bld_index++ * 2 + 1] = wide_int_to_tree (range_type, ub);
1803 break;
1804 }
1805 else
1806 m_base[bld_index++ * 2 + 1] = pairu;
1807 }
1808
1809 m_num_ranges = bld_index;
1810
1811 m_kind = VR_RANGE;
1812 normalize_kind ();
1813
1814 if (flag_checkingglobal_options.x_flag_checking)
1815 verify_range ();
1816}
1817// Signed 1-bits are strange. You can't subtract 1, because you can't
1818// represent the number 1. This works around that for the invert routine.
1819
1820static wide_int inline
1821subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow)
1822{
1823 if (TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1823, __FUNCTION__))->base.u.bits.unsigned_flag))
== SIGNED)
1824 return wi::add (x, -1, SIGNED, &overflow);
1825 else
1826 return wi::sub (x, 1, UNSIGNED, &overflow);
1827}
1828
1829// The analogous function for adding 1.
1830
1831static wide_int inline
1832add_one (const wide_int &x, tree type, wi::overflow_type &overflow)
1833{
1834 if (TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1834, __FUNCTION__))->base.u.bits.unsigned_flag))
== SIGNED)
1835 return wi::sub (x, -1, SIGNED, &overflow);
1836 else
1837 return wi::add (x, 1, UNSIGNED, &overflow);
1838}
1839
1840// Return the inverse of a range.
1841
1842void
1843irange::invert ()
1844{
1845 if (legacy_mode_p ())
1846 {
1847 // We can't just invert VR_RANGE and VR_ANTI_RANGE because we may
1848 // create non-canonical ranges. Use the constructors instead.
1849 if (m_kind == VR_RANGE)
1850 *this = value_range (min (), max (), VR_ANTI_RANGE);
1851 else if (m_kind == VR_ANTI_RANGE)
1852 *this = value_range (min (), max ());
1853 else
1854 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1854, __FUNCTION__))
;
1855 return;
1856 }
1857
1858 gcc_checking_assert (!undefined_p () && !varying_p ())((void)(!(!undefined_p () && !varying_p ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1858, __FUNCTION__), 0 : 0))
;
1859
1860 // We always need one more set of bounds to represent an inverse, so
1861 // if we're at the limit, we can't properly represent things.
1862 //
1863 // For instance, to represent the inverse of a 2 sub-range set
1864 // [5, 10][20, 30], we would need a 3 sub-range set
1865 // [-MIN, 4][11, 19][31, MAX].
1866 //
1867 // In this case, return the most conservative thing.
1868 //
1869 // However, if any of the extremes of the range are -MIN/+MAX, we
1870 // know we will not need an extra bound. For example:
1871 //
1872 // INVERT([-MIN,20][30,40]) => [21,29][41,+MAX]
1873 // INVERT([-MIN,20][30,MAX]) => [21,29]
1874 tree ttype = type ();
1875 unsigned prec = TYPE_PRECISION (ttype)((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1875, __FUNCTION__))->type_common.precision)
;
1876 signop sign = TYPE_SIGN (ttype)((signop) ((tree_class_check ((ttype), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1876, __FUNCTION__))->base.u.bits.unsigned_flag))
;
1877 wide_int type_min = wi::min_value (prec, sign);
1878 wide_int type_max = wi::max_value (prec, sign);
1879 if (m_num_ranges == m_max_ranges
1880 && lower_bound () != type_min
1881 && upper_bound () != type_max)
1882 {
1883 m_base[1] = wide_int_to_tree (ttype, type_max);
1884 m_num_ranges = 1;
1885 return;
1886 }
1887 // The algorithm is as follows. To calculate INVERT ([a,b][c,d]), we
1888 // generate [-MIN, a-1][b+1, c-1][d+1, MAX].
1889 //
1890 // If there is an over/underflow in the calculation for any
1891 // sub-range, we eliminate that subrange. This allows us to easily
1892 // calculate INVERT([-MIN, 5]) with: [-MIN, -MIN-1][6, MAX]. And since
1893 // we eliminate the underflow, only [6, MAX] remains.
1894 unsigned i = 0;
1895 wi::overflow_type ovf;
1896 // Construct leftmost range.
1897 int_range_max orig_range (*this);
1898 unsigned nitems = 0;
1899 wide_int tmp;
1900 // If this is going to underflow on the MINUS 1, don't even bother
1901 // checking. This also handles subtracting one from an unsigned 0,
1902 // which doesn't set the underflow bit.
1903 if (type_min != orig_range.lower_bound ())
1904 {
1905 m_base[nitems++] = wide_int_to_tree (ttype, type_min);
1906 tmp = subtract_one (orig_range.lower_bound (), ttype, ovf);
1907 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
1908 if (ovf)
1909 nitems = 0;
1910 }
1911 i++;
1912 // Construct middle ranges if applicable.
1913 if (orig_range.num_pairs () > 1)
1914 {
1915 unsigned j = i;
1916 for (; j < (orig_range.num_pairs () * 2) - 1; j += 2)
1917 {
1918 // The middle ranges cannot have MAX/MIN, so there's no need
1919 // to check for unsigned overflow on the +1 and -1 here.
1920 tmp = wi::add (wi::to_wide (orig_range.m_base[j]), 1, sign, &ovf);
1921 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
1922 tmp = subtract_one (wi::to_wide (orig_range.m_base[j + 1]),
1923 ttype, ovf);
1924 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
1925 if (ovf)
1926 nitems -= 2;
1927 }
1928 i = j;
1929 }
1930 // Construct rightmost range.
1931 //
1932 // However, if this will overflow on the PLUS 1, don't even bother.
1933 // This also handles adding one to an unsigned MAX, which doesn't
1934 // set the overflow bit.
1935 if (type_max != wi::to_wide (orig_range.m_base[i]))
1936 {
1937 tmp = add_one (wi::to_wide (orig_range.m_base[i]), ttype, ovf);
1938 m_base[nitems++] = wide_int_to_tree (ttype, tmp);
1939 m_base[nitems++] = wide_int_to_tree (ttype, type_max);
1940 if (ovf)
1941 nitems -= 2;
1942 }
1943 m_num_ranges = nitems / 2;
1944
1945 // We disallow undefined or varying coming in, so the result can
1946 // only be a VR_RANGE.
1947 gcc_checking_assert (m_kind == VR_RANGE)((void)(!(m_kind == VR_RANGE) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1947, __FUNCTION__), 0 : 0))
;
1948
1949 if (flag_checkingglobal_options.x_flag_checking)
1950 verify_range ();
1951}
1952
1953static void
1954dump_bound_with_infinite_markers (FILE *file, tree bound)
1955{
1956 tree type = TREE_TYPE (bound)((contains_struct_check ((bound), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1956, __FUNCTION__))->typed.type)
;
1957 wide_int type_min = wi::min_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1957, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1957, __FUNCTION__))->base.u.bits.unsigned_flag))
);
1958 wide_int type_max = wi::max_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1958, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1958, __FUNCTION__))->base.u.bits.unsigned_flag))
);
1959
1960 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)
1961 && !TYPE_UNSIGNED (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1961, __FUNCTION__))->base.u.bits.unsigned_flag)
1962 && TREE_CODE (bound)((enum tree_code) (bound)->base.code) == INTEGER_CST
1963 && wi::to_wide (bound) == type_min
1964 && TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1964, __FUNCTION__))->type_common.precision)
!= 1)
1965 fprintf (file, "-INF");
1966 else if (TREE_CODE (bound)((enum tree_code) (bound)->base.code) == INTEGER_CST
1967 && wi::to_wide (bound) == type_max
1968 && TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 1968, __FUNCTION__))->type_common.precision)
!= 1)
1969 fprintf (file, "+INF");
1970 else
1971 print_generic_expr (file, bound);
1972}
1973
1974void
1975irange::dump (FILE *file) const
1976{
1977 if (undefined_p ())
1978 {
1979 fprintf (file, "UNDEFINED");
1980 return;
1981 }
1982 print_generic_expr (file, type ());
1983 fprintf (file, " ");
1984 if (varying_p ())
1985 {
1986 fprintf (file, "VARYING");
1987 return;
1988 }
1989 if (legacy_mode_p ())
1990 {
1991 fprintf (file, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
1992 dump_bound_with_infinite_markers (file, min ());
1993 fprintf (file, ", ");
1994 dump_bound_with_infinite_markers (file, max ());
1995 fprintf (file, "]");
1996 return;
1997 }
1998 for (unsigned i = 0; i < m_num_ranges; ++i)
1999 {
2000 tree lb = m_base[i * 2];
2001 tree ub = m_base[i * 2 + 1];
2002 fprintf (file, "[");
2003 dump_bound_with_infinite_markers (file, lb);
2004 fprintf (file, ", ");
2005 dump_bound_with_infinite_markers (file, ub);
2006 fprintf (file, "]");
2007 }
2008}
2009
2010void
2011irange::debug () const
2012{
2013 dump (stderrstderr);
2014 fprintf (stderrstderr, "\n");
2015}
2016
2017void
2018dump_value_range (FILE *file, const irange *vr)
2019{
2020 vr->dump (file);
2021}
2022
2023DEBUG_FUNCTION__attribute__ ((__used__)) void
2024debug (const irange *vr)
2025{
2026 dump_value_range (stderrstderr, vr);
2027 fprintf (stderrstderr, "\n");
2028}
2029
2030DEBUG_FUNCTION__attribute__ ((__used__)) void
2031debug (const irange &vr)
2032{
2033 debug (&vr);
2034}
2035
2036DEBUG_FUNCTION__attribute__ ((__used__)) void
2037debug (const value_range *vr)
2038{
2039 dump_value_range (stderrstderr, vr);
2040 fprintf (stderrstderr, "\n");
2041}
2042
2043DEBUG_FUNCTION__attribute__ ((__used__)) void
2044debug (const value_range &vr)
2045{
2046 dump_value_range (stderrstderr, &vr);
2047 fprintf (stderrstderr, "\n");
2048}
2049
2050/* Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
2051 so that *VR0 U *VR1 == *AR. Returns true if that is possible,
2052 false otherwise. If *AR can be represented with a single range
2053 *VR1 will be VR_UNDEFINED. */
2054
2055bool
2056ranges_from_anti_range (const value_range *ar,
2057 value_range *vr0, value_range *vr1)
2058{
2059 tree type = ar->type ();
2060
2061 vr0->set_undefined ();
2062 vr1->set_undefined ();
2063
2064 /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
2065 [A+1, +INF]. Not sure if this helps in practice, though. */
2066
2067 if (ar->kind () != VR_ANTI_RANGE
2068 || TREE_CODE (ar->min ())((enum tree_code) (ar->min ())->base.code) != INTEGER_CST
2069 || TREE_CODE (ar->max ())((enum tree_code) (ar->max ())->base.code) != INTEGER_CST
2070 || !vrp_val_min (type)
2071 || !vrp_val_max (type))
2072 return false;
2073
2074 if (tree_int_cst_lt (vrp_val_min (type), ar->min ()))
2075 vr0->set (vrp_val_min (type),
2076 wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
2077 if (tree_int_cst_lt (ar->max (), vrp_val_max (type)))
2078 vr1->set (wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
2079 vrp_val_max (type));
2080 if (vr0->undefined_p ())
2081 {
2082 *vr0 = *vr1;
2083 vr1->set_undefined ();
2084 }
2085
2086 return !vr0->undefined_p ();
2087}
2088
2089bool
2090range_has_numeric_bounds_p (const irange *vr)
2091{
2092 return (!vr->undefined_p ()
2093 && TREE_CODE (vr->min ())((enum tree_code) (vr->min ())->base.code) == INTEGER_CST
2094 && TREE_CODE (vr->max ())((enum tree_code) (vr->max ())->base.code) == INTEGER_CST);
2095}
2096
2097/* Return whether VAL is equal to the maximum value of its type.
2098 We can't do a simple equality comparison with TYPE_MAX_VALUE because
2099 C typedefs and Ada subtypes can produce types whose TYPE_MAX_VALUE
2100 is not == to the integer constant with the same value in the type. */
2101
2102bool
2103vrp_val_is_max (const_tree val)
2104{
2105 tree type_max = vrp_val_max (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2105, __FUNCTION__))->typed.type)
);
2106 return (val == type_max
2107 || (type_max != NULL_TREE(tree) nullptr
2108 && operand_equal_p (val, type_max, 0)));
2109}
2110
2111/* Return whether VAL is equal to the minimum value of its type. */
2112
2113bool
2114vrp_val_is_min (const_tree val)
2115{
2116 tree type_min = vrp_val_min (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2116, __FUNCTION__))->typed.type)
);
2117 return (val == type_min
2118 || (type_min != NULL_TREE(tree) nullptr
2119 && operand_equal_p (val, type_min, 0)));
2120}
2121
2122/* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
2123
2124bool
2125vrp_operand_equal_p (const_tree val1, const_tree val2)
2126{
2127 if (val1 == val2)
2128 return true;
2129 if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
2130 return false;
2131 return true;
2132}
2133
2134// ?? These stubs are for ipa-prop.c which use a value_range in a
2135// hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
2136// instead of picking up the gt_ggc_mx (T *) version.
2137void
2138gt_pch_nx (int_range<1> *&x)
2139{
2140 return gt_pch_nx ((irange *) x);
2141}
2142
2143void
2144gt_ggc_mx (int_range<1> *&x)
2145{
2146 return gt_ggc_mx ((irange *) x);
2147}
2148
2149#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 &);
\
2150 template int_range<N>::int_range(tree, tree, value_range_kind); \
2151 template int_range<N>::int_range(tree_node *, \
2152 const wide_int &, \
2153 const wide_int &, \
2154 value_range_kind); \
2155 template int_range<N>::int_range(tree); \
2156 template int_range<N>::int_range(const irange &); \
2157 template int_range<N>::int_range(const int_range &); \
2158 template int_range<N>& int_range<N>::operator= (const int_range &);
2159
2160DEFINE_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 &);
2161DEFINE_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 &);
2162DEFINE_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 &);
2163DEFINE_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
&);
2164
2165#if CHECKING_P1
2166#include "selftest.h"
2167
2168namespace selftest
2169{
2170#define INT(N)build_int_cst (integer_types[itk_int], (N)) build_int_cst (integer_type_nodeinteger_types[itk_int], (N))
2171#define UINT(N)build_int_cstu (integer_types[itk_unsigned_int], (N)) build_int_cstu (unsigned_type_nodeinteger_types[itk_unsigned_int], (N))
2172#define UINT128(N)build_int_cstu (u128_type, (N)) build_int_cstu (u128_type, (N))
2173#define UCHAR(N)build_int_cstu (integer_types[itk_unsigned_char], (N)) build_int_cstu (unsigned_char_type_nodeinteger_types[itk_unsigned_char], (N))
2174#define SCHAR(N)build_int_cst (integer_types[itk_signed_char], (N)) build_int_cst (signed_char_type_nodeinteger_types[itk_signed_char], (N))
2175
2176static int_range<3>
2177build_range3 (int a, int b, int c, int d, int e, int f)
2178{
2179 int_range<3> i1 (INT (a)build_int_cst (integer_types[itk_int], (a)), INT (b)build_int_cst (integer_types[itk_int], (b)));
2180 int_range<3> i2 (INT (c)build_int_cst (integer_types[itk_int], (c)), INT (d)build_int_cst (integer_types[itk_int], (d)));
2181 int_range<3> i3 (INT (e)build_int_cst (integer_types[itk_int], (e)), INT (f)build_int_cst (integer_types[itk_int], (f)));
2182 i1.union_ (i2);
2183 i1.union_ (i3);
2184 return i1;
2185}
2186
2187static void
2188range_tests_irange3 ()
2189{
2190 typedef int_range<3> int_range3;
2191 int_range3 r0, r1, r2;
2192 int_range3 i1, i2, i3;
2193
2194 // ([10,20] U [5,8]) U [1,3] ==> [1,3][5,8][10,20].
2195 r0 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2196 r1 = int_range3 (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (8)build_int_cst (integer_types[itk_int], (8)));
2197 r0.union_ (r1);
2198 r1 = int_range3 (INT (1)build_int_cst (integer_types[itk_int], (1)), INT (3)build_int_cst (integer_types[itk_int], (3)));
2199 r0.union_ (r1);
2200 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2200, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2200, __FUNCTION__))), desc_); } while (0)
;
2201
2202 // [1,3][5,8][10,20] U [-5,0] => [-5,3][5,8][10,20].
2203 r1 = int_range3 (INT (-5)build_int_cst (integer_types[itk_int], (-5)), INT (0)build_int_cst (integer_types[itk_int], (0)));
2204 r0.union_ (r1);
2205 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2205, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2205, __FUNCTION__))), desc_); } while (0)
;
2206
2207 // [10,20][30,40] U [50,60] ==> [10,20][30,40][50,60].
2208 r1 = int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60)));
2209 r0 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2210 r0.union_ (int_range3 (INT (30)build_int_cst (integer_types[itk_int], (30)), INT (40)build_int_cst (integer_types[itk_int], (40))));
2211 r0.union_ (r1);
2212 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
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2212, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2212, __FUNCTION__))), desc_); } while (0)
;
2213 // [10,20][30,40][50,60] U [70, 80] ==> [10,20][30,40][50,60][70,80].
2214 r1 = int_range3 (INT (70)build_int_cst (integer_types[itk_int], (70)), INT (80)build_int_cst (integer_types[itk_int], (80)));
2215 r0.union_ (r1);
2216
2217 r2 = build_range3 (10, 20, 30, 40, 50, 60);
2218 r2.union_ (int_range3 (INT (70)build_int_cst (integer_types[itk_int], (70)), INT (80)build_int_cst (integer_types[itk_int], (80))));
2219 ASSERT_TRUE (r0 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r2)" ")"; bool
actual_ = ((r0 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2219, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2219, __FUNCTION__))), desc_); } while (0)
;
2220
2221 // [10,20][30,40][50,60] U [6,35] => [6,40][50,60].
2222 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2223 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (35)build_int_cst (integer_types[itk_int], (35)));
2224 r0.union_ (r1);
2225 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (40)build_int_cst (integer_types[itk_int], (40)));
2226 r1.union_ (int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60))));
2227 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2227, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2227, __FUNCTION__))), desc_); } while (0)
;
2228
2229 // [10,20][30,40][50,60] U [6,60] => [6,60].
2230 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2231 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (60)build_int_cst (integer_types[itk_int], (60)));
2232 r0.union_ (r1);
2233 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2233, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2233, __FUNCTION__))), desc_); } while (0)
;
2234
2235 // [10,20][30,40][50,60] U [6,70] => [6,70].
2236 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2237 r1 = int_range3 (INT (6)build_int_cst (integer_types[itk_int], (6)), INT (70)build_int_cst (integer_types[itk_int], (70)));
2238 r0.union_ (r1);
2239 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2239, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2239, __FUNCTION__))), desc_); } while (0)
;
2240
2241 // [10,20][30,40][50,60] U [35,70] => [10,20][30,70].
2242 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2243 r1 = int_range3 (INT (35)build_int_cst (integer_types[itk_int], (35)), INT (70)build_int_cst (integer_types[itk_int], (70)));
2244 r0.union_ (r1);
2245 r1 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2246 r1.union_ (int_range3 (INT (30)build_int_cst (integer_types[itk_int], (30)), INT (70)build_int_cst (integer_types[itk_int], (70))));
2247 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2247, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2247, __FUNCTION__))), desc_); } while (0)
;
2248
2249 // [10,20][30,40][50,60] U [15,35] => [10,40][50,60].
2250 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2251 r1 = int_range3 (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (35)build_int_cst (integer_types[itk_int], (35)));
2252 r0.union_ (r1);
2253 r1 = int_range3 (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (40)build_int_cst (integer_types[itk_int], (40)));
2254 r1.union_ (int_range3 (INT (50)build_int_cst (integer_types[itk_int], (50)), INT (60)build_int_cst (integer_types[itk_int], (60))));
2255 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2255, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2255, __FUNCTION__))), desc_); } while (0)
;
2256
2257 // [10,20][30,40][50,60] U [35,35] => [10,20][30,40][50,60].
2258 r0 = build_range3 (10, 20, 30, 40, 50, 60);
2259 r1 = int_range3 (INT (35)build_int_cst (integer_types[itk_int], (35)), INT (35)build_int_cst (integer_types[itk_int], (35)));
2260 r0.union_ (r1);
2261 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
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2261, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2261, __FUNCTION__))), desc_); } while (0)
;
2262}
2263
2264static void
2265range_tests_int_range_max ()
2266{
2267 int_range_max big;
2268 unsigned int nrange;
2269
2270 // Build a huge multi-range range.
2271 for (nrange = 0; nrange < 50; ++nrange)
2272 {
2273 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)));
2274 big.union_ (tmp);
2275 }
2276 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2276, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2276, __FUNCTION__))), desc_); } while (0)
;
2277
2278 // Verify that we can copy it without loosing precision.
2279 int_range_max copy (big);
2280 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2280, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2280, __FUNCTION__))), desc_); } while (0)
;
2281
2282 // Inverting it should produce one more sub-range.
2283 big.invert ();
2284 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2284, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2284, __FUNCTION__))), desc_); } while (0)
;
2285
2286 int_range<1> tmp (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (37)build_int_cst (integer_types[itk_int], (37)));
2287 big.intersect (tmp);
2288 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2288, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2288, __FUNCTION__))), desc_); } while (0)
;
2289
2290 // Test that [10,10][20,20] does NOT contain 15.
2291 {
2292 int_range_max i1 (build_int_cst (integer_type_nodeinteger_types[itk_int], 10),
2293 build_int_cst (integer_type_nodeinteger_types[itk_int], 10));
2294 int_range_max i2 (build_int_cst (integer_type_nodeinteger_types[itk_int], 20),
2295 build_int_cst (integer_type_nodeinteger_types[itk_int], 20));
2296 i1.union_ (i2);
2297 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2297, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2297, __FUNCTION__))), desc_); } while (0)
;
2298 }
2299}
2300
2301static void
2302range_tests_legacy ()
2303{
2304 // Test truncating copy to int_range<1>.
2305 int_range<3> big = build_range3 (10, 20, 30, 40, 50, 60);
2306 int_range<1> small = big;
2307 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2307, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2307, __FUNCTION__))), desc_); } while (0)
;
2
Taking true branch
3
Loop condition is false. Exiting loop
2308
2309 // Test truncating copy to int_range<2>.
2310 int_range<2> medium = big;
2311 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2311, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2311, __FUNCTION__))), desc_); } while (0)
;
4
Taking true branch
5
Loop condition is false. Exiting loop
2312
2313 // Test that a truncating copy of [MIN,20][22,40][80,MAX]
2314 // ends up as a conservative anti-range of ~[21,21].
2315 big = int_range<3> (vrp_val_min (integer_type_nodeinteger_types[itk_int]), INT (20)build_int_cst (integer_types[itk_int], (20)));
2316 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))));
2317 big.union_ (int_range<1> (INT (80)build_int_cst (integer_types[itk_int], (80)), vrp_val_max (integer_type_nodeinteger_types[itk_int])));
2318 small = big;
2319 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2319, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2319, __FUNCTION__))), desc_); } while (0)
;
6
Taking true branch
7
Loop condition is false. Exiting loop
2320
2321 // Copying a legacy symbolic to an int_range should normalize the
2322 // symbolic at copy time.
2323 {
2324 tree ssa = make_ssa_name (integer_type_nodeinteger_types[itk_int]);
2325 value_range legacy_range (ssa, INT (25)build_int_cst (integer_types[itk_int], (25)));
2326 int_range<2> copy = legacy_range;
8
Calling constructor for 'int_range<2U>'
11
Returning from constructor for 'int_range<2U>'
2327 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
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2328, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2328, __FUNCTION__))), desc_); } while (0)
12
Calling 'irange::operator=='
2328 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
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2328, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2328, __FUNCTION__))), desc_); } while (0)
;
2329
2330 // Test that copying ~[abc_23, abc_23] to a multi-range yields varying.
2331 legacy_range = value_range (ssa, ssa, VR_ANTI_RANGE);
2332 copy = legacy_range;
2333 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2333, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2333, __FUNCTION__))), desc_); } while (0)
;
2334 }
2335
2336 // VARYING of different sizes should not be equal.
2337 tree big_type = build_nonstandard_integer_type (32, 1);
2338 tree small_type = build_nonstandard_integer_type (16, 1);
2339 int_range_max r0 (big_type);
2340 int_range_max r1 (small_type);
2341 ASSERT_TRUE (r0 != r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 != r1)" ")"; bool
actual_ = ((r0 != r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2341, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2341, __FUNCTION__))), desc_); } while (0)
;
2342 value_range vr0 (big_type);
2343 int_range_max vr1 (small_type);
2344 ASSERT_TRUE (vr0 != vr1)do { const char *desc_ = "ASSERT_TRUE (" "(vr0 != vr1)" ")"; bool
actual_ = ((vr0 != vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2344, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2344, __FUNCTION__))), desc_); } while (0)
;
2345}
2346
2347// Simulate -fstrict-enums where the domain of a type is less than the
2348// underlying type.
2349
2350static void
2351range_tests_strict_enum ()
2352{
2353 // The enum can only hold [0, 3].
2354 tree rtype = copy_node (unsigned_type_nodeinteger_types[itk_unsigned_int]);
2355 TYPE_MIN_VALUE (rtype)((tree_check5 ((rtype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2355, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
= build_int_cstu (rtype, 0);
2356 TYPE_MAX_VALUE (rtype)((tree_check5 ((rtype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2356, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
= build_int_cstu (rtype, 3);
2357
2358 // Test that even though vr1 covers the strict enum domain ([0, 3]),
2359 // it does not cover the domain of the underlying type.
2360 int_range<1> vr1 (build_int_cstu (rtype, 0), build_int_cstu (rtype, 1));
2361 int_range<1> vr2 (build_int_cstu (rtype, 2), build_int_cstu (rtype, 3));
2362 vr1.union_ (vr2);
2363 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2364, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2364, __FUNCTION__))), desc_); } while (0)
2364 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2364, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2364, __FUNCTION__))), desc_); } while (0)
;
2365 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2365, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2365, __FUNCTION__))), desc_); } while (0)
;
2366
2367 // Test that copying to a multi-range does not change things.
2368 int_range<2> ir1 (vr1);
2369 ASSERT_TRUE (ir1 == vr1)do { const char *desc_ = "ASSERT_TRUE (" "(ir1 == vr1)" ")"; bool
actual_ = ((ir1 == vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2369, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2369, __FUNCTION__))), desc_); } while (0)
;
2370 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2370, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2370, __FUNCTION__))), desc_); } while (0)
;
2371
2372 // The same test as above, but using TYPE_{MIN,MAX}_VALUE instead of [0,3].
2373 vr1 = int_range<1> (TYPE_MIN_VALUE (rtype)((tree_check5 ((rtype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2373, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
, TYPE_MAX_VALUE (rtype)((tree_check5 ((rtype), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2373, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
);
2374 ir1 = vr1;
2375 ASSERT_TRUE (ir1 == vr1)do { const char *desc_ = "ASSERT_TRUE (" "(ir1 == vr1)" ")"; bool
actual_ = ((ir1 == vr1)); if (actual_) ::selftest::pass (((::
selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2375, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2375, __FUNCTION__))), desc_); } while (0)
;
2376 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2376, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2376, __FUNCTION__))), desc_); } while (0)
;
2377}
2378
2379static void
2380range_tests_misc ()
2381{
2382 tree u128_type = build_nonstandard_integer_type (128, /*unsigned=*/1);
2383 int_range<1> i1, i2, i3;
2384 int_range<1> r0, r1, rold;
2385
2386 // Test 1-bit signed integer union.
2387 // [-1,-1] U [0,0] = VARYING.
2388 tree one_bit_type = build_nonstandard_integer_type (1, 0);
2389 tree one_bit_min = vrp_val_min (one_bit_type);
2390 tree one_bit_max = vrp_val_max (one_bit_type);
2391 {
2392 int_range<2> min (one_bit_min, one_bit_min);
2393 int_range<2> max (one_bit_max, one_bit_max);
2394 max.union_ (min);
2395 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2395, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2395, __FUNCTION__))), desc_); } while (0)
;
2396 }
2397
2398 // Test inversion of 1-bit signed integers.
2399 {
2400 int_range<2> min (one_bit_min, one_bit_min);
2401 int_range<2> max (one_bit_max, one_bit_max);
2402 int_range<2> t;
2403 t = min;
2404 t.invert ();
2405 ASSERT_TRUE (t == max)do { const char *desc_ = "ASSERT_TRUE (" "(t == max)" ")"; bool
actual_ = ((t == max)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2405, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2405, __FUNCTION__))), desc_); } while (0)
;
2406 t = max;
2407 t.invert ();
2408 ASSERT_TRUE (t == min)do { const char *desc_ = "ASSERT_TRUE (" "(t == min)" ")"; bool
actual_ = ((t == min)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2408, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2408, __FUNCTION__))), desc_); } while (0)
;
2409 }
2410
2411 // Test that NOT(255) is [0..254] in 8-bit land.
2412 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);
2413 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2413, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2413, __FUNCTION__))), desc_); } while (0)
;
2414
2415 // Test that NOT(0) is [1..255] in 8-bit land.
2416 int_range<1> not_zero = range_nonzero (unsigned_char_type_nodeinteger_types[itk_unsigned_char]);
2417 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2417, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2417, __FUNCTION__))), desc_); } while (0)
;
2418
2419 // Check that [0,127][0x..ffffff80,0x..ffffff]
2420 // => ~[128, 0x..ffffff7f].
2421 r0 = int_range<1> (UINT128 (0)build_int_cstu (u128_type, (0)), UINT128 (127)build_int_cstu (u128_type, (127)));
2422 tree high = build_minus_one_cst (u128_type);
2423 // low = -1 - 127 => 0x..ffffff80.
2424 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)) )
;
2425 r1 = int_range<1> (low, high); // [0x..ffffff80, 0x..ffffffff]
2426 // r0 = [0,127][0x..ffffff80,0x..fffffff].
2427 r0.union_ (r1);
2428 // r1 = [128, 0x..ffffff7f].
2429 r1 = int_range<1> (UINT128(128)build_int_cstu (u128_type, (128)),
2430 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)) )
2431 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)) )
2432 UINT128(128))fold_build2_loc (((location_t) 0), MINUS_EXPR, u128_type, build_minus_one_cst
(u128_type), build_int_cstu (u128_type, (128)) )
);
2433 r0.invert ();
2434 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2434, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2434, __FUNCTION__))), desc_); } while (0)
;
2435
2436 r0.set_varying (integer_type_nodeinteger_types[itk_int]);
2437 tree minint = wide_int_to_tree (integer_type_nodeinteger_types[itk_int], r0.lower_bound ());
2438 tree maxint = wide_int_to_tree (integer_type_nodeinteger_types[itk_int], r0.upper_bound ());
2439
2440 r0.set_varying (short_integer_type_nodeinteger_types[itk_short]);
2441
2442 r0.set_varying (unsigned_type_nodeinteger_types[itk_unsigned_int]);
2443 tree maxuint = wide_int_to_tree (unsigned_type_nodeinteger_types[itk_unsigned_int], r0.upper_bound ());
2444
2445 // Check that ~[0,5] => [6,MAX] for unsigned int.
2446 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)));
2447 r0.invert ();
2448 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2448, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2448, __FUNCTION__))), desc_); } while (0)
;
2449
2450 // Check that ~[10,MAX] => [0,9] for unsigned int.
2451 r0 = int_range<1> (UINT(10)build_int_cstu (integer_types[itk_unsigned_int], (10)), maxuint);
2452 r0.invert ();
2453 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2453, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2453, __FUNCTION__))), desc_); } while (0)
;
2454
2455 // Check that ~[0,5] => [6,MAX] for unsigned 128-bit numbers.
2456 r0 = int_range<1> (UINT128 (0)build_int_cstu (u128_type, (0)), UINT128 (5)build_int_cstu (u128_type, (5)), VR_ANTI_RANGE);
2457 r1 = int_range<1> (UINT128(6)build_int_cstu (u128_type, (6)), build_minus_one_cst (u128_type));
2458 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2458, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2458, __FUNCTION__))), desc_); } while (0)
;
2459
2460 // Check that [~5] is really [-MIN,4][6,MAX].
2461 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);
2462 r1 = int_range<1> (minint, INT (4)build_int_cst (integer_types[itk_int], (4)));
2463 r1.union_ (int_range<1> (INT (6)build_int_cst (integer_types[itk_int], (6)), maxint));
2464 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2464, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2464, __FUNCTION__))), desc_); } while (0)
;
2465 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2465, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2465, __FUNCTION__))), desc_); } while (0)
;
2466
2467 r1 = int_range<1> (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (5)build_int_cst (integer_types[itk_int], (5)));
2468 int_range<1> r2 (r1);
2469 ASSERT_TRUE (r1 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r1 == r2)" ")"; bool
actual_ = ((r1 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2469, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2469, __FUNCTION__))), desc_); } while (0)
;
2470
2471 r1 = int_range<1> (INT (5)build_int_cst (integer_types[itk_int], (5)), INT (10)build_int_cst (integer_types[itk_int], (10)));
2472
2473 r1 = int_range<1> (integer_type_nodeinteger_types[itk_int],
2474 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))));
2475 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2475, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2475, __FUNCTION__))), desc_); } while (0)
;
2476
2477 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)));
2478 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2478, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2478, __FUNCTION__))), desc_); } while (0)
;
2479 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2479, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2479, __FUNCTION__))), desc_); } while (0)
;
2480
2481 // NOT([10,20]) ==> [-MIN,9][21,MAX].
2482 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)));
2483 r2 = int_range<1> (minint, INT(9)build_int_cst (integer_types[itk_int], (9)));
2484 r2.union_ (int_range<1> (INT(21)build_int_cst (integer_types[itk_int], (21)), maxint));
2485 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2485, __FUNCTION__))), desc_); else ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2485, __FUNCTION__))), desc_); } while (0)
;
2486 r1.invert ();
2487 ASSERT_TRUE (r1 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r1 == r2)" ")"; bool
actual_ = ((r1 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2487, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2487, __FUNCTION__))), desc_); } while (0)
;
2488 // Test that NOT(NOT(x)) == x.
2489 r2.invert ();
2490 ASSERT_TRUE (r0 == r2)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r2)" ")"; bool
actual_ = ((r0 == r2)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2490, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2490, __FUNCTION__))), desc_); } while (0)
;
2491
2492 // Test that booleans and their inverse work as expected.
2493 r0 = range_zero (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]);
2494 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2495, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2495, __FUNCTION__))), desc_); } while (0)
2495 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2495, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2495, __FUNCTION__))), desc_); } while (0)
;
2496 r0.invert ();
2497 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2498, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2498, __FUNCTION__))), desc_); } while (0)
2498 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2498, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2498, __FUNCTION__))), desc_); } while (0)
;
2499
2500 // Make sure NULL and non-NULL of pointer types work, and that
2501 // inverses of them are consistent.
2502 tree voidp = build_pointer_type (void_type_nodeglobal_trees[TI_VOID_TYPE]);
2503 r0 = range_zero (voidp);
2504 r1 = r0;
2505 r0.invert ();
2506 r0.invert ();
2507 ASSERT_TRUE (r0 == r1)do { const char *desc_ = "ASSERT_TRUE (" "(r0 == r1)" ")"; bool
actual_ = ((r0 == r1)); if (actual_) ::selftest::pass (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2507, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2507, __FUNCTION__))), desc_); } while (0)
;
2508
2509 // [10,20] U [15, 30] => [10, 30].
2510 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2511 r1 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (30)build_int_cst (integer_types[itk_int], (30)));
2512 r0.union_ (r1);
2513 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2513, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2513, __FUNCTION__))), desc_); } while (0)
;
2514
2515 // [15,40] U [] => [15,40].
2516 r0 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (40)build_int_cst (integer_types[itk_int], (40)));
2517 r1.set_undefined ();
2518 r0.union_ (r1);
2519 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2519, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2519, __FUNCTION__))), desc_); } while (0)
;
2520
2521 // [10,20] U [10,10] => [10,20].
2522 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2523 r1 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (10)build_int_cst (integer_types[itk_int], (10)));
2524 r0.union_ (r1);
2525 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2525, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2525, __FUNCTION__))), desc_); } while (0)
;
2526
2527 // [10,20] U [9,9] => [9,20].
2528 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2529 r1 = int_range<1> (INT (9)build_int_cst (integer_types[itk_int], (9)), INT (9)build_int_cst (integer_types[itk_int], (9)));
2530 r0.union_ (r1);
2531 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2531, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2531, __FUNCTION__))), desc_); } while (0)
;
2532
2533 // [10,20] ^ [15,30] => [15,20].
2534 r0 = int_range<1> (INT (10)build_int_cst (integer_types[itk_int], (10)), INT (20)build_int_cst (integer_types[itk_int], (20)));
2535 r1 = int_range<1> (INT (15)build_int_cst (integer_types[itk_int], (15)), INT (30)build_int_cst (integer_types[itk_int], (30)));
2536 r0.intersect (r1);
2537 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2537, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2537, __FUNCTION__))), desc_); } while (0)
;
2538
2539 // Test the internal sanity of wide_int's wrt HWIs.
2540 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), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2540, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2542, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2540, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); } while (0)
2541 TYPE_SIGN (boolean_type_node))do { const char *desc_ = "ASSERT_TRUE (" "(wi::max_value (((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2540, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2542, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2540, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); } while (0)
2542 == 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), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2540, __FUNCTION__))->type_common.precision), ((signop) ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type), \"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc\", 2542, __FUNCTION__))->type_common.precision)))"
")"; bool actual_ = ((wi::max_value (((tree_class_check ((global_trees
[TI_BOOLEAN_TYPE]), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2540, __FUNCTION__))->type_common.precision), ((signop) (
(tree_class_check ((global_trees[TI_BOOLEAN_TYPE]), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2541, __FUNCTION__))->base.u.bits.unsigned_flag))) == wi
::uhwi (1, ((tree_class_check ((global_trees[TI_BOOLEAN_TYPE]
), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))->type_common.precision)))); if (actual_
) ::selftest::pass (((::selftest::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2542, __FUNCTION__))), desc_); } while (0)
;
2543
2544 // Test zero_p().
2545 r0 = int_range<1> (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (0)build_int_cst (integer_types[itk_int], (0)));
2546 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2546, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2546, __FUNCTION__))), desc_); } while (0)
;
2547
2548 // Test nonzero_p().
2549 r0 = int_range<1> (INT (0)build_int_cst (integer_types[itk_int], (0)), INT (0)build_int_cst (integer_types[itk_int], (0)));
2550 r0.invert ();
2551 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2551, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2551, __FUNCTION__))), desc_); } while (0)
;
2552
2553 // test legacy interaction
2554 // r0 = ~[1,1]
2555 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);
2556 // r1 = ~[3,3]
2557 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);
2558
2559 // vv = [0,0][2,2][4, MAX]
2560 int_range<3> vv = r0;
2561 vv.intersect (r1);
2562
2563 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2563, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2563, __FUNCTION__))), desc_); } while (0)
;
2564 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2564, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2564, __FUNCTION__))), desc_); } while (0)
;
2565
2566 // create r0 as legacy [1,1]
2567 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)));
2568 // And union it with [0,0][2,2][4,MAX] multi range
2569 r0.union_ (vv);
2570 // The result should be [0,2][4,MAX], or ~[3,3] but it must contain 2
2571 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 ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2571, __FUNCTION__))), desc_); else ::selftest::fail (((::selftest
::location ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.cc"
, 2571, __FUNCTION__))), desc_); } while (0)
;
2572}
2573
2574void
2575range_tests ()
2576{
2577 range_tests_legacy ();
1
Calling 'range_tests_legacy'
2578 range_tests_irange3 ();
2579 range_tests_int_range_max ();
2580 range_tests_strict_enum ();
2581 range_tests_misc ();
2582}
2583
2584} // namespace selftest
2585
2586#endif // CHECKING_P

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h

1/* Support routines for value ranges.
2 Copyright (C) 2019-2021 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
25// Types of value ranges.
26enum value_range_kind
27{
28 /* Empty range. */
29 VR_UNDEFINED,
30 /* Range spans the entire domain. */
31 VR_VARYING,
32 /* Range is [MIN, MAX]. */
33 VR_RANGE,
34 /* Range is ~[MIN, MAX]. */
35 VR_ANTI_RANGE,
36 /* Range is a nice guy. */
37 VR_LAST
38};
39
40// Range of values that can be associated with an SSA_NAME.
41//
42// This is the base class without any storage.
43
44class GTY((user)) irange
45{
46 friend class irange_allocator;
47public:
48 // In-place setters.
49 void set (tree, tree, value_range_kind = VR_RANGE);
50 void set_nonzero (tree);
51 void set_zero (tree);
52 void set_varying (tree type);
53 void set_undefined ();
54
55 // Range types.
56 static bool supports_type_p (tree);
57 tree type () const;
58
59 // Iteration over sub-ranges.
60 unsigned num_pairs () const;
61 wide_int lower_bound (unsigned = 0) const;
62 wide_int upper_bound (unsigned) const;
63 wide_int upper_bound () const;
64
65 // Predicates.
66 bool zero_p () const;
67 bool nonzero_p () const;
68 bool undefined_p () const;
69 bool varying_p () const;
70 bool singleton_p (tree *result = NULLnullptr) const;
71 bool contains_p (tree) const;
72
73 // In-place operators.
74 void union_ (const irange &);
75 void intersect (const irange &);
76 void intersect (const wide_int& lb, const wide_int& ub);
77 void invert ();
78
79 // Operator overloads.
80 irange& operator= (const irange &);
81 bool operator== (const irange &) const;
82 bool operator!= (const irange &r) const { return !(*this == r); }
83
84 // Misc methods.
85 bool fits_p (const irange &r) { return m_max_ranges >= r.num_pairs (); }
86 void dump (FILE * = stderrstderr) const;
87 void debug () const;
88
89 // Deprecated legacy public methods.
90 enum value_range_kind kind () const; // DEPRECATED
91 tree min () const; // DEPRECATED
92 tree max () const; // DEPRECATED
93 bool symbolic_p () const; // DEPRECATED
94 bool constant_p () const; // DEPRECATED
95 void normalize_symbolics (); // DEPRECATED
96 void normalize_addresses (); // DEPRECATED
97 bool may_contain_p (tree) const; // DEPRECATED
98 void set (tree); // DEPRECATED
99 bool equal_p (const irange &) const; // DEPRECATED
100 void union_ (const class irange *); // DEPRECATED
101 void intersect (const irange *); // DEPRECATED
102
103protected:
104 irange (tree *, unsigned);
105 // potential promotion to public?
106 tree tree_lower_bound (unsigned = 0) const;
107 tree tree_upper_bound (unsigned) const;
108 tree tree_upper_bound () const;
109
110 // In-place operators.
111 void irange_union (const irange &);
112 void irange_intersect (const irange &);
113 void irange_set (tree, tree);
114 void irange_set_anti_range (tree, tree);
115
116 void normalize_kind ();
117
118 bool legacy_mode_p () const;
119 bool legacy_equal_p (const irange &) const;
120 void legacy_union (irange *, const irange *);
121 void legacy_intersect (irange *, const irange *);
122 void verify_range ();
123 wide_int legacy_lower_bound (unsigned = 0) const;
124 wide_int legacy_upper_bound (unsigned) const;
125 int value_inside_range (tree) const;
126 bool maybe_anti_range () const;
127 void copy_to_legacy (const irange &);
128 void copy_legacy_to_multi_range (const irange &);
129
130private:
131 friend void gt_ggc_mx (irange *);
132 friend void gt_pch_nx (irange *);
133 friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
134
135 void irange_set_1bit_anti_range (tree, tree);
136 bool varying_compatible_p () const;
137
138 unsigned char m_num_ranges;
139 unsigned char m_max_ranges;
140 ENUM_BITFIELD(value_range_kind)enum value_range_kind m_kind : 8;
141 tree *m_base;
142};
143
144// Here we describe an irange with N pairs of ranges. The storage for
145// the pairs is embedded in the class as an array.
146
147template<unsigned N>
148class GTY((user)) int_range : public irange
149{
150public:
151 int_range ();
152 int_range (tree, tree, value_range_kind = VR_RANGE);
153 int_range (tree type, const wide_int &, const wide_int &,
154 value_range_kind = VR_RANGE);
155 int_range (tree type);
156 int_range (const int_range &);
157 int_range (const irange &);
158 int_range& operator= (const int_range &);
159private:
160 template <unsigned X> friend void gt_ggc_mx (int_range<X> *);
161 template <unsigned X> friend void gt_pch_nx (int_range<X> *);
162 template <unsigned X> friend void gt_pch_nx (int_range<X> *,
163 gt_pointer_operator, void *);
164
165 // ?? These stubs are for ipa-prop.c which use a value_range in a
166 // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
167 // instead of picking up the gt_ggc_mx (T *) version.
168 friend void gt_ggc_mx (int_range<1> *&);
169 friend void gt_pch_nx (int_range<1> *&);
170
171 tree m_ranges[N*2];
172};
173
174// This is a special int_range<1> with only one pair, plus
175// VR_ANTI_RANGE magic to describe slightly more than can be described
176// in one pair. It is described in the code as a "legacy range" (as
177// opposed to multi-ranges which have multiple sub-ranges). It is
178// provided for backward compatibility with code that has not been
179// converted to multi-range irange's.
180//
181// There are copy operators to seamlessly copy to/fro multi-ranges.
182typedef int_range<1> value_range;
183
184// This is an "infinite" precision irange for use in temporary
185// calculations.
186typedef int_range<255> int_range_max;
187
188// Returns true for an old-school value_range as described above.
189inline bool
190irange::legacy_mode_p () const
191{
192 return m_max_ranges == 1;
15
Returning zero, which participates in a condition later
19
Assuming field 'm_max_ranges' is not equal to 1
20
Returning zero, which participates in a condition later
193}
194
195extern bool range_has_numeric_bounds_p (const irange *);
196extern bool ranges_from_anti_range (const value_range *,
197 value_range *, value_range *);
198extern void dump_value_range (FILE *, const irange *);
199extern bool vrp_val_is_min (const_tree);
200extern bool vrp_val_is_max (const_tree);
201extern bool vrp_operand_equal_p (const_tree, const_tree);
202
203inline value_range_kind
204irange::kind () const
205{
206 return m_kind;
207}
208
209// Number of sub-ranges in a range.
210
211inline unsigned
212irange::num_pairs () const
213{
214 if (m_kind == VR_ANTI_RANGE)
215 return constant_p () ? 2 : 1;
216 else
217 return m_num_ranges;
218}
219
220inline tree
221irange::type () const
222{
223 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 223, __FUNCTION__), 0 : 0))
;
224 return TREE_TYPE (m_base[0])((contains_struct_check ((m_base[0]), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 224, __FUNCTION__))->typed.type)
;
225}
226
227// Return the lower bound of a sub-range expressed as a tree. PAIR is
228// the sub-range in question.
229
230inline tree
231irange::tree_lower_bound (unsigned pair) const
232{
233 return m_base[pair * 2];
30
Undefined or garbage value returned to caller
234}
235
236// Return the upper bound of a sub-range expressed as a tree. PAIR is
237// the sub-range in question.
238
239inline tree
240irange::tree_upper_bound (unsigned pair) const
241{
242 return m_base[pair * 2 + 1];
243}
244
245// Return the highest bound of a range expressed as a tree.
246
247inline tree
248irange::tree_upper_bound () const
249{
250 gcc_checking_assert (m_num_ranges)((void)(!(m_num_ranges) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 250, __FUNCTION__), 0 : 0))
;
251 return tree_upper_bound (m_num_ranges - 1);
252}
253
254inline tree
255irange::min () const
256{
257 return tree_lower_bound (0);
258}
259
260inline tree
261irange::max () const
262{
263 if (m_num_ranges)
264 return tree_upper_bound ();
265 else
266 return NULLnullptr;
267}
268
269inline bool
270irange::varying_compatible_p () const
271{
272 if (m_num_ranges != 1)
273 return false;
274
275 tree l = m_base[0];
276 tree u = m_base[1];
277 tree t = TREE_TYPE (l)((contains_struct_check ((l), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 277, __FUNCTION__))->typed.type)
;
278
279 if (m_kind == VR_VARYING && t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
280 return true;
281
282 unsigned prec = TYPE_PRECISION (t)((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 282, __FUNCTION__))->type_common.precision)
;
283 signop sign = TYPE_SIGN (t)((signop) ((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 283, __FUNCTION__))->base.u.bits.unsigned_flag))
;
284 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)
)
285 return (wi::to_wide (l) == wi::min_value (prec, sign)
286 && wi::to_wide (u) == wi::max_value (prec, sign));
287 if (POINTER_TYPE_P (t)(((enum tree_code) (t)->base.code) == POINTER_TYPE || ((enum
tree_code) (t)->base.code) == REFERENCE_TYPE)
)
288 return (wi::to_wide (l) == 0
289 && wi::to_wide (u) == wi::max_value (prec, sign));
290 return true;
291}
292
293inline bool
294irange::varying_p () const
295{
296 return m_kind == VR_VARYING;
297}
298
299inline bool
300irange::undefined_p () const
301{
302 return m_kind == VR_UNDEFINED;
303}
304
305inline bool
306irange::zero_p () const
307{
308 return (m_kind == VR_RANGE && m_num_ranges == 1
309 && integer_zerop (tree_lower_bound (0))
310 && integer_zerop (tree_upper_bound (0)));
311}
312
313inline bool
314irange::nonzero_p () const
315{
316 if (undefined_p ())
317 return false;
318
319 tree zero = build_zero_cst (type ());
320 return *this == int_range<1> (zero, zero, VR_ANTI_RANGE);
321}
322
323inline bool
324irange::supports_type_p (tree type)
325{
326 if (type && (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)
))
327 return type;
328 return false;
329}
330
331inline bool
332range_includes_zero_p (const irange *vr)
333{
334 if (vr->undefined_p ())
335 return false;
336
337 if (vr->varying_p ())
338 return true;
339
340 return vr->may_contain_p (build_zero_cst (vr->type ()));
341}
342
343inline void
344gt_ggc_mx (irange *x)
345{
346 for (unsigned i = 0; i < x->m_num_ranges; ++i)
347 {
348 gt_ggc_mx (x->m_base[i * 2]);
349 gt_ggc_mx (x->m_base[i * 2 + 1]);
350 }
351}
352
353inline void
354gt_pch_nx (irange *x)
355{
356 for (unsigned i = 0; i < x->m_num_ranges; ++i)
357 {
358 gt_pch_nx (x->m_base[i * 2]);
359 gt_pch_nx (x->m_base[i * 2 + 1]);
360 }
361}
362
363inline void
364gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
365{
366 for (unsigned i = 0; i < x->m_num_ranges; ++i)
367 {
368 op (&x->m_base[i * 2], cookie);
369 op (&x->m_base[i * 2 + 1], cookie);
370 }
371}
372
373template<unsigned N>
374inline void
375gt_ggc_mx (int_range<N> *x)
376{
377 gt_ggc_mx ((irange *) x);
378}
379
380template<unsigned N>
381inline void
382gt_pch_nx (int_range<N> *x)
383{
384 gt_pch_nx ((irange *) x);
385}
386
387template<unsigned N>
388inline void
389gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
390{
391 gt_pch_nx ((irange *) x, op, cookie);
392}
393
394// Constructors for irange
395
396inline
397irange::irange (tree *base, unsigned nranges)
398{
399 m_base = base;
400 m_num_ranges = 0;
401 m_max_ranges = nranges;
402 m_kind = VR_UNDEFINED;
403}
404
405// Constructors for int_range<>.
406
407template<unsigned N>
408inline
409int_range<N>::int_range ()
410 : irange (m_ranges, N)
411{
412}
413
414template<unsigned N>
415int_range<N>::int_range (const int_range &other)
416 : irange (m_ranges, N)
417{
418 irange::operator= (other);
419}
420
421template<unsigned N>
422int_range<N>::int_range (tree min, tree max, value_range_kind kind)
423 : irange (m_ranges, N)
424{
425 irange::set (min, max, kind);
426}
427
428template<unsigned N>
429int_range<N>::int_range (tree type)
430 : irange (m_ranges, N)
431{
432 set_varying (type);
433}
434
435template<unsigned N>
436int_range<N>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
437 value_range_kind kind)
438 : irange (m_ranges, N)
439{
440 tree min = wide_int_to_tree (type, wmin);
441 tree max = wide_int_to_tree (type, wmax);
442 set (min, max, kind);
443}
444
445template<unsigned N>
446int_range<N>::int_range (const irange &other)
447 : irange (m_ranges, N)
9
Calling constructor for 'irange'
10
Returning from constructor for 'irange'
448{
449 irange::operator= (other);
450}
451
452template<unsigned N>
453int_range<N>&
454int_range<N>::operator= (const int_range &src)
455{
456 irange::operator= (src);
457 return *this;
458}
459
460inline void
461irange::set (tree val)
462{
463 set (val, val);
464}
465
466inline void
467irange::set_undefined ()
468{
469 m_kind = VR_UNDEFINED;
470 m_num_ranges = 0;
471}
472
473inline void
474irange::set_varying (tree type)
475{
476 m_kind = VR_VARYING;
477 m_num_ranges = 1;
478
479 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)
)
480 {
481 // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
482 // min_value and max_value.
483 wide_int min = wi::min_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 483, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 483, __FUNCTION__))->base.u.bits.unsigned_flag))
);
484 wide_int max = wi::max_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 484, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 484, __FUNCTION__))->base.u.bits.unsigned_flag))
);
485 if (wi::eq_p (max, wi::to_wide (TYPE_MAX_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 485, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
))
486 && wi::eq_p (min, wi::to_wide (TYPE_MIN_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 486, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
)))
487 {
488 m_base[0] = TYPE_MIN_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 488, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
;
489 m_base[1] = TYPE_MAX_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 489, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
;
490 }
491 else
492 {
493 m_base[0] = wide_int_to_tree (type, min);
494 m_base[1] = wide_int_to_tree (type, max);
495 }
496 }
497 else if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
498 {
499 m_base[0] = build_int_cst (type, 0);
500 m_base[1] = build_int_cst (type, -1);
501 }
502 else
503 m_base[0] = m_base[1] = error_mark_nodeglobal_trees[TI_ERROR_MARK];
504}
505
506inline bool
507irange::operator== (const irange &r) const
508{
509 return equal_p (r);
13
Calling 'irange::equal_p'
510}
511
512// Return the lower bound of a sub-range. PAIR is the sub-range in
513// question.
514
515inline wide_int
516irange::lower_bound (unsigned pair) const
517{
518 if (legacy_mode_p ())
519 return legacy_lower_bound (pair);
520 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 520, __FUNCTION__), 0 : 0))
;
521 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 521, __FUNCTION__), 0 : 0))
;
522 return wi::to_wide (tree_lower_bound (pair));
523}
524
525// Return the upper bound of a sub-range. PAIR is the sub-range in
526// question.
527
528inline wide_int
529irange::upper_bound (unsigned pair) const
530{
531 if (legacy_mode_p ())
532 return legacy_upper_bound (pair);
533 gcc_checking_assert (m_num_ranges > 0)((void)(!(m_num_ranges > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 533, __FUNCTION__), 0 : 0))
;
534 gcc_checking_assert (pair + 1 <= num_pairs ())((void)(!(pair + 1 <= num_pairs ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 534, __FUNCTION__), 0 : 0))
;
535 return wi::to_wide (tree_upper_bound (pair));
536}
537
538// Return the highest bound of a range.
539
540inline wide_int
541irange::upper_bound () const
542{
543 unsigned pairs = num_pairs ();
544 gcc_checking_assert (pairs > 0)((void)(!(pairs > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 544, __FUNCTION__), 0 : 0))
;
545 return upper_bound (pairs - 1);
546}
547
548inline void
549irange::union_ (const irange &r)
550{
551 dump_flags_t m_flags = dump_flags;
552 dump_flags &= ~TDF_DETAILS;
553 irange::union_ (&r);
554 dump_flags = m_flags;
555}
556
557inline void
558irange::intersect (const irange &r)
559{
560 dump_flags_t m_flags = dump_flags;
561 dump_flags &= ~TDF_DETAILS;
562 irange::intersect (&r);
563 dump_flags = m_flags;
564}
565
566// Set value range VR to a nonzero range of type TYPE.
567
568inline void
569irange::set_nonzero (tree type)
570{
571 tree zero = build_int_cst (type, 0);
572 if (legacy_mode_p ())
573 set (zero, zero, VR_ANTI_RANGE);
574 else
575 irange_set_anti_range (zero, zero);
576}
577
578// Set value range VR to a ZERO range of type TYPE.
579
580inline void
581irange::set_zero (tree type)
582{
583 tree z = build_int_cst (type, 0);
584 if (legacy_mode_p ())
585 set (z);
586 else
587 irange_set (z, z);
588}
589
590// Normalize a range to VARYING or UNDEFINED if possible.
591
592inline void
593irange::normalize_kind ()
594{
595 if (m_num_ranges == 0)
596 m_kind = VR_UNDEFINED;
597 else if (varying_compatible_p ())
598 {
599 if (m_kind == VR_RANGE)
600 m_kind = VR_VARYING;
601 else if (m_kind == VR_ANTI_RANGE)
602 set_undefined ();
603 else
604 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 604, __FUNCTION__))
;
605 }
606}
607
608// Return the maximum value for TYPE.
609
610inline tree
611vrp_val_max (const_tree type)
612{
613 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)
)
614 return TYPE_MAX_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 614, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
;
615 if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
616 {
617 wide_int max = wi::max_value (TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 617, __FUNCTION__))->type_common.precision)
, TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 617, __FUNCTION__))->base.u.bits.unsigned_flag))
);
618 return wide_int_to_tree (const_cast<tree> (type), max);
619 }
620 return NULL_TREE(tree) nullptr;
621}
622
623// Return the minimum value for TYPE.
624
625inline tree
626vrp_val_min (const_tree type)
627{
628 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)
)
629 return TYPE_MIN_VALUE (type)((tree_check5 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/value-range.h"
, 629, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval
)
;
630 if (POINTER_TYPE_P (type)(((enum tree_code) (type)->base.code) == POINTER_TYPE || (
(enum tree_code) (type)->base.code) == REFERENCE_TYPE)
)
631 return build_zero_cst (const_cast<tree> (type));
632 return NULL_TREE(tree) nullptr;
633}
634
635// This is the irange storage class. It is used to allocate the
636// minimum amount of storage needed for a given irange. Storage is
637// automatically freed at destruction of the storage class.
638//
639// It is meant for long term storage, as opposed to int_range_max
640// which is meant for intermediate temporary results on the stack.
641//
642// The newly allocated irange is initialized to the empty set
643// (undefined_p() is true).
644
645class irange_allocator
646{
647public:
648 irange_allocator ();
649 ~irange_allocator ();
650 // Return a new range with NUM_PAIRS.
651 irange *allocate (unsigned num_pairs);
652 // Return a copy of SRC with the minimum amount of sub-ranges needed
653 // to represent it.
654 irange *allocate (const irange &src);
655 void *get_memory (unsigned num_bytes);
656private:
657 DISABLE_COPY_AND_ASSIGN (irange_allocator)irange_allocator (const irange_allocator&) = delete; void
operator= (const irange_allocator &) = delete
;
658 struct obstack m_obstack;
659};
660
661inline
662irange_allocator::irange_allocator ()
663{
664 obstack_init (&m_obstack)_obstack_begin ((&m_obstack), 0, 0, (mempool_obstack_chunk_alloc
), (mempool_obstack_chunk_free))
;
665}
666
667inline
668irange_allocator::~irange_allocator ()
669{
670 obstack_free (&m_obstack, NULL)__extension__ ({ struct obstack *__o = (&m_obstack); void
*__obj = (void *) (nullptr); if (__obj > (void *) __o->
chunk && __obj < (void *) __o->chunk_limit) __o
->next_free = __o->object_base = (char *) __obj; else _obstack_free
(__o, __obj); })
;
671}
672
673// Provide a hunk of memory from the obstack.
674inline void *
675irange_allocator::get_memory (unsigned num_bytes)
676{
677 void *r = obstack_alloc (&m_obstack, num_bytes)__extension__ ({ struct obstack *__h = (&m_obstack); __extension__
({ struct obstack *__o = (__h); size_t __len = ((num_bytes))
; if (__extension__ ({ struct obstack const *__o1 = (__o); (size_t
) (__o1->chunk_limit - __o1->next_free); }) < __len)
_obstack_newchunk (__o, __len); ((void) ((__o)->next_free
+= (__len))); }); __extension__ ({ struct obstack *__o1 = (__h
); void *__value = (void *) __o1->object_base; if (__o1->
next_free == __value) __o1->maybe_empty_object = 1; __o1->
next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1
->object_base) + (((__o1->next_free) - (__o1->object_base
) + (__o1->alignment_mask)) & ~(__o1->alignment_mask
))) : (char *) (((ptrdiff_t) (__o1->next_free) + (__o1->
alignment_mask)) & ~(__o1->alignment_mask))); if ((size_t
) (__o1->next_free - (char *) __o1->chunk) > (size_t
) (__o1->chunk_limit - (char *) __o1->chunk)) __o1->
next_free = __o1->chunk_limit; __o1->object_base = __o1
->next_free; __value; }); })
;
678 return r;
679}
680
681// Return a new range with NUM_PAIRS.
682
683inline irange *
684irange_allocator::allocate (unsigned num_pairs)
685{
686 // Never allocate 0 pairs.
687 // Don't allocate 1 either, or we get legacy value_range's.
688 if (num_pairs < 2)
689 num_pairs = 2;
690
691 size_t nbytes = sizeof (tree) * 2 * num_pairs;
692
693 // Allocate the irange and required memory for the vector.
694 void *r = obstack_alloc (&m_obstack, sizeof (irange))__extension__ ({ struct obstack *__h = (&m_obstack); __extension__
({ struct obstack *__o = (__h); size_t __len = ((sizeof (irange
))); if (__extension__ ({ struct obstack const *__o1 = (__o);
(size_t) (__o1->chunk_limit - __o1->next_free); }) <
__len) _obstack_newchunk (__o, __len); ((void) ((__o)->next_free
+= (__len))); }); __extension__ ({ struct obstack *__o1 = (__h
); void *__value = (void *) __o1->object_base; if (__o1->
next_free == __value) __o1->maybe_empty_object = 1; __o1->
next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1
->object_base) + (((__o1->next_free) - (__o1->object_base
) + (__o1->alignment_mask)) & ~(__o1->alignment_mask
))) : (char *) (((ptrdiff_t) (__o1->next_free) + (__o1->
alignment_mask)) & ~(__o1->alignment_mask))); if ((size_t
) (__o1->next_free - (char *) __o1->chunk) > (size_t
) (__o1->chunk_limit - (char *) __o1->chunk)) __o1->
next_free = __o1->chunk_limit; __o1->object_base = __o1
->next_free; __value; }); })
;
695 tree *mem = (tree *) obstack_alloc (&m_obstack, nbytes)__extension__ ({ struct obstack *__h = (&m_obstack); __extension__
({ struct obstack *__o = (__h); size_t __len = ((nbytes)); if
(__extension__ ({ struct obstack const *__o1 = (__o); (size_t
) (__o1->chunk_limit - __o1->next_free); }) < __len)
_obstack_newchunk (__o, __len); ((void) ((__o)->next_free
+= (__len))); }); __extension__ ({ struct obstack *__o1 = (__h
); void *__value = (void *) __o1->object_base; if (__o1->
next_free == __value) __o1->maybe_empty_object = 1; __o1->
next_free = (sizeof (ptrdiff_t) < sizeof (void *) ? ((__o1
->object_base) + (((__o1->next_free) - (__o1->object_base
) + (__o1->alignment_mask)) & ~(__o1->alignment_mask
))) : (char *) (((ptrdiff_t) (__o1->next_free) + (__o1->
alignment_mask)) & ~(__o1->alignment_mask))); if ((size_t
) (__o1->next_free - (char *) __o1->chunk) > (size_t
) (__o1->chunk_limit - (char *) __o1->chunk)) __o1->
next_free = __o1->chunk_limit; __o1->object_base = __o1
->next_free; __value; }); })
;
696 return new (r) irange (mem, num_pairs);
697}
698
699inline irange *
700irange_allocator::allocate (const irange &src)
701{
702 irange *r = allocate (src.num_pairs ());
703 *r = src;
704 return r;
705}
706
707#endif // GCC_VALUE_RANGE_H