Bug Summary

File:build/gcc/wide-int.h
Warning:line 1160, column 57
The right operand of '>' is a garbage value

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

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h

1/* Operations with very long integers. -*- C++ -*-
2 Copyright (C) 2012-2021 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 3, or (at your option) any
9later version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#ifndef WIDE_INT_H
21#define WIDE_INT_H
22
23/* wide-int.[cc|h] implements a class that efficiently performs
24 mathematical operations on finite precision integers. wide_ints
25 are designed to be transient - they are not for long term storage
26 of values. There is tight integration between wide_ints and the
27 other longer storage GCC representations (rtl and tree).
28
29 The actual precision of a wide_int depends on the flavor. There
30 are three predefined flavors:
31
32 1) wide_int (the default). This flavor does the math in the
33 precision of its input arguments. It is assumed (and checked)
34 that the precisions of the operands and results are consistent.
35 This is the most efficient flavor. It is not possible to examine
36 bits above the precision that has been specified. Because of
37 this, the default flavor has semantics that are simple to
38 understand and in general model the underlying hardware that the
39 compiler is targetted for.
40
41 This flavor must be used at the RTL level of gcc because there
42 is, in general, not enough information in the RTL representation
43 to extend a value beyond the precision specified in the mode.
44
45 This flavor should also be used at the TREE and GIMPLE levels of
46 the compiler except for the circumstances described in the
47 descriptions of the other two flavors.
48
49 The default wide_int representation does not contain any
50 information inherent about signedness of the represented value,
51 so it can be used to represent both signed and unsigned numbers.
52 For operations where the results depend on signedness (full width
53 multiply, division, shifts, comparisons, and operations that need
54 overflow detected), the signedness must be specified separately.
55
56 2) offset_int. This is a fixed-precision integer that can hold
57 any address offset, measured in either bits or bytes, with at
58 least one extra sign bit. At the moment the maximum address
59 size GCC supports is 64 bits. With 8-bit bytes and an extra
60 sign bit, offset_int therefore needs to have at least 68 bits
61 of precision. We round this up to 128 bits for efficiency.
62 Values of type T are converted to this precision by sign- or
63 zero-extending them based on the signedness of T.
64
65 The extra sign bit means that offset_int is effectively a signed
66 128-bit integer, i.e. it behaves like int128_t.
67
68 Since the values are logically signed, there is no need to
69 distinguish between signed and unsigned operations. Sign-sensitive
70 comparison operators <, <=, > and >= are therefore supported.
71 Shift operators << and >> are also supported, with >> being
72 an _arithmetic_ right shift.
73
74 [ Note that, even though offset_int is effectively int128_t,
75 it can still be useful to use unsigned comparisons like
76 wi::leu_p (a, b) as a more efficient short-hand for
77 "a >= 0 && a <= b". ]
78
79 3) widest_int. This representation is an approximation of
80 infinite precision math. However, it is not really infinite
81 precision math as in the GMP library. It is really finite
82 precision math where the precision is 4 times the size of the
83 largest integer that the target port can represent.
84
85 Like offset_int, widest_int is wider than all the values that
86 it needs to represent, so the integers are logically signed.
87 Sign-sensitive comparison operators <, <=, > and >= are supported,
88 as are << and >>.
89
90 There are several places in the GCC where this should/must be used:
91
92 * Code that does induction variable optimizations. This code
93 works with induction variables of many different types at the
94 same time. Because of this, it ends up doing many different
95 calculations where the operands are not compatible types. The
96 widest_int makes this easy, because it provides a field where
97 nothing is lost when converting from any variable,
98
99 * There are a small number of passes that currently use the
100 widest_int that should use the default. These should be
101 changed.
102
103 There are surprising features of offset_int and widest_int
104 that the users should be careful about:
105
106 1) Shifts and rotations are just weird. You have to specify a
107 precision in which the shift or rotate is to happen in. The bits
108 above this precision are zeroed. While this is what you
109 want, it is clearly non obvious.
110
111 2) Larger precision math sometimes does not produce the same
112 answer as would be expected for doing the math at the proper
113 precision. In particular, a multiply followed by a divide will
114 produce a different answer if the first product is larger than
115 what can be represented in the input precision.
116
117 The offset_int and the widest_int flavors are more expensive
118 than the default wide int, so in addition to the caveats with these
119 two, the default is the prefered representation.
120
121 All three flavors of wide_int are represented as a vector of
122 HOST_WIDE_INTs. The default and widest_int vectors contain enough elements
123 to hold a value of MAX_BITSIZE_MODE_ANY_INT bits. offset_int contains only
124 enough elements to hold ADDR_MAX_PRECISION bits. The values are stored
125 in the vector with the least significant HOST_BITS_PER_WIDE_INT bits
126 in element 0.
127
128 The default wide_int contains three fields: the vector (VAL),
129 the precision and a length (LEN). The length is the number of HWIs
130 needed to represent the value. widest_int and offset_int have a
131 constant precision that cannot be changed, so they only store the
132 VAL and LEN fields.
133
134 Since most integers used in a compiler are small values, it is
135 generally profitable to use a representation of the value that is
136 as small as possible. LEN is used to indicate the number of
137 elements of the vector that are in use. The numbers are stored as
138 sign extended numbers as a means of compression. Leading
139 HOST_WIDE_INTs that contain strings of either -1 or 0 are removed
140 as long as they can be reconstructed from the top bit that is being
141 represented.
142
143 The precision and length of a wide_int are always greater than 0.
144 Any bits in a wide_int above the precision are sign-extended from the
145 most significant bit. For example, a 4-bit value 0x8 is represented as
146 VAL = { 0xf...fff8 }. However, as an optimization, we allow other integer
147 constants to be represented with undefined bits above the precision.
148 This allows INTEGER_CSTs to be pre-extended according to TYPE_SIGN,
149 so that the INTEGER_CST representation can be used both in TYPE_PRECISION
150 and in wider precisions.
151
152 There are constructors to create the various forms of wide_int from
153 trees, rtl and constants. For trees the options are:
154
155 tree t = ...;
156 wi::to_wide (t) // Treat T as a wide_int
157 wi::to_offset (t) // Treat T as an offset_int
158 wi::to_widest (t) // Treat T as a widest_int
159
160 All three are light-weight accessors that should have no overhead
161 in release builds. If it is useful for readability reasons to
162 store the result in a temporary variable, the preferred method is:
163
164 wi::tree_to_wide_ref twide = wi::to_wide (t);
165 wi::tree_to_offset_ref toffset = wi::to_offset (t);
166 wi::tree_to_widest_ref twidest = wi::to_widest (t);
167
168 To make an rtx into a wide_int, you have to pair it with a mode.
169 The canonical way to do this is with rtx_mode_t as in:
170
171 rtx r = ...
172 wide_int x = rtx_mode_t (r, mode);
173
174 Similarly, a wide_int can only be constructed from a host value if
175 the target precision is given explicitly, such as in:
176
177 wide_int x = wi::shwi (c, prec); // sign-extend C if necessary
178 wide_int y = wi::uhwi (c, prec); // zero-extend C if necessary
179
180 However, offset_int and widest_int have an inherent precision and so
181 can be initialized directly from a host value:
182
183 offset_int x = (int) c; // sign-extend C
184 widest_int x = (unsigned int) c; // zero-extend C
185
186 It is also possible to do arithmetic directly on rtx_mode_ts and
187 constants. For example:
188
189 wi::add (r1, r2); // add equal-sized rtx_mode_ts r1 and r2
190 wi::add (r1, 1); // add 1 to rtx_mode_t r1
191 wi::lshift (1, 100); // 1 << 100 as a widest_int
192
193 Many binary operations place restrictions on the combinations of inputs,
194 using the following rules:
195
196 - {rtx, wide_int} op {rtx, wide_int} -> wide_int
197 The inputs must be the same precision. The result is a wide_int
198 of the same precision
199
200 - {rtx, wide_int} op (un)signed HOST_WIDE_INT -> wide_int
201 (un)signed HOST_WIDE_INT op {rtx, wide_int} -> wide_int
202 The HOST_WIDE_INT is extended or truncated to the precision of
203 the other input. The result is a wide_int of the same precision
204 as that input.
205
206 - (un)signed HOST_WIDE_INT op (un)signed HOST_WIDE_INT -> widest_int
207 The inputs are extended to widest_int precision and produce a
208 widest_int result.
209
210 - offset_int op offset_int -> offset_int
211 offset_int op (un)signed HOST_WIDE_INT -> offset_int
212 (un)signed HOST_WIDE_INT op offset_int -> offset_int
213
214 - widest_int op widest_int -> widest_int
215 widest_int op (un)signed HOST_WIDE_INT -> widest_int
216 (un)signed HOST_WIDE_INT op widest_int -> widest_int
217
218 Other combinations like:
219
220 - widest_int op offset_int and
221 - wide_int op offset_int
222
223 are not allowed. The inputs should instead be extended or truncated
224 so that they match.
225
226 The inputs to comparison functions like wi::eq_p and wi::lts_p
227 follow the same compatibility rules, although their return types
228 are different. Unary functions on X produce the same result as
229 a binary operation X + X. Shift functions X op Y also produce
230 the same result as X + X; the precision of the shift amount Y
231 can be arbitrarily different from X. */
232
233/* The MAX_BITSIZE_MODE_ANY_INT is automatically generated by a very
234 early examination of the target's mode file. The WIDE_INT_MAX_ELTS
235 can accomodate at least 1 more bit so that unsigned numbers of that
236 mode can be represented as a signed value. Note that it is still
237 possible to create fixed_wide_ints that have precisions greater than
238 MAX_BITSIZE_MODE_ANY_INT. This can be useful when representing a
239 double-width multiplication result, for example. */
240#define WIDE_INT_MAX_ELTS((160 + 64) / 64) \
241 ((MAX_BITSIZE_MODE_ANY_INT160 + HOST_BITS_PER_WIDE_INT64) / HOST_BITS_PER_WIDE_INT64)
242
243#define WIDE_INT_MAX_PRECISION(((160 + 64) / 64) * 64) (WIDE_INT_MAX_ELTS((160 + 64) / 64) * HOST_BITS_PER_WIDE_INT64)
244
245/* This is the max size of any pointer on any machine. It does not
246 seem to be as easy to sniff this out of the machine description as
247 it is for MAX_BITSIZE_MODE_ANY_INT since targets may support
248 multiple address sizes and may have different address sizes for
249 different address spaces. However, currently the largest pointer
250 on any platform is 64 bits. When that changes, then it is likely
251 that a target hook should be defined so that targets can make this
252 value larger for those targets. */
253#define ADDR_MAX_BITSIZE64 64
254
255/* This is the internal precision used when doing any address
256 arithmetic. The '4' is really 3 + 1. Three of the bits are for
257 the number of extra bits needed to do bit addresses and the other bit
258 is to allow everything to be signed without loosing any precision.
259 Then everything is rounded up to the next HWI for efficiency. */
260#define ADDR_MAX_PRECISION((64 + 4 + 64 - 1) & ~(64 - 1)) \
261 ((ADDR_MAX_BITSIZE64 + 4 + HOST_BITS_PER_WIDE_INT64 - 1) \
262 & ~(HOST_BITS_PER_WIDE_INT64 - 1))
263
264/* The number of HWIs needed to store an offset_int. */
265#define OFFSET_INT_ELTS(((64 + 4 + 64 - 1) & ~(64 - 1)) / 64) (ADDR_MAX_PRECISION((64 + 4 + 64 - 1) & ~(64 - 1)) / HOST_BITS_PER_WIDE_INT64)
266
267/* The type of result produced by a binary operation on types T1 and T2.
268 Defined purely for brevity. */
269#define WI_BINARY_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::result_type \
270 typename wi::binary_traits <T1, T2>::result_type
271
272/* Likewise for binary operators, which excludes the case in which neither
273 T1 nor T2 is a wide-int-based type. */
274#define WI_BINARY_OPERATOR_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::operator_result \
275 typename wi::binary_traits <T1, T2>::operator_result
276
277/* The type of result produced by T1 << T2. Leads to substitution failure
278 if the operation isn't supported. Defined purely for brevity. */
279#define WI_SIGNED_SHIFT_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::signed_shift_result_type \
280 typename wi::binary_traits <T1, T2>::signed_shift_result_type
281
282/* The type of result produced by a sign-agnostic binary predicate on
283 types T1 and T2. This is bool if wide-int operations make sense for
284 T1 and T2 and leads to substitution failure otherwise. */
285#define WI_BINARY_PREDICATE_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::predicate_result \
286 typename wi::binary_traits <T1, T2>::predicate_result
287
288/* The type of result produced by a signed binary predicate on types T1 and T2.
289 This is bool if signed comparisons make sense for T1 and T2 and leads to
290 substitution failure otherwise. */
291#define WI_SIGNED_BINARY_PREDICATE_RESULT(T1, T2)typename wi::binary_traits <T1, T2>::signed_predicate_result \
292 typename wi::binary_traits <T1, T2>::signed_predicate_result
293
294/* The type of result produced by a unary operation on type T. */
295#define WI_UNARY_RESULT(T)typename wi::binary_traits <T, T>::result_type \
296 typename wi::binary_traits <T, T>::result_type
297
298/* Define a variable RESULT to hold the result of a binary operation on
299 X and Y, which have types T1 and T2 respectively. Define VAL to
300 point to the blocks of RESULT. Once the user of the macro has
301 filled in VAL, it should call RESULT.set_len to set the number
302 of initialized blocks. */
303#define WI_BINARY_RESULT_VAR(RESULT, VAL, T1, X, T2, Y)typename wi::binary_traits <T1, T2>::result_type RESULT
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (X, Y); long *VAL = RESULT
.write_val ()
\
304 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type RESULT = \
305 wi::int_traits <WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type>::get_binary_result (X, Y); \
306 HOST_WIDE_INTlong *VAL = RESULT.write_val ()
307
308/* Similar for the result of a unary operation on X, which has type T. */
309#define WI_UNARY_RESULT_VAR(RESULT, VAL, T, X)typename wi::binary_traits <T, T>::result_type RESULT =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (X, X); long *VAL = RESULT
.write_val ()
\
310 WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type RESULT = \
311 wi::int_traits <WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type>::get_binary_result (X, X); \
312 HOST_WIDE_INTlong *VAL = RESULT.write_val ()
313
314template <typename T> class generic_wide_int;
315template <int N> class fixed_wide_int_storage;
316class wide_int_storage;
317
318/* An N-bit integer. Until we can use typedef templates, use this instead. */
319#define FIXED_WIDE_INT(N)generic_wide_int < fixed_wide_int_storage <N> > \
320 generic_wide_int < fixed_wide_int_storage <N> >
321
322typedef generic_wide_int <wide_int_storage> wide_int;
323typedef FIXED_WIDE_INT (ADDR_MAX_PRECISION)generic_wide_int < fixed_wide_int_storage <((64 + 4 + 64
- 1) & ~(64 - 1))> >
offset_int;
324typedef FIXED_WIDE_INT (WIDE_INT_MAX_PRECISION)generic_wide_int < fixed_wide_int_storage <(((160 + 64)
/ 64) * 64)> >
widest_int;
325/* Spelled out explicitly (rather than through FIXED_WIDE_INT)
326 so as not to confuse gengtype. */
327typedef generic_wide_int < fixed_wide_int_storage <WIDE_INT_MAX_PRECISION(((160 + 64) / 64) * 64) * 2> > widest2_int;
328
329/* wi::storage_ref can be a reference to a primitive type,
330 so this is the conservatively-correct setting. */
331template <bool SE, bool HDP = true>
332class wide_int_ref_storage;
333
334typedef generic_wide_int <wide_int_ref_storage <false> > wide_int_ref;
335
336/* This can be used instead of wide_int_ref if the referenced value is
337 known to have type T. It carries across properties of T's representation,
338 such as whether excess upper bits in a HWI are defined, and can therefore
339 help avoid redundant work.
340
341 The macro could be replaced with a template typedef, once we're able
342 to use those. */
343#define WIDE_INT_REF_FOR(T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
\
344 generic_wide_int \
345 <wide_int_ref_storage <wi::int_traits <T>::is_sign_extended, \
346 wi::int_traits <T>::host_dependent_precision> >
347
348namespace wi
349{
350 /* Operations that calculate overflow do so even for
351 TYPE_OVERFLOW_WRAPS types. For example, adding 1 to +MAX_INT in
352 an unsigned int is 0 and does not overflow in C/C++, but wi::add
353 will set the overflow argument in case it's needed for further
354 analysis.
355
356 For operations that require overflow, these are the different
357 types of overflow. */
358 enum overflow_type {
359 OVF_NONE = 0,
360 OVF_UNDERFLOW = -1,
361 OVF_OVERFLOW = 1,
362 /* There was an overflow, but we are unsure whether it was an
363 overflow or an underflow. */
364 OVF_UNKNOWN = 2
365 };
366
367 /* Classifies an integer based on its precision. */
368 enum precision_type {
369 /* The integer has both a precision and defined signedness. This allows
370 the integer to be converted to any width, since we know whether to fill
371 any extra bits with zeros or signs. */
372 FLEXIBLE_PRECISION,
373
374 /* The integer has a variable precision but no defined signedness. */
375 VAR_PRECISION,
376
377 /* The integer has a constant precision (known at GCC compile time)
378 and is signed. */
379 CONST_PRECISION
380 };
381
382 /* This class, which has no default implementation, is expected to
383 provide the following members:
384
385 static const enum precision_type precision_type;
386 Classifies the type of T.
387
388 static const unsigned int precision;
389 Only defined if precision_type == CONST_PRECISION. Specifies the
390 precision of all integers of type T.
391
392 static const bool host_dependent_precision;
393 True if the precision of T depends (or can depend) on the host.
394
395 static unsigned int get_precision (const T &x)
396 Return the number of bits in X.
397
398 static wi::storage_ref *decompose (HOST_WIDE_INT *scratch,
399 unsigned int precision, const T &x)
400 Decompose X as a PRECISION-bit integer, returning the associated
401 wi::storage_ref. SCRATCH is available as scratch space if needed.
402 The routine should assert that PRECISION is acceptable. */
403 template <typename T> struct int_traits;
404
405 /* This class provides a single type, result_type, which specifies the
406 type of integer produced by a binary operation whose inputs have
407 types T1 and T2. The definition should be symmetric. */
408 template <typename T1, typename T2,
409 enum precision_type P1 = int_traits <T1>::precision_type,
410 enum precision_type P2 = int_traits <T2>::precision_type>
411 struct binary_traits;
412
413 /* Specify the result type for each supported combination of binary
414 inputs. Note that CONST_PRECISION and VAR_PRECISION cannot be
415 mixed, in order to give stronger type checking. When both inputs
416 are CONST_PRECISION, they must have the same precision. */
417 template <typename T1, typename T2>
418 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, FLEXIBLE_PRECISION>
419 {
420 typedef widest_int result_type;
421 /* Don't define operators for this combination. */
422 };
423
424 template <typename T1, typename T2>
425 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, VAR_PRECISION>
426 {
427 typedef wide_int result_type;
428 typedef result_type operator_result;
429 typedef bool predicate_result;
430 };
431
432 template <typename T1, typename T2>
433 struct binary_traits <T1, T2, FLEXIBLE_PRECISION, CONST_PRECISION>
434 {
435 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
436 so as not to confuse gengtype. */
437 typedef generic_wide_int < fixed_wide_int_storage
438 <int_traits <T2>::precision> > result_type;
439 typedef result_type operator_result;
440 typedef bool predicate_result;
441 typedef result_type signed_shift_result_type;
442 typedef bool signed_predicate_result;
443 };
444
445 template <typename T1, typename T2>
446 struct binary_traits <T1, T2, VAR_PRECISION, FLEXIBLE_PRECISION>
447 {
448 typedef wide_int result_type;
449 typedef result_type operator_result;
450 typedef bool predicate_result;
451 };
452
453 template <typename T1, typename T2>
454 struct binary_traits <T1, T2, CONST_PRECISION, FLEXIBLE_PRECISION>
455 {
456 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
457 so as not to confuse gengtype. */
458 typedef generic_wide_int < fixed_wide_int_storage
459 <int_traits <T1>::precision> > result_type;
460 typedef result_type operator_result;
461 typedef bool predicate_result;
462 typedef result_type signed_shift_result_type;
463 typedef bool signed_predicate_result;
464 };
465
466 template <typename T1, typename T2>
467 struct binary_traits <T1, T2, CONST_PRECISION, CONST_PRECISION>
468 {
469 STATIC_ASSERT (int_traits <T1>::precision == int_traits <T2>::precision)static_assert ((int_traits <T1>::precision == int_traits
<T2>::precision), "int_traits <T1>::precision == int_traits <T2>::precision"
)
;
470 /* Spelled out explicitly (rather than through FIXED_WIDE_INT)
471 so as not to confuse gengtype. */
472 typedef generic_wide_int < fixed_wide_int_storage
473 <int_traits <T1>::precision> > result_type;
474 typedef result_type operator_result;
475 typedef bool predicate_result;
476 typedef result_type signed_shift_result_type;
477 typedef bool signed_predicate_result;
478 };
479
480 template <typename T1, typename T2>
481 struct binary_traits <T1, T2, VAR_PRECISION, VAR_PRECISION>
482 {
483 typedef wide_int result_type;
484 typedef result_type operator_result;
485 typedef bool predicate_result;
486 };
487}
488
489/* Public functions for querying and operating on integers. */
490namespace wi
491{
492 template <typename T>
493 unsigned int get_precision (const T &);
494
495 template <typename T1, typename T2>
496 unsigned int get_binary_precision (const T1 &, const T2 &);
497
498 template <typename T1, typename T2>
499 void copy (T1 &, const T2 &);
500
501#define UNARY_PREDICATE \
502 template <typename T> bool
503#define UNARY_FUNCTION \
504 template <typename T> WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
505#define BINARY_PREDICATE \
506 template <typename T1, typename T2> bool
507#define BINARY_FUNCTION \
508 template <typename T1, typename T2> WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
509#define SHIFT_FUNCTION \
510 template <typename T1, typename T2> WI_UNARY_RESULT (T1)typename wi::binary_traits <T1, T1>::result_type
511
512 UNARY_PREDICATE fits_shwi_p (const T &);
513 UNARY_PREDICATE fits_uhwi_p (const T &);
514 UNARY_PREDICATE neg_p (const T &, signop = SIGNED);
515
516 template <typename T>
517 HOST_WIDE_INTlong sign_mask (const T &);
518
519 BINARY_PREDICATE eq_p (const T1 &, const T2 &);
520 BINARY_PREDICATE ne_p (const T1 &, const T2 &);
521 BINARY_PREDICATE lt_p (const T1 &, const T2 &, signop);
522 BINARY_PREDICATE lts_p (const T1 &, const T2 &);
523 BINARY_PREDICATE ltu_p (const T1 &, const T2 &);
524 BINARY_PREDICATE le_p (const T1 &, const T2 &, signop);
525 BINARY_PREDICATE les_p (const T1 &, const T2 &);
526 BINARY_PREDICATE leu_p (const T1 &, const T2 &);
527 BINARY_PREDICATE gt_p (const T1 &, const T2 &, signop);
528 BINARY_PREDICATE gts_p (const T1 &, const T2 &);
529 BINARY_PREDICATE gtu_p (const T1 &, const T2 &);
530 BINARY_PREDICATE ge_p (const T1 &, const T2 &, signop);
531 BINARY_PREDICATE ges_p (const T1 &, const T2 &);
532 BINARY_PREDICATE geu_p (const T1 &, const T2 &);
533
534 template <typename T1, typename T2>
535 int cmp (const T1 &, const T2 &, signop);
536
537 template <typename T1, typename T2>
538 int cmps (const T1 &, const T2 &);
539
540 template <typename T1, typename T2>
541 int cmpu (const T1 &, const T2 &);
542
543 UNARY_FUNCTION bit_not (const T &);
544 UNARY_FUNCTION neg (const T &);
545 UNARY_FUNCTION neg (const T &, overflow_type *);
546 UNARY_FUNCTION abs (const T &);
547 UNARY_FUNCTION ext (const T &, unsigned int, signop);
548 UNARY_FUNCTION sext (const T &, unsigned int);
549 UNARY_FUNCTION zext (const T &, unsigned int);
550 UNARY_FUNCTION set_bit (const T &, unsigned int);
551
552 BINARY_FUNCTION min (const T1 &, const T2 &, signop);
553 BINARY_FUNCTION smin (const T1 &, const T2 &);
554 BINARY_FUNCTION umin (const T1 &, const T2 &);
555 BINARY_FUNCTION max (const T1 &, const T2 &, signop);
556 BINARY_FUNCTION smax (const T1 &, const T2 &);
557 BINARY_FUNCTION umax (const T1 &, const T2 &);
558
559 BINARY_FUNCTION bit_and (const T1 &, const T2 &);
560 BINARY_FUNCTION bit_and_not (const T1 &, const T2 &);
561 BINARY_FUNCTION bit_or (const T1 &, const T2 &);
562 BINARY_FUNCTION bit_or_not (const T1 &, const T2 &);
563 BINARY_FUNCTION bit_xor (const T1 &, const T2 &);
564 BINARY_FUNCTION add (const T1 &, const T2 &);
565 BINARY_FUNCTION add (const T1 &, const T2 &, signop, overflow_type *);
566 BINARY_FUNCTION sub (const T1 &, const T2 &);
567 BINARY_FUNCTION sub (const T1 &, const T2 &, signop, overflow_type *);
568 BINARY_FUNCTION mul (const T1 &, const T2 &);
569 BINARY_FUNCTION mul (const T1 &, const T2 &, signop, overflow_type *);
570 BINARY_FUNCTION smul (const T1 &, const T2 &, overflow_type *);
571 BINARY_FUNCTION umul (const T1 &, const T2 &, overflow_type *);
572 BINARY_FUNCTION mul_high (const T1 &, const T2 &, signop);
573 BINARY_FUNCTION div_trunc (const T1 &, const T2 &, signop,
574 overflow_type * = 0);
575 BINARY_FUNCTION sdiv_trunc (const T1 &, const T2 &);
576 BINARY_FUNCTION udiv_trunc (const T1 &, const T2 &);
577 BINARY_FUNCTION div_floor (const T1 &, const T2 &, signop,
578 overflow_type * = 0);
579 BINARY_FUNCTION udiv_floor (const T1 &, const T2 &);
580 BINARY_FUNCTION sdiv_floor (const T1 &, const T2 &);
581 BINARY_FUNCTION div_ceil (const T1 &, const T2 &, signop,
582 overflow_type * = 0);
583 BINARY_FUNCTION udiv_ceil (const T1 &, const T2 &);
584 BINARY_FUNCTION div_round (const T1 &, const T2 &, signop,
585 overflow_type * = 0);
586 BINARY_FUNCTION divmod_trunc (const T1 &, const T2 &, signop,
587 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type *);
588 BINARY_FUNCTION gcd (const T1 &, const T2 &, signop = UNSIGNED);
589 BINARY_FUNCTION mod_trunc (const T1 &, const T2 &, signop,
590 overflow_type * = 0);
591 BINARY_FUNCTION smod_trunc (const T1 &, const T2 &);
592 BINARY_FUNCTION umod_trunc (const T1 &, const T2 &);
593 BINARY_FUNCTION mod_floor (const T1 &, const T2 &, signop,
594 overflow_type * = 0);
595 BINARY_FUNCTION umod_floor (const T1 &, const T2 &);
596 BINARY_FUNCTION mod_ceil (const T1 &, const T2 &, signop,
597 overflow_type * = 0);
598 BINARY_FUNCTION mod_round (const T1 &, const T2 &, signop,
599 overflow_type * = 0);
600
601 template <typename T1, typename T2>
602 bool multiple_of_p (const T1 &, const T2 &, signop);
603
604 template <typename T1, typename T2>
605 bool multiple_of_p (const T1 &, const T2 &, signop,
606 WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type *);
607
608 SHIFT_FUNCTION lshift (const T1 &, const T2 &);
609 SHIFT_FUNCTION lrshift (const T1 &, const T2 &);
610 SHIFT_FUNCTION arshift (const T1 &, const T2 &);
611 SHIFT_FUNCTION rshift (const T1 &, const T2 &, signop sgn);
612 SHIFT_FUNCTION lrotate (const T1 &, const T2 &, unsigned int = 0);
613 SHIFT_FUNCTION rrotate (const T1 &, const T2 &, unsigned int = 0);
614
615#undef SHIFT_FUNCTION
616#undef BINARY_PREDICATE
617#undef BINARY_FUNCTION
618#undef UNARY_PREDICATE
619#undef UNARY_FUNCTION
620
621 bool only_sign_bit_p (const wide_int_ref &, unsigned int);
622 bool only_sign_bit_p (const wide_int_ref &);
623 int clz (const wide_int_ref &);
624 int clrsb (const wide_int_ref &);
625 int ctz (const wide_int_ref &);
626 int exact_log2 (const wide_int_ref &);
627 int floor_log2 (const wide_int_ref &);
628 int ffs (const wide_int_ref &);
629 int popcount (const wide_int_ref &);
630 int parity (const wide_int_ref &);
631
632 template <typename T>
633 unsigned HOST_WIDE_INTlong extract_uhwi (const T &, unsigned int, unsigned int);
634
635 template <typename T>
636 unsigned int min_precision (const T &, signop);
637
638 static inline void accumulate_overflow (overflow_type &, overflow_type);
639}
640
641namespace wi
642{
643 /* Contains the components of a decomposed integer for easy, direct
644 access. */
645 class storage_ref
646 {
647 public:
648 storage_ref () {}
649 storage_ref (const HOST_WIDE_INTlong *, unsigned int, unsigned int);
650
651 const HOST_WIDE_INTlong *val;
652 unsigned int len;
653 unsigned int precision;
654
655 /* Provide enough trappings for this class to act as storage for
656 generic_wide_int. */
657 unsigned int get_len () const;
658 unsigned int get_precision () const;
659 const HOST_WIDE_INTlong *get_val () const;
660 };
661}
662
663inline::wi::storage_ref::storage_ref (const HOST_WIDE_INTlong *val_in,
664 unsigned int len_in,
665 unsigned int precision_in)
666 : val (val_in), len (len_in), precision (precision_in)
667{
668}
669
670inline unsigned int
671wi::storage_ref::get_len () const
672{
673 return len;
674}
675
676inline unsigned int
677wi::storage_ref::get_precision () const
678{
679 return precision;
680}
681
682inline const HOST_WIDE_INTlong *
683wi::storage_ref::get_val () const
684{
685 return val;
686}
687
688/* This class defines an integer type using the storage provided by the
689 template argument. The storage class must provide the following
690 functions:
691
692 unsigned int get_precision () const
693 Return the number of bits in the integer.
694
695 HOST_WIDE_INT *get_val () const
696 Return a pointer to the array of blocks that encodes the integer.
697
698 unsigned int get_len () const
699 Return the number of blocks in get_val (). If this is smaller
700 than the number of blocks implied by get_precision (), the
701 remaining blocks are sign extensions of block get_len () - 1.
702
703 Although not required by generic_wide_int itself, writable storage
704 classes can also provide the following functions:
705
706 HOST_WIDE_INT *write_val ()
707 Get a modifiable version of get_val ()
708
709 unsigned int set_len (unsigned int len)
710 Set the value returned by get_len () to LEN. */
711template <typename storage>
712class GTY(()) generic_wide_int : public storage
713{
714public:
715 generic_wide_int ();
716
717 template <typename T>
718 generic_wide_int (const T &);
719
720 template <typename T>
721 generic_wide_int (const T &, unsigned int);
722
723 /* Conversions. */
724 HOST_WIDE_INTlong to_shwi (unsigned int) const;
725 HOST_WIDE_INTlong to_shwi () const;
726 unsigned HOST_WIDE_INTlong to_uhwi (unsigned int) const;
727 unsigned HOST_WIDE_INTlong to_uhwi () const;
728 HOST_WIDE_INTlong to_short_addr () const;
729
730 /* Public accessors for the interior of a wide int. */
731 HOST_WIDE_INTlong sign_mask () const;
732 HOST_WIDE_INTlong elt (unsigned int) const;
733 HOST_WIDE_INTlong sext_elt (unsigned int) const;
734 unsigned HOST_WIDE_INTlong ulow () const;
735 unsigned HOST_WIDE_INTlong uhigh () const;
736 HOST_WIDE_INTlong slow () const;
737 HOST_WIDE_INTlong shigh () const;
738
739 template <typename T>
740 generic_wide_int &operator = (const T &);
741
742#define ASSIGNMENT_OPERATOR(OP, F) \
743 template <typename T> \
744 generic_wide_int &OP (const T &c) { return (*this = wi::F (*this, c)); }
745
746/* Restrict these to cases where the shift operator is defined. */
747#define SHIFT_ASSIGNMENT_OPERATOR(OP, OP2) \
748 template <typename T> \
749 generic_wide_int &OP (const T &c) { return (*this = *this OP2 c); }
750
751#define INCDEC_OPERATOR(OP, DELTA) \
752 generic_wide_int &OP () { *this += DELTA; return *this; }
753
754 ASSIGNMENT_OPERATOR (operator &=, bit_and)
755 ASSIGNMENT_OPERATOR (operator |=, bit_or)
756 ASSIGNMENT_OPERATOR (operator ^=, bit_xor)
757 ASSIGNMENT_OPERATOR (operator +=, add)
758 ASSIGNMENT_OPERATOR (operator -=, sub)
759 ASSIGNMENT_OPERATOR (operator *=, mul)
760 ASSIGNMENT_OPERATOR (operator <<=, lshift)
761 SHIFT_ASSIGNMENT_OPERATOR (operator >>=, >>)
762 INCDEC_OPERATOR (operator ++, 1)
763 INCDEC_OPERATOR (operator --, -1)
764
765#undef SHIFT_ASSIGNMENT_OPERATOR
766#undef ASSIGNMENT_OPERATOR
767#undef INCDEC_OPERATOR
768
769 /* Debugging functions. */
770 void dump () const;
771
772 static const bool is_sign_extended
773 = wi::int_traits <generic_wide_int <storage> >::is_sign_extended;
774};
775
776template <typename storage>
777inline generic_wide_int <storage>::generic_wide_int () {}
778
779template <typename storage>
780template <typename T>
781inline generic_wide_int <storage>::generic_wide_int (const T &x)
782 : storage (x)
21
Calling constructor for 'wide_int_storage'
783{
784}
785
786template <typename storage>
787template <typename T>
788inline generic_wide_int <storage>::generic_wide_int (const T &x,
789 unsigned int precision)
790 : storage (x, precision)
791{
792}
793
794/* Return THIS as a signed HOST_WIDE_INT, sign-extending from PRECISION.
795 If THIS does not fit in PRECISION, the information is lost. */
796template <typename storage>
797inline HOST_WIDE_INTlong
798generic_wide_int <storage>::to_shwi (unsigned int precision) const
799{
800 if (precision < HOST_BITS_PER_WIDE_INT64)
801 return sext_hwi (this->get_val ()[0], precision);
802 else
803 return this->get_val ()[0];
804}
805
806/* Return THIS as a signed HOST_WIDE_INT, in its natural precision. */
807template <typename storage>
808inline HOST_WIDE_INTlong
809generic_wide_int <storage>::to_shwi () const
810{
811 if (is_sign_extended)
812 return this->get_val ()[0];
813 else
814 return to_shwi (this->get_precision ());
815}
816
817/* Return THIS as an unsigned HOST_WIDE_INT, zero-extending from
818 PRECISION. If THIS does not fit in PRECISION, the information
819 is lost. */
820template <typename storage>
821inline unsigned HOST_WIDE_INTlong
822generic_wide_int <storage>::to_uhwi (unsigned int precision) const
823{
824 if (precision < HOST_BITS_PER_WIDE_INT64)
825 return zext_hwi (this->get_val ()[0], precision);
826 else
827 return this->get_val ()[0];
828}
829
830/* Return THIS as an signed HOST_WIDE_INT, in its natural precision. */
831template <typename storage>
832inline unsigned HOST_WIDE_INTlong
833generic_wide_int <storage>::to_uhwi () const
834{
835 return to_uhwi (this->get_precision ());
836}
837
838/* TODO: The compiler is half converted from using HOST_WIDE_INT to
839 represent addresses to using offset_int to represent addresses.
840 We use to_short_addr at the interface from new code to old,
841 unconverted code. */
842template <typename storage>
843inline HOST_WIDE_INTlong
844generic_wide_int <storage>::to_short_addr () const
845{
846 return this->get_val ()[0];
847}
848
849/* Return the implicit value of blocks above get_len (). */
850template <typename storage>
851inline HOST_WIDE_INTlong
852generic_wide_int <storage>::sign_mask () const
853{
854 unsigned int len = this->get_len ();
855 gcc_assert (len > 0)((void)(!(len > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 855, __FUNCTION__), 0 : 0))
;
856
857 unsigned HOST_WIDE_INTlong high = this->get_val ()[len - 1];
858 if (!is_sign_extended)
859 {
860 unsigned int precision = this->get_precision ();
861 int excess = len * HOST_BITS_PER_WIDE_INT64 - precision;
862 if (excess > 0)
863 high <<= excess;
864 }
865 return (HOST_WIDE_INTlong) (high) < 0 ? -1 : 0;
866}
867
868/* Return the signed value of the least-significant explicitly-encoded
869 block. */
870template <typename storage>
871inline HOST_WIDE_INTlong
872generic_wide_int <storage>::slow () const
873{
874 return this->get_val ()[0];
875}
876
877/* Return the signed value of the most-significant explicitly-encoded
878 block. */
879template <typename storage>
880inline HOST_WIDE_INTlong
881generic_wide_int <storage>::shigh () const
882{
883 return this->get_val ()[this->get_len () - 1];
884}
885
886/* Return the unsigned value of the least-significant
887 explicitly-encoded block. */
888template <typename storage>
889inline unsigned HOST_WIDE_INTlong
890generic_wide_int <storage>::ulow () const
891{
892 return this->get_val ()[0];
893}
894
895/* Return the unsigned value of the most-significant
896 explicitly-encoded block. */
897template <typename storage>
898inline unsigned HOST_WIDE_INTlong
899generic_wide_int <storage>::uhigh () const
900{
901 return this->get_val ()[this->get_len () - 1];
902}
903
904/* Return block I, which might be implicitly or explicit encoded. */
905template <typename storage>
906inline HOST_WIDE_INTlong
907generic_wide_int <storage>::elt (unsigned int i) const
908{
909 if (i >= this->get_len ())
910 return sign_mask ();
911 else
912 return this->get_val ()[i];
913}
914
915/* Like elt, but sign-extend beyond the upper bit, instead of returning
916 the raw encoding. */
917template <typename storage>
918inline HOST_WIDE_INTlong
919generic_wide_int <storage>::sext_elt (unsigned int i) const
920{
921 HOST_WIDE_INTlong elt_i = elt (i);
922 if (!is_sign_extended)
923 {
924 unsigned int precision = this->get_precision ();
925 unsigned int lsb = i * HOST_BITS_PER_WIDE_INT64;
926 if (precision - lsb < HOST_BITS_PER_WIDE_INT64)
927 elt_i = sext_hwi (elt_i, precision - lsb);
928 }
929 return elt_i;
930}
931
932template <typename storage>
933template <typename T>
934inline generic_wide_int <storage> &
935generic_wide_int <storage>::operator = (const T &x)
936{
937 storage::operator = (x);
938 return *this;
939}
940
941/* Dump the contents of the integer to stderr, for debugging. */
942template <typename storage>
943void
944generic_wide_int <storage>::dump () const
945{
946 unsigned int len = this->get_len ();
947 const HOST_WIDE_INTlong *val = this->get_val ();
948 unsigned int precision = this->get_precision ();
949 fprintf (stderrstderr, "[");
950 if (len * HOST_BITS_PER_WIDE_INT64 < precision)
951 fprintf (stderrstderr, "...,");
952 for (unsigned int i = 0; i < len - 1; ++i)
953 fprintf (stderrstderr, HOST_WIDE_INT_PRINT_HEX"%#" "l" "x" ",", val[len - 1 - i]);
954 fprintf (stderrstderr, HOST_WIDE_INT_PRINT_HEX"%#" "l" "x" "], precision = %d\n",
955 val[0], precision);
956}
957
958namespace wi
959{
960 template <typename storage>
961 struct int_traits < generic_wide_int <storage> >
962 : public wi::int_traits <storage>
963 {
964 static unsigned int get_precision (const generic_wide_int <storage> &);
965 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int,
966 const generic_wide_int <storage> &);
967 };
968}
969
970template <typename storage>
971inline unsigned int
972wi::int_traits < generic_wide_int <storage> >::
973get_precision (const generic_wide_int <storage> &x)
974{
975 return x.get_precision ();
976}
977
978template <typename storage>
979inline wi::storage_ref
980wi::int_traits < generic_wide_int <storage> >::
981decompose (HOST_WIDE_INTlong *, unsigned int precision,
982 const generic_wide_int <storage> &x)
983{
984 gcc_checking_assert (precision == x.get_precision ())((void)(!(precision == x.get_precision ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 984, __FUNCTION__), 0 : 0))
;
985 return wi::storage_ref (x.get_val (), x.get_len (), precision);
986}
987
988/* Provide the storage for a wide_int_ref. This acts like a read-only
989 wide_int, with the optimization that VAL is normally a pointer to
990 another integer's storage, so that no array copy is needed. */
991template <bool SE, bool HDP>
992class wide_int_ref_storage : public wi::storage_ref
993{
994private:
995 /* Scratch space that can be used when decomposing the original integer.
996 It must live as long as this object. */
997 HOST_WIDE_INTlong scratch[2];
998
999public:
1000 wide_int_ref_storage () {}
1001
1002 wide_int_ref_storage (const wi::storage_ref &);
1003
1004 template <typename T>
1005 wide_int_ref_storage (const T &);
1006
1007 template <typename T>
1008 wide_int_ref_storage (const T &, unsigned int);
1009};
1010
1011/* Create a reference from an existing reference. */
1012template <bool SE, bool HDP>
1013inline wide_int_ref_storage <SE, HDP>::
1014wide_int_ref_storage (const wi::storage_ref &x)
1015 : storage_ref (x)
1016{}
1017
1018/* Create a reference to integer X in its natural precision. Note
1019 that the natural precision is host-dependent for primitive
1020 types. */
1021template <bool SE, bool HDP>
1022template <typename T>
1023inline wide_int_ref_storage <SE, HDP>::wide_int_ref_storage (const T &x)
1024 : storage_ref (wi::int_traits <T>::decompose (scratch,
1025 wi::get_precision (x), x))
1026{
1027}
1028
1029/* Create a reference to integer X in precision PRECISION. */
1030template <bool SE, bool HDP>
1031template <typename T>
1032inline wide_int_ref_storage <SE, HDP>::
1033wide_int_ref_storage (const T &x, unsigned int precision)
1034 : storage_ref (wi::int_traits <T>::decompose (scratch, precision, x))
1035{
1036}
1037
1038namespace wi
1039{
1040 template <bool SE, bool HDP>
1041 struct int_traits <wide_int_ref_storage <SE, HDP> >
1042 {
1043 static const enum precision_type precision_type = VAR_PRECISION;
1044 static const bool host_dependent_precision = HDP;
1045 static const bool is_sign_extended = SE;
1046 };
1047}
1048
1049namespace wi
1050{
1051 unsigned int force_to_size (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1052 unsigned int, unsigned int, unsigned int,
1053 signop sgn);
1054 unsigned int from_array (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1055 unsigned int, unsigned int, bool = true);
1056}
1057
1058/* The storage used by wide_int. */
1059class GTY(()) wide_int_storage
1060{
1061private:
1062 HOST_WIDE_INTlong val[WIDE_INT_MAX_ELTS((160 + 64) / 64)];
1063 unsigned int len;
1064 unsigned int precision;
1065
1066public:
1067 wide_int_storage ();
1068 template <typename T>
1069 wide_int_storage (const T &);
1070
1071 /* The standard generic_wide_int storage methods. */
1072 unsigned int get_precision () const;
1073 const HOST_WIDE_INTlong *get_val () const;
1074 unsigned int get_len () const;
1075 HOST_WIDE_INTlong *write_val ();
1076 void set_len (unsigned int, bool = false);
1077
1078 template <typename T>
1079 wide_int_storage &operator = (const T &);
1080
1081 static wide_int from (const wide_int_ref &, unsigned int, signop);
1082 static wide_int from_array (const HOST_WIDE_INTlong *, unsigned int,
1083 unsigned int, bool = true);
1084 static wide_int create (unsigned int);
1085
1086 /* FIXME: target-dependent, so should disappear. */
1087 wide_int bswap () const;
1088};
1089
1090namespace wi
1091{
1092 template <>
1093 struct int_traits <wide_int_storage>
1094 {
1095 static const enum precision_type precision_type = VAR_PRECISION;
1096 /* Guaranteed by a static assert in the wide_int_storage constructor. */
1097 static const bool host_dependent_precision = false;
1098 static const bool is_sign_extended = true;
1099 template <typename T1, typename T2>
1100 static wide_int get_binary_result (const T1 &, const T2 &);
1101 };
1102}
1103
1104inline wide_int_storage::wide_int_storage () {}
1105
1106/* Initialize the storage from integer X, in its natural precision.
1107 Note that we do not allow integers with host-dependent precision
1108 to become wide_ints; wide_ints must always be logically independent
1109 of the host. */
1110template <typename T>
1111inline wide_int_storage::wide_int_storage (const T &x)
1112{
1113 { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision)static_assert ((!wi::int_traits<T>::host_dependent_precision
), "!wi::int_traits<T>::host_dependent_precision")
; }
1114 { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION)static_assert ((wi::int_traits<T>::precision_type != wi
::CONST_PRECISION), "wi::int_traits<T>::precision_type != wi::CONST_PRECISION"
)
; }
1115 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1116 precision = xi.precision;
1117 wi::copy (*this, xi);
22
Calling 'copy<wide_int_storage, generic_wide_int<wide_int_ref_storage<false, false>>>'
1118}
1119
1120template <typename T>
1121inline wide_int_storage&
1122wide_int_storage::operator = (const T &x)
1123{
1124 { STATIC_ASSERT (!wi::int_traits<T>::host_dependent_precision)static_assert ((!wi::int_traits<T>::host_dependent_precision
), "!wi::int_traits<T>::host_dependent_precision")
; }
1125 { STATIC_ASSERT (wi::int_traits<T>::precision_type != wi::CONST_PRECISION)static_assert ((wi::int_traits<T>::precision_type != wi
::CONST_PRECISION), "wi::int_traits<T>::precision_type != wi::CONST_PRECISION"
)
; }
1126 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1127 precision = xi.precision;
1128 wi::copy (*this, xi);
1129 return *this;
1130}
1131
1132inline unsigned int
1133wide_int_storage::get_precision () const
1134{
1135 return precision;
1136}
1137
1138inline const HOST_WIDE_INTlong *
1139wide_int_storage::get_val () const
1140{
1141 return val;
1142}
1143
1144inline unsigned int
1145wide_int_storage::get_len () const
1146{
1147 return len;
1148}
1149
1150inline HOST_WIDE_INTlong *
1151wide_int_storage::write_val ()
1152{
1153 return val;
1154}
1155
1156inline void
1157wide_int_storage::set_len (unsigned int l, bool is_sign_extended)
1158{
1159 len = l;
1160 if (!is_sign_extended
33.1
'is_sign_extended' is false
33.1
'is_sign_extended' is false
33.1
'is_sign_extended' is false
&& len * HOST_BITS_PER_WIDE_INT64 > precision)
34
The right operand of '>' is a garbage value
1161 val[len - 1] = sext_hwi (val[len - 1],
1162 precision % HOST_BITS_PER_WIDE_INT64);
1163}
1164
1165/* Treat X as having signedness SGN and convert it to a PRECISION-bit
1166 number. */
1167inline wide_int
1168wide_int_storage::from (const wide_int_ref &x, unsigned int precision,
1169 signop sgn)
1170{
1171 wide_int result = wide_int::create (precision);
1172 result.set_len (wi::force_to_size (result.write_val (), x.val, x.len,
1173 x.precision, precision, sgn));
1174 return result;
1175}
1176
1177/* Create a wide_int from the explicit block encoding given by VAL and
1178 LEN. PRECISION is the precision of the integer. NEED_CANON_P is
1179 true if the encoding may have redundant trailing blocks. */
1180inline wide_int
1181wide_int_storage::from_array (const HOST_WIDE_INTlong *val, unsigned int len,
1182 unsigned int precision, bool need_canon_p)
1183{
1184 wide_int result = wide_int::create (precision);
1185 result.set_len (wi::from_array (result.write_val (), val, len, precision,
1186 need_canon_p));
1187 return result;
1188}
1189
1190/* Return an uninitialized wide_int with precision PRECISION. */
1191inline wide_int
1192wide_int_storage::create (unsigned int precision)
1193{
1194 wide_int x;
1195 x.precision = precision;
1196 return x;
1197}
1198
1199template <typename T1, typename T2>
1200inline wide_int
1201wi::int_traits <wide_int_storage>::get_binary_result (const T1 &x, const T2 &y)
1202{
1203 /* This shouldn't be used for two flexible-precision inputs. */
1204 STATIC_ASSERT (wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISIONstatic_assert ((wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION
|| wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION
), "wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION"
)
1205 || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION)static_assert ((wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION
|| wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION
), "wi::int_traits <T1>::precision_type != FLEXIBLE_PRECISION || wi::int_traits <T2>::precision_type != FLEXIBLE_PRECISION"
)
;
1206 if (wi::int_traits <T1>::precision_type == FLEXIBLE_PRECISION)
1207 return wide_int::create (wi::get_precision (y));
1208 else
1209 return wide_int::create (wi::get_precision (x));
1210}
1211
1212/* The storage used by FIXED_WIDE_INT (N). */
1213template <int N>
1214class GTY(()) fixed_wide_int_storage
1215{
1216private:
1217 HOST_WIDE_INTlong val[(N + HOST_BITS_PER_WIDE_INT64 + 1) / HOST_BITS_PER_WIDE_INT64];
1218 unsigned int len;
1219
1220public:
1221 fixed_wide_int_storage ();
1222 template <typename T>
1223 fixed_wide_int_storage (const T &);
1224
1225 /* The standard generic_wide_int storage methods. */
1226 unsigned int get_precision () const;
1227 const HOST_WIDE_INTlong *get_val () const;
1228 unsigned int get_len () const;
1229 HOST_WIDE_INTlong *write_val ();
1230 void set_len (unsigned int, bool = false);
1231
1232 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > from (const wide_int_ref &, signop);
1233 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > from_array (const HOST_WIDE_INTlong *, unsigned int,
1234 bool = true);
1235};
1236
1237namespace wi
1238{
1239 template <int N>
1240 struct int_traits < fixed_wide_int_storage <N> >
1241 {
1242 static const enum precision_type precision_type = CONST_PRECISION;
1243 static const bool host_dependent_precision = false;
1244 static const bool is_sign_extended = true;
1245 static const unsigned int precision = N;
1246 template <typename T1, typename T2>
1247 static FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > get_binary_result (const T1 &, const T2 &);
1248 };
1249}
1250
1251template <int N>
1252inline fixed_wide_int_storage <N>::fixed_wide_int_storage () {}
1253
1254/* Initialize the storage from integer X, in precision N. */
1255template <int N>
1256template <typename T>
1257inline fixed_wide_int_storage <N>::fixed_wide_int_storage (const T &x)
1258{
1259 /* Check for type compatibility. We don't want to initialize a
1260 fixed-width integer from something like a wide_int. */
1261 WI_BINARY_RESULT (T, FIXED_WIDE_INT (N))typename wi::binary_traits <T, generic_wide_int < fixed_wide_int_storage
<N> > >::result_type
*assertion ATTRIBUTE_UNUSED__attribute__ ((__unused__));
1262 wi::copy (*this, WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
(x, N));
1263}
1264
1265template <int N>
1266inline unsigned int
1267fixed_wide_int_storage <N>::get_precision () const
1268{
1269 return N;
1270}
1271
1272template <int N>
1273inline const HOST_WIDE_INTlong *
1274fixed_wide_int_storage <N>::get_val () const
1275{
1276 return val;
1277}
1278
1279template <int N>
1280inline unsigned int
1281fixed_wide_int_storage <N>::get_len () const
1282{
1283 return len;
1284}
1285
1286template <int N>
1287inline HOST_WIDE_INTlong *
1288fixed_wide_int_storage <N>::write_val ()
1289{
1290 return val;
1291}
1292
1293template <int N>
1294inline void
1295fixed_wide_int_storage <N>::set_len (unsigned int l, bool)
1296{
1297 len = l;
1298 /* There are no excess bits in val[len - 1]. */
1299 STATIC_ASSERT (N % HOST_BITS_PER_WIDE_INT == 0)static_assert ((N % 64 == 0), "N % HOST_BITS_PER_WIDE_INT == 0"
)
;
1300}
1301
1302/* Treat X as having signedness SGN and convert it to an N-bit number. */
1303template <int N>
1304inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1305fixed_wide_int_storage <N>::from (const wide_int_ref &x, signop sgn)
1306{
1307 FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > result;
1308 result.set_len (wi::force_to_size (result.write_val (), x.val, x.len,
1309 x.precision, N, sgn));
1310 return result;
1311}
1312
1313/* Create a FIXED_WIDE_INT (N) from the explicit block encoding given by
1314 VAL and LEN. NEED_CANON_P is true if the encoding may have redundant
1315 trailing blocks. */
1316template <int N>
1317inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1318fixed_wide_int_storage <N>::from_array (const HOST_WIDE_INTlong *val,
1319 unsigned int len,
1320 bool need_canon_p)
1321{
1322 FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > result;
1323 result.set_len (wi::from_array (result.write_val (), val, len,
1324 N, need_canon_p));
1325 return result;
1326}
1327
1328template <int N>
1329template <typename T1, typename T2>
1330inline FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> >
1331wi::int_traits < fixed_wide_int_storage <N> >::
1332get_binary_result (const T1 &, const T2 &)
1333{
1334 return FIXED_WIDE_INT (N)generic_wide_int < fixed_wide_int_storage <N> > ();
1335}
1336
1337/* A reference to one element of a trailing_wide_ints structure. */
1338class trailing_wide_int_storage
1339{
1340private:
1341 /* The precision of the integer, which is a fixed property of the
1342 parent trailing_wide_ints. */
1343 unsigned int m_precision;
1344
1345 /* A pointer to the length field. */
1346 unsigned char *m_len;
1347
1348 /* A pointer to the HWI array. There are enough elements to hold all
1349 values of precision M_PRECISION. */
1350 HOST_WIDE_INTlong *m_val;
1351
1352public:
1353 trailing_wide_int_storage (unsigned int, unsigned char *, HOST_WIDE_INTlong *);
1354
1355 /* The standard generic_wide_int storage methods. */
1356 unsigned int get_len () const;
1357 unsigned int get_precision () const;
1358 const HOST_WIDE_INTlong *get_val () const;
1359 HOST_WIDE_INTlong *write_val ();
1360 void set_len (unsigned int, bool = false);
1361
1362 template <typename T>
1363 trailing_wide_int_storage &operator = (const T &);
1364};
1365
1366typedef generic_wide_int <trailing_wide_int_storage> trailing_wide_int;
1367
1368/* trailing_wide_int behaves like a wide_int. */
1369namespace wi
1370{
1371 template <>
1372 struct int_traits <trailing_wide_int_storage>
1373 : public int_traits <wide_int_storage> {};
1374}
1375
1376/* An array of N wide_int-like objects that can be put at the end of
1377 a variable-sized structure. Use extra_size to calculate how many
1378 bytes beyond the sizeof need to be allocated. Use set_precision
1379 to initialize the structure. */
1380template <int N>
1381struct GTY((user)) trailing_wide_ints
1382{
1383private:
1384 /* The shared precision of each number. */
1385 unsigned short m_precision;
1386
1387 /* The shared maximum length of each number. */
1388 unsigned char m_max_len;
1389
1390 /* The current length of each number.
1391 Avoid char array so the whole structure is not a typeless storage
1392 that will, in turn, turn off TBAA on gimple, trees and RTL. */
1393 struct {unsigned char len;} m_len[N];
1394
1395 /* The variable-length part of the structure, which always contains
1396 at least one HWI. Element I starts at index I * M_MAX_LEN. */
1397 HOST_WIDE_INTlong m_val[1];
1398
1399public:
1400 typedef WIDE_INT_REF_FOR (trailing_wide_int_storage)generic_wide_int <wide_int_ref_storage <wi::int_traits <
trailing_wide_int_storage>::is_sign_extended, wi::int_traits
<trailing_wide_int_storage>::host_dependent_precision>
>
const_reference;
1401
1402 void set_precision (unsigned int);
1403 unsigned int get_precision () const { return m_precision; }
1404 trailing_wide_int operator [] (unsigned int);
1405 const_reference operator [] (unsigned int) const;
1406 static size_t extra_size (unsigned int);
1407 size_t extra_size () const { return extra_size (m_precision); }
1408};
1409
1410inline trailing_wide_int_storage::
1411trailing_wide_int_storage (unsigned int precision, unsigned char *len,
1412 HOST_WIDE_INTlong *val)
1413 : m_precision (precision), m_len (len), m_val (val)
1414{
1415}
1416
1417inline unsigned int
1418trailing_wide_int_storage::get_len () const
1419{
1420 return *m_len;
1421}
1422
1423inline unsigned int
1424trailing_wide_int_storage::get_precision () const
1425{
1426 return m_precision;
1427}
1428
1429inline const HOST_WIDE_INTlong *
1430trailing_wide_int_storage::get_val () const
1431{
1432 return m_val;
1433}
1434
1435inline HOST_WIDE_INTlong *
1436trailing_wide_int_storage::write_val ()
1437{
1438 return m_val;
1439}
1440
1441inline void
1442trailing_wide_int_storage::set_len (unsigned int len, bool is_sign_extended)
1443{
1444 *m_len = len;
1445 if (!is_sign_extended && len * HOST_BITS_PER_WIDE_INT64 > m_precision)
1446 m_val[len - 1] = sext_hwi (m_val[len - 1],
1447 m_precision % HOST_BITS_PER_WIDE_INT64);
1448}
1449
1450template <typename T>
1451inline trailing_wide_int_storage &
1452trailing_wide_int_storage::operator = (const T &x)
1453{
1454 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, m_precision);
1455 wi::copy (*this, xi);
1456 return *this;
1457}
1458
1459/* Initialize the structure and record that all elements have precision
1460 PRECISION. */
1461template <int N>
1462inline void
1463trailing_wide_ints <N>::set_precision (unsigned int precision)
1464{
1465 m_precision = precision;
1466 m_max_len = ((precision + HOST_BITS_PER_WIDE_INT64 - 1)
1467 / HOST_BITS_PER_WIDE_INT64);
1468}
1469
1470/* Return a reference to element INDEX. */
1471template <int N>
1472inline trailing_wide_int
1473trailing_wide_ints <N>::operator [] (unsigned int index)
1474{
1475 return trailing_wide_int_storage (m_precision, &m_len[index].len,
1476 &m_val[index * m_max_len]);
1477}
1478
1479template <int N>
1480inline typename trailing_wide_ints <N>::const_reference
1481trailing_wide_ints <N>::operator [] (unsigned int index) const
1482{
1483 return wi::storage_ref (&m_val[index * m_max_len],
1484 m_len[index].len, m_precision);
1485}
1486
1487/* Return how many extra bytes need to be added to the end of the structure
1488 in order to handle N wide_ints of precision PRECISION. */
1489template <int N>
1490inline size_t
1491trailing_wide_ints <N>::extra_size (unsigned int precision)
1492{
1493 unsigned int max_len = ((precision + HOST_BITS_PER_WIDE_INT64 - 1)
1494 / HOST_BITS_PER_WIDE_INT64);
1495 return (N * max_len - 1) * sizeof (HOST_WIDE_INTlong);
1496}
1497
1498/* This macro is used in structures that end with a trailing_wide_ints field
1499 called FIELD. It declares get_NAME() and set_NAME() methods to access
1500 element I of FIELD. */
1501#define TRAILING_WIDE_INT_ACCESSOR(NAME, FIELD, I)trailing_wide_int get_NAME () { return FIELD[I]; } template <
typename T> void set_NAME (const T &x) { FIELD[I] = x;
}
\
1502 trailing_wide_int get_##NAME () { return FIELD[I]; } \
1503 template <typename T> void set_##NAME (const T &x) { FIELD[I] = x; }
1504
1505namespace wi
1506{
1507 /* Implementation of int_traits for primitive integer types like "int". */
1508 template <typename T, bool signed_p>
1509 struct primitive_int_traits
1510 {
1511 static const enum precision_type precision_type = FLEXIBLE_PRECISION;
1512 static const bool host_dependent_precision = true;
1513 static const bool is_sign_extended = true;
1514 static unsigned int get_precision (T);
1515 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int, T);
1516 };
1517}
1518
1519template <typename T, bool signed_p>
1520inline unsigned int
1521wi::primitive_int_traits <T, signed_p>::get_precision (T)
1522{
1523 return sizeof (T) * CHAR_BIT8;
1524}
1525
1526template <typename T, bool signed_p>
1527inline wi::storage_ref
1528wi::primitive_int_traits <T, signed_p>::decompose (HOST_WIDE_INTlong *scratch,
1529 unsigned int precision, T x)
1530{
1531 scratch[0] = x;
1532 if (signed_p || scratch[0] >= 0 || precision <= HOST_BITS_PER_WIDE_INT64)
1533 return wi::storage_ref (scratch, 1, precision);
1534 scratch[1] = 0;
1535 return wi::storage_ref (scratch, 2, precision);
1536}
1537
1538/* Allow primitive C types to be used in wi:: routines. */
1539namespace wi
1540{
1541 template <>
1542 struct int_traits <unsigned char>
1543 : public primitive_int_traits <unsigned char, false> {};
1544
1545 template <>
1546 struct int_traits <unsigned short>
1547 : public primitive_int_traits <unsigned short, false> {};
1548
1549 template <>
1550 struct int_traits <int>
1551 : public primitive_int_traits <int, true> {};
1552
1553 template <>
1554 struct int_traits <unsigned int>
1555 : public primitive_int_traits <unsigned int, false> {};
1556
1557 template <>
1558 struct int_traits <long>
1559 : public primitive_int_traits <long, true> {};
1560
1561 template <>
1562 struct int_traits <unsigned long>
1563 : public primitive_int_traits <unsigned long, false> {};
1564
1565#if defined HAVE_LONG_LONG1
1566 template <>
1567 struct int_traits <long long>
1568 : public primitive_int_traits <long long, true> {};
1569
1570 template <>
1571 struct int_traits <unsigned long long>
1572 : public primitive_int_traits <unsigned long long, false> {};
1573#endif
1574}
1575
1576namespace wi
1577{
1578 /* Stores HWI-sized integer VAL, treating it as having signedness SGN
1579 and precision PRECISION. */
1580 class hwi_with_prec
1581 {
1582 public:
1583 hwi_with_prec () {}
1584 hwi_with_prec (HOST_WIDE_INTlong, unsigned int, signop);
1585 HOST_WIDE_INTlong val;
1586 unsigned int precision;
1587 signop sgn;
1588 };
1589
1590 hwi_with_prec shwi (HOST_WIDE_INTlong, unsigned int);
1591 hwi_with_prec uhwi (unsigned HOST_WIDE_INTlong, unsigned int);
1592
1593 hwi_with_prec minus_one (unsigned int);
1594 hwi_with_prec zero (unsigned int);
1595 hwi_with_prec one (unsigned int);
1596 hwi_with_prec two (unsigned int);
1597}
1598
1599inline wi::hwi_with_prec::hwi_with_prec (HOST_WIDE_INTlong v, unsigned int p,
1600 signop s)
1601 : precision (p), sgn (s)
1602{
1603 if (precision < HOST_BITS_PER_WIDE_INT64)
1604 val = sext_hwi (v, precision);
1605 else
1606 val = v;
1607}
1608
1609/* Return a signed integer that has value VAL and precision PRECISION. */
1610inline wi::hwi_with_prec
1611wi::shwi (HOST_WIDE_INTlong val, unsigned int precision)
1612{
1613 return hwi_with_prec (val, precision, SIGNED);
1614}
1615
1616/* Return an unsigned integer that has value VAL and precision PRECISION. */
1617inline wi::hwi_with_prec
1618wi::uhwi (unsigned HOST_WIDE_INTlong val, unsigned int precision)
1619{
1620 return hwi_with_prec (val, precision, UNSIGNED);
1621}
1622
1623/* Return a wide int of -1 with precision PRECISION. */
1624inline wi::hwi_with_prec
1625wi::minus_one (unsigned int precision)
1626{
1627 return wi::shwi (-1, precision);
1628}
1629
1630/* Return a wide int of 0 with precision PRECISION. */
1631inline wi::hwi_with_prec
1632wi::zero (unsigned int precision)
1633{
1634 return wi::shwi (0, precision);
1635}
1636
1637/* Return a wide int of 1 with precision PRECISION. */
1638inline wi::hwi_with_prec
1639wi::one (unsigned int precision)
1640{
1641 return wi::shwi (1, precision);
1642}
1643
1644/* Return a wide int of 2 with precision PRECISION. */
1645inline wi::hwi_with_prec
1646wi::two (unsigned int precision)
1647{
1648 return wi::shwi (2, precision);
1649}
1650
1651namespace wi
1652{
1653 /* ints_for<T>::zero (X) returns a zero that, when asssigned to a T,
1654 gives that T the same precision as X. */
1655 template<typename T, precision_type = int_traits<T>::precision_type>
1656 struct ints_for
1657 {
1658 static int zero (const T &) { return 0; }
1659 };
1660
1661 template<typename T>
1662 struct ints_for<T, VAR_PRECISION>
1663 {
1664 static hwi_with_prec zero (const T &);
1665 };
1666}
1667
1668template<typename T>
1669inline wi::hwi_with_prec
1670wi::ints_for<T, wi::VAR_PRECISION>::zero (const T &x)
1671{
1672 return wi::zero (wi::get_precision (x));
1673}
1674
1675namespace wi
1676{
1677 template <>
1678 struct int_traits <wi::hwi_with_prec>
1679 {
1680 static const enum precision_type precision_type = VAR_PRECISION;
1681 /* hwi_with_prec has an explicitly-given precision, rather than the
1682 precision of HOST_WIDE_INT. */
1683 static const bool host_dependent_precision = false;
1684 static const bool is_sign_extended = true;
1685 static unsigned int get_precision (const wi::hwi_with_prec &);
1686 static wi::storage_ref decompose (HOST_WIDE_INTlong *, unsigned int,
1687 const wi::hwi_with_prec &);
1688 };
1689}
1690
1691inline unsigned int
1692wi::int_traits <wi::hwi_with_prec>::get_precision (const wi::hwi_with_prec &x)
1693{
1694 return x.precision;
1695}
1696
1697inline wi::storage_ref
1698wi::int_traits <wi::hwi_with_prec>::
1699decompose (HOST_WIDE_INTlong *scratch, unsigned int precision,
1700 const wi::hwi_with_prec &x)
1701{
1702 gcc_checking_assert (precision == x.precision)((void)(!(precision == x.precision) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/wide-int.h"
, 1702, __FUNCTION__), 0 : 0))
;
1703 scratch[0] = x.val;
1704 if (x.sgn == SIGNED || x.val >= 0 || precision <= HOST_BITS_PER_WIDE_INT64)
1705 return wi::storage_ref (scratch, 1, precision);
1706 scratch[1] = 0;
1707 return wi::storage_ref (scratch, 2, precision);
1708}
1709
1710/* Private functions for handling large cases out of line. They take
1711 individual length and array parameters because that is cheaper for
1712 the inline caller than constructing an object on the stack and
1713 passing a reference to it. (Although many callers use wide_int_refs,
1714 we generally want those to be removed by SRA.) */
1715namespace wi
1716{
1717 bool eq_p_large (const HOST_WIDE_INTlong *, unsigned int,
1718 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1719 bool lts_p_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1720 const HOST_WIDE_INTlong *, unsigned int);
1721 bool ltu_p_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1722 const HOST_WIDE_INTlong *, unsigned int);
1723 int cmps_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1724 const HOST_WIDE_INTlong *, unsigned int);
1725 int cmpu_large (const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1726 const HOST_WIDE_INTlong *, unsigned int);
1727 unsigned int sext_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1728 unsigned int,
1729 unsigned int, unsigned int);
1730 unsigned int zext_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1731 unsigned int,
1732 unsigned int, unsigned int);
1733 unsigned int set_bit_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1734 unsigned int, unsigned int, unsigned int);
1735 unsigned int lshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1736 unsigned int, unsigned int, unsigned int);
1737 unsigned int lrshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1738 unsigned int, unsigned int, unsigned int,
1739 unsigned int);
1740 unsigned int arshift_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1741 unsigned int, unsigned int, unsigned int,
1742 unsigned int);
1743 unsigned int and_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1744 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1745 unsigned int and_not_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1746 unsigned int, const HOST_WIDE_INTlong *,
1747 unsigned int, unsigned int);
1748 unsigned int or_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1749 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1750 unsigned int or_not_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1751 unsigned int, const HOST_WIDE_INTlong *,
1752 unsigned int, unsigned int);
1753 unsigned int xor_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1754 const HOST_WIDE_INTlong *, unsigned int, unsigned int);
1755 unsigned int add_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1756 const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1757 signop, overflow_type *);
1758 unsigned int sub_large (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *, unsigned int,
1759 const HOST_WIDE_INTlong *, unsigned int, unsigned int,
1760 signop, overflow_type *);
1761 unsigned int mul_internal (HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1762 unsigned int, const HOST_WIDE_INTlong *,
1763 unsigned int, unsigned int, signop,
1764 overflow_type *, bool);
1765 unsigned int divmod_internal (HOST_WIDE_INTlong *, unsigned int *,
1766 HOST_WIDE_INTlong *, const HOST_WIDE_INTlong *,
1767 unsigned int, unsigned int,
1768 const HOST_WIDE_INTlong *,
1769 unsigned int, unsigned int,
1770 signop, overflow_type *);
1771}
1772
1773/* Return the number of bits that integer X can hold. */
1774template <typename T>
1775inline unsigned int
1776wi::get_precision (const T &x)
1777{
1778 return wi::int_traits <T>::get_precision (x);
1779}
1780
1781/* Return the number of bits that the result of a binary operation can
1782 hold when the input operands are X and Y. */
1783template <typename T1, typename T2>
1784inline unsigned int
1785wi::get_binary_precision (const T1 &x, const T2 &y)
1786{
1787 return get_precision (wi::int_traits <WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type>::
1788 get_binary_result (x, y));
1789}
1790
1791/* Copy the contents of Y to X, but keeping X's current precision. */
1792template <typename T1, typename T2>
1793inline void
1794wi::copy (T1 &x, const T2 &y)
1795{
1796 HOST_WIDE_INTlong *xval = x.write_val ();
1797 const HOST_WIDE_INTlong *yval = y.get_val ();
1798 unsigned int len = y.get_len ();
1799 unsigned int i = 0;
1800 do
24
Loop condition is true. Execution continues on line 1801
26
Loop condition is true. Execution continues on line 1801
29
Loop condition is true. Execution continues on line 1801
32
Loop condition is false. Exiting loop
1801 xval[i] = yval[i];
30
Uninitialized value stored to 'val_im1.precision'
1802 while (++i < len);
23
Assuming the condition is true
25
Assuming the condition is true
27
The value 3 is assigned to 'i'
28
Assuming the condition is true
31
Assuming the condition is false
1803 x.set_len (len, y.is_sign_extended);
33
Calling 'wide_int_storage::set_len'
1804}
1805
1806/* Return true if X fits in a HOST_WIDE_INT with no loss of precision. */
1807template <typename T>
1808inline bool
1809wi::fits_shwi_p (const T &x)
1810{
1811 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1812 return xi.len == 1;
1813}
1814
1815/* Return true if X fits in an unsigned HOST_WIDE_INT with no loss of
1816 precision. */
1817template <typename T>
1818inline bool
1819wi::fits_uhwi_p (const T &x)
1820{
1821 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1822 if (xi.precision <= HOST_BITS_PER_WIDE_INT64)
1823 return true;
1824 if (xi.len == 1)
1825 return xi.slow () >= 0;
1826 return xi.len == 2 && xi.uhigh () == 0;
1827}
1828
1829/* Return true if X is negative based on the interpretation of SGN.
1830 For UNSIGNED, this is always false. */
1831template <typename T>
1832inline bool
1833wi::neg_p (const T &x, signop sgn)
1834{
1835 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1836 if (sgn == UNSIGNED)
1837 return false;
1838 return xi.sign_mask () < 0;
1839}
1840
1841/* Return -1 if the top bit of X is set and 0 if the top bit is clear. */
1842template <typename T>
1843inline HOST_WIDE_INTlong
1844wi::sign_mask (const T &x)
1845{
1846 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x);
1847 return xi.sign_mask ();
1848}
1849
1850/* Return true if X == Y. X and Y must be binary-compatible. */
1851template <typename T1, typename T2>
1852inline bool
1853wi::eq_p (const T1 &x, const T2 &y)
1854{
1855 unsigned int precision = get_binary_precision (x, y);
1856 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1857 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1858 if (xi.is_sign_extended && yi.is_sign_extended)
1859 {
1860 /* This case reduces to array equality. */
1861 if (xi.len != yi.len)
1862 return false;
1863 unsigned int i = 0;
1864 do
1865 if (xi.val[i] != yi.val[i])
1866 return false;
1867 while (++i != xi.len);
1868 return true;
1869 }
1870 if (__builtin_expect (yi.len == 1, true))
1871 {
1872 /* XI is only equal to YI if it too has a single HWI. */
1873 if (xi.len != 1)
1874 return false;
1875 /* Excess bits in xi.val[0] will be signs or zeros, so comparisons
1876 with 0 are simple. */
1877 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
1878 return xi.val[0] == 0;
1879 /* Otherwise flush out any excess bits first. */
1880 unsigned HOST_WIDE_INTlong diff = xi.val[0] ^ yi.val[0];
1881 int excess = HOST_BITS_PER_WIDE_INT64 - precision;
1882 if (excess > 0)
1883 diff <<= excess;
1884 return diff == 0;
1885 }
1886 return eq_p_large (xi.val, xi.len, yi.val, yi.len, precision);
1887}
1888
1889/* Return true if X != Y. X and Y must be binary-compatible. */
1890template <typename T1, typename T2>
1891inline bool
1892wi::ne_p (const T1 &x, const T2 &y)
1893{
1894 return !eq_p (x, y);
1895}
1896
1897/* Return true if X < Y when both are treated as signed values. */
1898template <typename T1, typename T2>
1899inline bool
1900wi::lts_p (const T1 &x, const T2 &y)
1901{
1902 unsigned int precision = get_binary_precision (x, y);
1903 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1904 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1905 /* We optimize x < y, where y is 64 or fewer bits. */
1906 if (wi::fits_shwi_p (yi))
1907 {
1908 /* Make lts_p (x, 0) as efficient as wi::neg_p (x). */
1909 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
1910 return neg_p (xi);
1911 /* If x fits directly into a shwi, we can compare directly. */
1912 if (wi::fits_shwi_p (xi))
1913 return xi.to_shwi () < yi.to_shwi ();
1914 /* If x doesn't fit and is negative, then it must be more
1915 negative than any value in y, and hence smaller than y. */
1916 if (neg_p (xi))
1917 return true;
1918 /* If x is positive, then it must be larger than any value in y,
1919 and hence greater than y. */
1920 return false;
1921 }
1922 /* Optimize the opposite case, if it can be detected at compile time. */
1923 if (STATIC_CONSTANT_P (xi.len == 1)(__builtin_constant_p (xi.len == 1) && (xi.len == 1)))
1924 /* If YI is negative it is lower than the least HWI.
1925 If YI is positive it is greater than the greatest HWI. */
1926 return !neg_p (yi);
1927 return lts_p_large (xi.val, xi.len, precision, yi.val, yi.len);
1928}
1929
1930/* Return true if X < Y when both are treated as unsigned values. */
1931template <typename T1, typename T2>
1932inline bool
1933wi::ltu_p (const T1 &x, const T2 &y)
1934{
1935 unsigned int precision = get_binary_precision (x, y);
1936 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
1937 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
1938 /* Optimize comparisons with constants. */
1939 if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)(__builtin_constant_p (yi.len == 1 && yi.val[0] >=
0) && (yi.len == 1 && yi.val[0] >= 0))
)
1940 return xi.len == 1 && xi.to_uhwi () < (unsigned HOST_WIDE_INTlong) yi.val[0];
1941 if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)(__builtin_constant_p (xi.len == 1 && xi.val[0] >=
0) && (xi.len == 1 && xi.val[0] >= 0))
)
1942 return yi.len != 1 || yi.to_uhwi () > (unsigned HOST_WIDE_INTlong) xi.val[0];
1943 /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended
1944 for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
1945 values does not change the result. */
1946 if (__builtin_expect (xi.len + yi.len == 2, true))
1947 {
1948 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
1949 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
1950 return xl < yl;
1951 }
1952 return ltu_p_large (xi.val, xi.len, precision, yi.val, yi.len);
1953}
1954
1955/* Return true if X < Y. Signedness of X and Y is indicated by SGN. */
1956template <typename T1, typename T2>
1957inline bool
1958wi::lt_p (const T1 &x, const T2 &y, signop sgn)
1959{
1960 if (sgn == SIGNED)
1961 return lts_p (x, y);
1962 else
1963 return ltu_p (x, y);
1964}
1965
1966/* Return true if X <= Y when both are treated as signed values. */
1967template <typename T1, typename T2>
1968inline bool
1969wi::les_p (const T1 &x, const T2 &y)
1970{
1971 return !lts_p (y, x);
1972}
1973
1974/* Return true if X <= Y when both are treated as unsigned values. */
1975template <typename T1, typename T2>
1976inline bool
1977wi::leu_p (const T1 &x, const T2 &y)
1978{
1979 return !ltu_p (y, x);
1980}
1981
1982/* Return true if X <= Y. Signedness of X and Y is indicated by SGN. */
1983template <typename T1, typename T2>
1984inline bool
1985wi::le_p (const T1 &x, const T2 &y, signop sgn)
1986{
1987 if (sgn == SIGNED)
1988 return les_p (x, y);
1989 else
1990 return leu_p (x, y);
1991}
1992
1993/* Return true if X > Y when both are treated as signed values. */
1994template <typename T1, typename T2>
1995inline bool
1996wi::gts_p (const T1 &x, const T2 &y)
1997{
1998 return lts_p (y, x);
1999}
2000
2001/* Return true if X > Y when both are treated as unsigned values. */
2002template <typename T1, typename T2>
2003inline bool
2004wi::gtu_p (const T1 &x, const T2 &y)
2005{
2006 return ltu_p (y, x);
2007}
2008
2009/* Return true if X > Y. Signedness of X and Y is indicated by SGN. */
2010template <typename T1, typename T2>
2011inline bool
2012wi::gt_p (const T1 &x, const T2 &y, signop sgn)
2013{
2014 if (sgn == SIGNED)
2015 return gts_p (x, y);
2016 else
2017 return gtu_p (x, y);
2018}
2019
2020/* Return true if X >= Y when both are treated as signed values. */
2021template <typename T1, typename T2>
2022inline bool
2023wi::ges_p (const T1 &x, const T2 &y)
2024{
2025 return !lts_p (x, y);
2026}
2027
2028/* Return true if X >= Y when both are treated as unsigned values. */
2029template <typename T1, typename T2>
2030inline bool
2031wi::geu_p (const T1 &x, const T2 &y)
2032{
2033 return !ltu_p (x, y);
2034}
2035
2036/* Return true if X >= Y. Signedness of X and Y is indicated by SGN. */
2037template <typename T1, typename T2>
2038inline bool
2039wi::ge_p (const T1 &x, const T2 &y, signop sgn)
2040{
2041 if (sgn == SIGNED)
2042 return ges_p (x, y);
2043 else
2044 return geu_p (x, y);
2045}
2046
2047/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y
2048 as signed values. */
2049template <typename T1, typename T2>
2050inline int
2051wi::cmps (const T1 &x, const T2 &y)
2052{
2053 unsigned int precision = get_binary_precision (x, y);
2054 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2055 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2056 if (wi::fits_shwi_p (yi))
2057 {
2058 /* Special case for comparisons with 0. */
2059 if (STATIC_CONSTANT_P (yi.val[0] == 0)(__builtin_constant_p (yi.val[0] == 0) && (yi.val[0] ==
0))
)
2060 return neg_p (xi) ? -1 : !(xi.len == 1 && xi.val[0] == 0);
2061 /* If x fits into a signed HWI, we can compare directly. */
2062 if (wi::fits_shwi_p (xi))
2063 {
2064 HOST_WIDE_INTlong xl = xi.to_shwi ();
2065 HOST_WIDE_INTlong yl = yi.to_shwi ();
2066 return xl < yl ? -1 : xl > yl;
2067 }
2068 /* If x doesn't fit and is negative, then it must be more
2069 negative than any signed HWI, and hence smaller than y. */
2070 if (neg_p (xi))
2071 return -1;
2072 /* If x is positive, then it must be larger than any signed HWI,
2073 and hence greater than y. */
2074 return 1;
2075 }
2076 /* Optimize the opposite case, if it can be detected at compile time. */
2077 if (STATIC_CONSTANT_P (xi.len == 1)(__builtin_constant_p (xi.len == 1) && (xi.len == 1)))
2078 /* If YI is negative it is lower than the least HWI.
2079 If YI is positive it is greater than the greatest HWI. */
2080 return neg_p (yi) ? 1 : -1;
2081 return cmps_large (xi.val, xi.len, precision, yi.val, yi.len);
2082}
2083
2084/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Treat both X and Y
2085 as unsigned values. */
2086template <typename T1, typename T2>
2087inline int
2088wi::cmpu (const T1 &x, const T2 &y)
2089{
2090 unsigned int precision = get_binary_precision (x, y);
2091 WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
xi (x, precision);
2092 WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
yi (y, precision);
2093 /* Optimize comparisons with constants. */
2094 if (STATIC_CONSTANT_P (yi.len == 1 && yi.val[0] >= 0)(__builtin_constant_p (yi.len == 1 && yi.val[0] >=
0) && (yi.len == 1 && yi.val[0] >= 0))
)
2095 {
2096 /* If XI doesn't fit in a HWI then it must be larger than YI. */
2097 if (xi.len != 1)
2098 return 1;
2099 /* Otherwise compare directly. */
2100 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
2101 unsigned HOST_WIDE_INTlong yl = yi.val[0];
2102 return xl < yl ? -1 : xl > yl;
2103 }
2104 if (STATIC_CONSTANT_P (xi.len == 1 && xi.val[0] >= 0)(__builtin_constant_p (xi.len == 1 && xi.val[0] >=
0) && (xi.len == 1 && xi.val[0] >= 0))
)
2105 {
2106 /* If YI doesn't fit in a HWI then it must be larger than XI. */
2107 if (yi.len != 1)
2108 return -1;
2109 /* Otherwise compare directly. */
2110 unsigned HOST_WIDE_INTlong xl = xi.val[0];
2111 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
2112 return xl < yl ? -1 : xl > yl;
2113 }
2114 /* Optimize the case of two HWIs. The HWIs are implicitly sign-extended
2115 for precisions greater than HOST_BITS_WIDE_INT, but sign-extending both
2116 values does not change the result. */
2117 if (__builtin_expect (xi.len + yi.len == 2, true))
2118 {
2119 unsigned HOST_WIDE_INTlong xl = xi.to_uhwi ();
2120 unsigned HOST_WIDE_INTlong yl = yi.to_uhwi ();
2121 return xl < yl ? -1 : xl > yl;
2122 }
2123 return cmpu_large (xi.val, xi.len, precision, yi.val, yi.len);
2124}
2125
2126/* Return -1 if X < Y, 0 if X == Y and 1 if X > Y. Signedness of
2127 X and Y indicated by SGN. */
2128template <typename T1, typename T2>
2129inline int
2130wi::cmp (const T1 &x, const T2 &y, signop sgn)
2131{
2132 if (sgn == SIGNED)
2133 return cmps (x, y);
2134 else
2135 return cmpu (x, y);
2136}
2137
2138/* Return ~x. */
2139template <typename T>
2140inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2141wi::bit_not (const T &x)
2142{
2143 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2144 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, get_precision (result));
2145 for (unsigned int i = 0; i < xi.len; ++i)
2146 val[i] = ~xi.val[i];
2147 result.set_len (xi.len);
2148 return result;
2149}
2150
2151/* Return -x. */
2152template <typename T>
2153inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2154wi::neg (const T &x)
2155{
2156 return sub (0, x);
2157}
2158
2159/* Return -x. Indicate in *OVERFLOW if performing the negation would
2160 cause an overflow. */
2161template <typename T>
2162inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2163wi::neg (const T &x, overflow_type *overflow)
2164{
2165 *overflow = only_sign_bit_p (x) ? OVF_OVERFLOW : OVF_NONE;
2166 return sub (0, x);
2167}
2168
2169/* Return the absolute value of x. */
2170template <typename T>
2171inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2172wi::abs (const T &x)
2173{
2174 return neg_p (x) ? neg (x) : WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type (x);
2175}
2176
2177/* Return the result of sign-extending the low OFFSET bits of X. */
2178template <typename T>
2179inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2180wi::sext (const T &x, unsigned int offset)
2181{
2182 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2183 unsigned int precision = get_precision (result);
2184 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2185
2186 if (offset <= HOST_BITS_PER_WIDE_INT64)
2187 {
2188 val[0] = sext_hwi (xi.ulow (), offset);
2189 result.set_len (1, true);
2190 }
2191 else
2192 result.set_len (sext_large (val, xi.val, xi.len, precision, offset));
2193 return result;
2194}
2195
2196/* Return the result of zero-extending the low OFFSET bits of X. */
2197template <typename T>
2198inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2199wi::zext (const T &x, unsigned int offset)
2200{
2201 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2202 unsigned int precision = get_precision (result);
2203 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2204
2205 /* This is not just an optimization, it is actually required to
2206 maintain canonization. */
2207 if (offset >= precision)
2208 {
2209 wi::copy (result, xi);
2210 return result;
2211 }
2212
2213 /* In these cases we know that at least the top bit will be clear,
2214 so no sign extension is necessary. */
2215 if (offset < HOST_BITS_PER_WIDE_INT64)
2216 {
2217 val[0] = zext_hwi (xi.ulow (), offset);
2218 result.set_len (1, true);
2219 }
2220 else
2221 result.set_len (zext_large (val, xi.val, xi.len, precision, offset), true);
2222 return result;
2223}
2224
2225/* Return the result of extending the low OFFSET bits of X according to
2226 signedness SGN. */
2227template <typename T>
2228inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2229wi::ext (const T &x, unsigned int offset, signop sgn)
2230{
2231 return sgn == SIGNED ? sext (x, offset) : zext (x, offset);
2232}
2233
2234/* Return an integer that represents X | (1 << bit). */
2235template <typename T>
2236inline WI_UNARY_RESULT (T)typename wi::binary_traits <T, T>::result_type
2237wi::set_bit (const T &x, unsigned int bit)
2238{
2239 WI_UNARY_RESULT_VAR (result, val, T, x)typename wi::binary_traits <T, T>::result_type result =
wi::int_traits <typename wi::binary_traits <T, T>::
result_type>::get_binary_result (x, x); long *val = result
.write_val ()
;
2240 unsigned int precision = get_precision (result);
2241 WIDE_INT_REF_FOR (T)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T>::is_sign_extended, wi::int_traits <T>::host_dependent_precision
> >
xi (x, precision);
2242 if (precision <= HOST_BITS_PER_WIDE_INT64)
2243 {
2244 val[0] = xi.ulow () | (HOST_WIDE_INT_1U1UL << bit);
2245 result.set_len (1);
2246 }
2247 else
2248 result.set_len (set_bit_large (val, xi.val, xi.len, precision, bit));
2249 return result;
2250}
2251
2252/* Return the mininum of X and Y, treating them both as having
2253 signedness SGN. */
2254template <typename T1, typename T2>
2255inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2256wi::min (const T1 &x, const T2 &y, signop sgn)
2257{
2258 WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val __attribute__
((__unused__)) = result.write_val ()
;
2259 unsigned int precision = get_precision (result);
2260 if (wi::le_p (x, y, sgn))
2261 wi::copy (result, WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
(x, precision));
2262 else
2263 wi::copy (result, WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
(y, precision));
2264 return result;
2265}
2266
2267/* Return the minimum of X and Y, treating both as signed values. */
2268template <typename T1, typename T2>
2269inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2270wi::smin (const T1 &x, const T2 &y)
2271{
2272 return wi::min (x, y, SIGNED);
2273}
2274
2275/* Return the minimum of X and Y, treating both as unsigned values. */
2276template <typename T1, typename T2>
2277inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2278wi::umin (const T1 &x, const T2 &y)
2279{
2280 return wi::min (x, y, UNSIGNED);
2281}
2282
2283/* Return the maxinum of X and Y, treating them both as having
2284 signedness SGN. */
2285template <typename T1, typename T2>
2286inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2287wi::max (const T1 &x, const T2 &y, signop sgn)
2288{
2289 WI_BINARY_RESULT_VAR (result, val ATTRIBUTE_UNUSED, T1, x, T2, y)typename wi::binary_traits <T1, T2>::result_type result
= wi::int_traits <typename wi::binary_traits <T1, T2>
::result_type>::get_binary_result (x, y); long *val __attribute__
((__unused__)) = result.write_val ()
;
2290 unsigned int precision = get_precision (result);
2291 if (wi::ge_p (x, y, sgn))
2292 wi::copy (result, WIDE_INT_REF_FOR (T1)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T1>::is_sign_extended, wi::int_traits <T1>::host_dependent_precision
> >
(x, precision));
2293 else
2294 wi::copy (result, WIDE_INT_REF_FOR (T2)generic_wide_int <wide_int_ref_storage <wi::int_traits <
T2>::is_sign_extended, wi::int_traits <T2>::host_dependent_precision
> >
(y, precision));
2295 return result;
2296}
2297
2298/* Return the maximum of X and Y, treating both as signed values. */
2299template <typename T1, typename T2>
2300inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2301wi::smax (const T1 &x, const T2 &y)
2302{
2303 return wi::max (x, y, SIGNED);
2304}
2305
2306/* Return the maximum of X and Y, treating both as unsigned values. */
2307template <typename T1, typename T2>
2308inline WI_BINARY_RESULT (T1, T2)typename wi::binary_traits <T1, T2>::result_type
2309