Bug Summary

File:build/gcc/gimple-fold.cc
Warning:line 1802, column 13
Although the value stored to 'val' is used in the enclosing expression, the value is never actually read from 'val'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-suse-linux -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gimple-fold.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/15.0.7 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../include/c++/13/backward -internal-isystem /usr/lib64/clang/15.0.7/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/13/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2023-03-27-141847-20772-1/report-gHZDuL.plist -x c++ /buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc
1/* Statement simplification on GIMPLE.
2 Copyright (C) 2010-2023 Free Software Foundation, Inc.
3 Split out from tree-ssa-ccp.cc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by the
9Free Software Foundation; either version 3, or (at your option) any
10later version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT
13ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "backend.h"
25#include "target.h"
26#include "rtl.h"
27#include "tree.h"
28#include "gimple.h"
29#include "predict.h"
30#include "ssa.h"
31#include "cgraph.h"
32#include "gimple-pretty-print.h"
33#include "gimple-ssa-warn-access.h"
34#include "gimple-ssa-warn-restrict.h"
35#include "fold-const.h"
36#include "stmt.h"
37#include "expr.h"
38#include "stor-layout.h"
39#include "dumpfile.h"
40#include "gimple-iterator.h"
41#include "gimple-fold.h"
42#include "gimplify.h"
43#include "tree-into-ssa.h"
44#include "tree-dfa.h"
45#include "tree-object-size.h"
46#include "tree-ssa.h"
47#include "tree-ssa-propagate.h"
48#include "ipa-utils.h"
49#include "tree-ssa-address.h"
50#include "langhooks.h"
51#include "gimplify-me.h"
52#include "dbgcnt.h"
53#include "builtins.h"
54#include "tree-eh.h"
55#include "gimple-match.h"
56#include "gomp-constants.h"
57#include "optabs-query.h"
58#include "omp-general.h"
59#include "tree-cfg.h"
60#include "fold-const-call.h"
61#include "stringpool.h"
62#include "attribs.h"
63#include "asan.h"
64#include "diagnostic-core.h"
65#include "intl.h"
66#include "calls.h"
67#include "tree-vector-builder.h"
68#include "tree-ssa-strlen.h"
69#include "varasm.h"
70#include "internal-fn.h"
71#include "gimple-range.h"
72
73enum strlen_range_kind {
74 /* Compute the exact constant string length. */
75 SRK_STRLEN,
76 /* Compute the maximum constant string length. */
77 SRK_STRLENMAX,
78 /* Compute a range of string lengths bounded by object sizes. When
79 the length of a string cannot be determined, consider as the upper
80 bound the size of the enclosing object the string may be a member
81 or element of. Also determine the size of the largest character
82 array the string may refer to. */
83 SRK_LENRANGE,
84 /* Determine the integer value of the argument (not string length). */
85 SRK_INT_VALUE
86};
87
88static bool
89get_range_strlen (tree, bitmap, strlen_range_kind, c_strlen_data *, unsigned);
90
91/* Return true when DECL can be referenced from current unit.
92 FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
93 We can get declarations that are not possible to reference for various
94 reasons:
95
96 1) When analyzing C++ virtual tables.
97 C++ virtual tables do have known constructors even
98 when they are keyed to other compilation unit.
99 Those tables can contain pointers to methods and vars
100 in other units. Those methods have both STATIC and EXTERNAL
101 set.
102 2) In WHOPR mode devirtualization might lead to reference
103 to method that was partitioned elsehwere.
104 In this case we have static VAR_DECL or FUNCTION_DECL
105 that has no corresponding callgraph/varpool node
106 declaring the body.
107 3) COMDAT functions referred by external vtables that
108 we devirtualize only during final compilation stage.
109 At this time we already decided that we will not output
110 the function body and thus we can't reference the symbol
111 directly. */
112
113static bool
114can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
115{
116 varpool_node *vnode;
117 struct cgraph_node *node;
118 symtab_node *snode;
119
120 if (DECL_ABSTRACT_P (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 120, __FUNCTION__))->decl_common.abstract_flag)
)
121 return false;
122
123 /* We are concerned only about static/external vars and functions. */
124 if ((!TREE_STATIC (decl)((decl)->base.static_flag) && !DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 124, __FUNCTION__))->decl_common.decl_flag_1)
)
125 || !VAR_OR_FUNCTION_DECL_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL || ((enum
tree_code) (decl)->base.code) == FUNCTION_DECL)
)
126 return true;
127
128 /* Static objects can be referred only if they are defined and not optimized
129 out yet. */
130 if (!TREE_PUBLIC (decl)((decl)->base.public_flag))
131 {
132 if (DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 132, __FUNCTION__))->decl_common.decl_flag_1)
)
133 return false;
134 /* Before we start optimizing unreachable code we can be sure all
135 static objects are defined. */
136 if (symtab->function_flags_ready)
137 return true;
138 snode = symtab_node::get (decl);
139 if (!snode || !snode->definition)
140 return false;
141 node = dyn_cast <cgraph_node *> (snode);
142 return !node || !node->inlined_to;
143 }
144
145 /* We will later output the initializer, so we can refer to it.
146 So we are concerned only when DECL comes from initializer of
147 external var or var that has been optimized out. */
148 if (!from_decl
149 || !VAR_P (from_decl)(((enum tree_code) (from_decl)->base.code) == VAR_DECL)
150 || (!DECL_EXTERNAL (from_decl)((contains_struct_check ((from_decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 150, __FUNCTION__))->decl_common.decl_flag_1)
151 && (vnode = varpool_node::get (from_decl)) != NULL__null
152 && vnode->definition)
153 || (flag_ltransglobal_options.x_flag_ltrans
154 && (vnode = varpool_node::get (from_decl)) != NULL__null
155 && vnode->in_other_partition))
156 return true;
157 /* We are folding reference from external vtable. The vtable may reffer
158 to a symbol keyed to other compilation unit. The other compilation
159 unit may be in separate DSO and the symbol may be hidden. */
160 if (DECL_VISIBILITY_SPECIFIED (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 160, __FUNCTION__))->decl_with_vis.visibility_specified)
161 && DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 161, __FUNCTION__))->decl_common.decl_flag_1)
162 && DECL_VISIBILITY (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 162, __FUNCTION__))->decl_with_vis.visibility)
!= VISIBILITY_DEFAULT
163 && (!(snode = symtab_node::get (decl)) || !snode->in_other_partition))
164 return false;
165 /* When function is public, we always can introduce new reference.
166 Exception are the COMDAT functions where introducing a direct
167 reference imply need to include function body in the curren tunit. */
168 if (TREE_PUBLIC (decl)((decl)->base.public_flag) && !DECL_COMDAT (decl)((contains_struct_check ((decl), (TS_DECL_WITH_VIS), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 168, __FUNCTION__))->decl_with_vis.comdat_flag)
)
169 return true;
170 /* We have COMDAT. We are going to check if we still have definition
171 or if the definition is going to be output in other partition.
172 Bypass this when gimplifying; all needed functions will be produced.
173
174 As observed in PR20991 for already optimized out comdat virtual functions
175 it may be tempting to not necessarily give up because the copy will be
176 output elsewhere when corresponding vtable is output.
177 This is however not possible - ABI specify that COMDATs are output in
178 units where they are used and when the other unit was compiled with LTO
179 it is possible that vtable was kept public while the function itself
180 was privatized. */
181 if (!symtab->function_flags_ready)
182 return true;
183
184 snode = symtab_node::get (decl);
185 if (!snode
186 || ((!snode->definition || DECL_EXTERNAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 186, __FUNCTION__))->decl_common.decl_flag_1)
)
187 && (!snode->in_other_partition
188 || (!snode->forced_by_abi && !snode->force_output))))
189 return false;
190 node = dyn_cast <cgraph_node *> (snode);
191 return !node || !node->inlined_to;
192}
193
194/* Create a temporary for TYPE for a statement STMT. If the current function
195 is in SSA form, a SSA name is created. Otherwise a temporary register
196 is made. */
197
198tree
199create_tmp_reg_or_ssa_name (tree type, gimple *stmt)
200{
201 if (gimple_in_ssa_p (cfun(cfun + 0)))
202 return make_ssa_name (type, stmt);
203 else
204 return create_tmp_reg (type);
205}
206
207/* CVAL is value taken from DECL_INITIAL of variable. Try to transform it into
208 acceptable form for is_gimple_min_invariant.
209 FROM_DECL (if non-NULL) specify variable whose constructor contains CVAL. */
210
211tree
212canonicalize_constructor_val (tree cval, tree from_decl)
213{
214 if (CONSTANT_CLASS_P (cval)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (cval)->base.code))] == tcc_constant)
)
215 return cval;
216
217 tree orig_cval = cval;
218 STRIP_NOPS (cval)(cval) = tree_strip_nop_conversions ((const_cast<union tree_node
*> (((cval)))))
;
219 if (TREE_CODE (cval)((enum tree_code) (cval)->base.code) == POINTER_PLUS_EXPR
220 && TREE_CODE (TREE_OPERAND (cval, 1))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((cval), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 220, __FUNCTION__))))))->base.code)
== INTEGER_CST)
221 {
222 tree ptr = TREE_OPERAND (cval, 0)(*((const_cast<tree*> (tree_operand_check ((cval), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 222, __FUNCTION__)))))
;
223 if (is_gimple_min_invariant (ptr))
224 cval = build1_loc (EXPR_LOCATION (cval)((((cval)) && ((tree_code_type_tmpl <0>::tree_code_type
[(int) (((enum tree_code) ((cval))->base.code))]) >= tcc_reference
&& (tree_code_type_tmpl <0>::tree_code_type[(int
) (((enum tree_code) ((cval))->base.code))]) <= tcc_expression
)) ? (cval)->exp.locus : ((location_t) 0))
,
225 ADDR_EXPR, TREE_TYPE (ptr)((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 225, __FUNCTION__))->typed.type)
,
226 fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (ptr)),fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check
((((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type), ptr, fold_convert_loc (
((location_t) 0), global_trees[TI_PTR_TYPE], (*((const_cast<
tree*> (tree_operand_check ((cval), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 229, __FUNCTION__)))))) )
227 ptr,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check
((((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type), ptr, fold_convert_loc (
((location_t) 0), global_trees[TI_PTR_TYPE], (*((const_cast<
tree*> (tree_operand_check ((cval), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 229, __FUNCTION__)))))) )
228 fold_convert (ptr_type_node,fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check
((((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type), ptr, fold_convert_loc (
((location_t) 0), global_trees[TI_PTR_TYPE], (*((const_cast<
tree*> (tree_operand_check ((cval), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 229, __FUNCTION__)))))) )
229 TREE_OPERAND (cval, 1)))fold_build2_loc (((location_t) 0), MEM_REF, ((contains_struct_check
((((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 226, __FUNCTION__))->typed.type), ptr, fold_convert_loc (
((location_t) 0), global_trees[TI_PTR_TYPE], (*((const_cast<
tree*> (tree_operand_check ((cval), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 229, __FUNCTION__)))))) )
);
230 }
231 if (TREE_CODE (cval)((enum tree_code) (cval)->base.code) == ADDR_EXPR)
232 {
233 tree base = NULL_TREE(tree) __null;
234 if (TREE_CODE (TREE_OPERAND (cval, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((cval), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 234, __FUNCTION__))))))->base.code)
== COMPOUND_LITERAL_EXPR)
235 {
236 base = COMPOUND_LITERAL_EXPR_DECL (TREE_OPERAND (cval, 0))(*((const_cast<tree*> (tree_operand_check (((tree_check
(((*((const_cast<tree*> (tree_operand_check (((tree_check
(((*((const_cast<tree*> (tree_operand_check ((cval), (
0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 236, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 236, __FUNCTION__, (COMPOUND_LITERAL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 236, __FUNCTION__)))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 236, __FUNCTION__, (DECL_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 236, __FUNCTION__)))))
;
237 if (base)
238 TREE_OPERAND (cval, 0)(*((const_cast<tree*> (tree_operand_check ((cval), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 238, __FUNCTION__)))))
= base;
239 }
240 else
241 base = get_base_address (TREE_OPERAND (cval, 0)(*((const_cast<tree*> (tree_operand_check ((cval), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 241, __FUNCTION__)))))
);
242 if (!base)
243 return NULL_TREE(tree) __null;
244
245 if (VAR_OR_FUNCTION_DECL_P (base)(((enum tree_code) (base)->base.code) == VAR_DECL || ((enum
tree_code) (base)->base.code) == FUNCTION_DECL)
246 && !can_refer_decl_in_current_unit_p (base, from_decl))
247 return NULL_TREE(tree) __null;
248 if (TREE_TYPE (base)((contains_struct_check ((base), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 248, __FUNCTION__))->typed.type)
== error_mark_nodeglobal_trees[TI_ERROR_MARK])
249 return NULL_TREE(tree) __null;
250 if (VAR_P (base)(((enum tree_code) (base)->base.code) == VAR_DECL))
251 /* ??? We should be able to assert that TREE_ADDRESSABLE is set,
252 but since the use can be in a debug stmt we can't. */
253 ;
254 else if (TREE_CODE (base)((enum tree_code) (base)->base.code) == FUNCTION_DECL)
255 {
256 /* Make sure we create a cgraph node for functions we'll reference.
257 They can be non-existent if the reference comes from an entry
258 of an external vtable for example. */
259 cgraph_node::get_create (base);
260 }
261 /* Fixup types in global initializers. */
262 if (TREE_TYPE (TREE_TYPE (cval))((contains_struct_check ((((contains_struct_check ((cval), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 262, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 262, __FUNCTION__))->typed.type)
!= TREE_TYPE (TREE_OPERAND (cval, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
((cval), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 262, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 262, __FUNCTION__))->typed.type)
)
263 cval = build_fold_addr_expr (TREE_OPERAND (cval, 0))build_fold_addr_expr_loc (((location_t) 0), ((*((const_cast<
tree*> (tree_operand_check ((cval), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 263, __FUNCTION__)))))))
;
264
265 if (!useless_type_conversion_p (TREE_TYPE (orig_cval)((contains_struct_check ((orig_cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 265, __FUNCTION__))->typed.type)
, TREE_TYPE (cval)((contains_struct_check ((cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 265, __FUNCTION__))->typed.type)
))
266 cval = fold_convert (TREE_TYPE (orig_cval), cval)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(orig_cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 266, __FUNCTION__))->typed.type), cval)
;
267 return cval;
268 }
269 /* In CONSTRUCTORs we may see unfolded constants like (int (*) ()) 0. */
270 if (TREE_CODE (cval)((enum tree_code) (cval)->base.code) == INTEGER_CST)
271 {
272 if (TREE_OVERFLOW_P (cval)((tree_code_type_tmpl <0>::tree_code_type[(int) (((enum
tree_code) (cval)->base.code))] == tcc_constant) &&
((tree_class_check ((cval), (tcc_constant), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 272, __FUNCTION__))->base.public_flag))
)
273 cval = drop_tree_overflow (cval);
274 if (!useless_type_conversion_p (TREE_TYPE (orig_cval)((contains_struct_check ((orig_cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 274, __FUNCTION__))->typed.type)
, TREE_TYPE (cval)((contains_struct_check ((cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 274, __FUNCTION__))->typed.type)
))
275 cval = fold_convert (TREE_TYPE (orig_cval), cval)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(orig_cval), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 275, __FUNCTION__))->typed.type), cval)
;
276 return cval;
277 }
278 return orig_cval;
279}
280
281/* If SYM is a constant variable with known value, return the value.
282 NULL_TREE is returned otherwise. */
283
284tree
285get_symbol_constant_value (tree sym)
286{
287 tree val = ctor_for_folding (sym);
288 if (val != error_mark_nodeglobal_trees[TI_ERROR_MARK])
289 {
290 if (val)
291 {
292 val = canonicalize_constructor_val (unshare_expr (val), sym);
293 if (val
294 && is_gimple_min_invariant (val)
295 && useless_type_conversion_p (TREE_TYPE (sym)((contains_struct_check ((sym), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 295, __FUNCTION__))->typed.type)
, TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 295, __FUNCTION__))->typed.type)
))
296 return val;
297 else
298 return NULL_TREE(tree) __null;
299 }
300 /* Variables declared 'const' without an initializer
301 have zero as the initializer if they may not be
302 overridden at link or run time. */
303 if (!val
304 && is_gimple_reg_type (TREE_TYPE (sym)((contains_struct_check ((sym), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 304, __FUNCTION__))->typed.type)
))
305 return build_zero_cst (TREE_TYPE (sym)((contains_struct_check ((sym), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 305, __FUNCTION__))->typed.type)
);
306 }
307
308 return NULL_TREE(tree) __null;
309}
310
311
312
313/* Subroutine of fold_stmt. We perform constant folding of the
314 memory reference tree EXPR. */
315
316static tree
317maybe_fold_reference (tree expr)
318{
319 tree result = NULL_TREE(tree) __null;
320
321 if ((TREE_CODE (expr)((enum tree_code) (expr)->base.code) == VIEW_CONVERT_EXPR
322 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == REALPART_EXPR
323 || TREE_CODE (expr)((enum tree_code) (expr)->base.code) == IMAGPART_EXPR)
324 && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0))(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) ((*((const_cast<tree*> (tree_operand_check ((expr), (
0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 324, __FUNCTION__))))))->base.code))] == tcc_constant)
)
325 result = fold_unary_loc (EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type
[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference
&& (tree_code_type_tmpl <0>::tree_code_type[(int
) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression
)) ? (expr)->exp.locus : ((location_t) 0))
,
326 TREE_CODE (expr)((enum tree_code) (expr)->base.code),
327 TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 327, __FUNCTION__))->typed.type)
,
328 TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 328, __FUNCTION__)))))
);
329 else if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) == BIT_FIELD_REF
330 && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0))(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) ((*((const_cast<tree*> (tree_operand_check ((expr), (
0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 330, __FUNCTION__))))))->base.code))] == tcc_constant)
)
331 result = fold_ternary_loc (EXPR_LOCATION (expr)((((expr)) && ((tree_code_type_tmpl <0>::tree_code_type
[(int) (((enum tree_code) ((expr))->base.code))]) >= tcc_reference
&& (tree_code_type_tmpl <0>::tree_code_type[(int
) (((enum tree_code) ((expr))->base.code))]) <= tcc_expression
)) ? (expr)->exp.locus : ((location_t) 0))
,
332 TREE_CODE (expr)((enum tree_code) (expr)->base.code),
333 TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 333, __FUNCTION__))->typed.type)
,
334 TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 334, __FUNCTION__)))))
,
335 TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 335, __FUNCTION__)))))
,
336 TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 336, __FUNCTION__)))))
);
337 else
338 result = fold_const_aggregate_ref (expr);
339
340 if (result && is_gimple_min_invariant (result))
341 return result;
342
343 return NULL_TREE(tree) __null;
344}
345
346/* Return true if EXPR is an acceptable right-hand-side for a
347 GIMPLE assignment. We validate the entire tree, not just
348 the root node, thus catching expressions that embed complex
349 operands that are not permitted in GIMPLE. This function
350 is needed because the folding routines in fold-const.cc
351 may return such expressions in some cases, e.g., an array
352 access with an embedded index addition. It may make more
353 sense to have folding routines that are sensitive to the
354 constraints on GIMPLE operands, rather than abandoning any
355 any attempt to fold if the usual folding turns out to be too
356 aggressive. */
357
358bool
359valid_gimple_rhs_p (tree expr)
360{
361 enum tree_code code = TREE_CODE (expr)((enum tree_code) (expr)->base.code);
362
363 switch (TREE_CODE_CLASS (code)tree_code_type_tmpl <0>::tree_code_type[(int) (code)])
364 {
365 case tcc_declaration:
366 if (!is_gimple_variable (expr))
367 return false;
368 break;
369
370 case tcc_constant:
371 /* All constants are ok. */
372 break;
373
374 case tcc_comparison:
375 /* GENERIC allows comparisons with non-boolean types, reject
376 those for GIMPLE. Let vector-typed comparisons pass - rules
377 for GENERIC and GIMPLE are the same here. */
378 if (!(INTEGRAL_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 378, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 378, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 378, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
379 && (TREE_CODE (TREE_TYPE (expr))((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 379, __FUNCTION__))->typed.type))->base.code)
== BOOLEAN_TYPE
380 || TYPE_PRECISION (TREE_TYPE (expr))((tree_class_check ((((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 380, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 380, __FUNCTION__))->type_common.precision)
== 1))
381 && ! VECTOR_TYPE_P (TREE_TYPE (expr))(((enum tree_code) (((contains_struct_check ((expr), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 381, __FUNCTION__))->typed.type))->base.code) == VECTOR_TYPE
)
)
382 return false;
383
384 /* Fallthru. */
385 case tcc_binary:
386 if (!is_gimple_val (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 386, __FUNCTION__)))))
)
387 || !is_gimple_val (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 387, __FUNCTION__)))))
))
388 return false;
389 break;
390
391 case tcc_unary:
392 if (!is_gimple_val (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 392, __FUNCTION__)))))
))
393 return false;
394 break;
395
396 case tcc_expression:
397 switch (code)
398 {
399 case ADDR_EXPR:
400 {
401 tree t;
402 if (is_gimple_min_invariant (expr))
403 return true;
404 t = TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 404, __FUNCTION__)))))
;
405 while (handled_component_p (t))
406 {
407 /* ??? More checks needed, see the GIMPLE verifier. */
408 if ((TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_REF
409 || TREE_CODE (t)((enum tree_code) (t)->base.code) == ARRAY_RANGE_REF)
410 && !is_gimple_val (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 410, __FUNCTION__)))))
))
411 return false;
412 t = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 412, __FUNCTION__)))))
;
413 }
414 if (!is_gimple_id (t))
415 return false;
416 }
417 break;
418
419 default:
420 if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
421 {
422 if (!is_gimple_val (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 422, __FUNCTION__)))))
)
423 || !is_gimple_val (TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 423, __FUNCTION__)))))
)
424 || !is_gimple_val (TREE_OPERAND (expr, 2)(*((const_cast<tree*> (tree_operand_check ((expr), (2),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 424, __FUNCTION__)))))
))
425 return false;
426 break;
427 }
428 return false;
429 }
430 break;
431
432 case tcc_vl_exp:
433 return false;
434
435 case tcc_exceptional:
436 if (code == CONSTRUCTOR)
437 {
438 unsigned i;
439 tree elt;
440 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)for (i = 0; (i >= vec_safe_length (((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 440, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ?
false : ((elt = (*(((tree_check ((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 440, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))[
i].value), true); (i)++)
441 if (!is_gimple_val (elt))
442 return false;
443 return true;
444 }
445 if (code != SSA_NAME)
446 return false;
447 break;
448
449 case tcc_reference:
450 if (code == BIT_FIELD_REF)
451 return is_gimple_val (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 451, __FUNCTION__)))))
);
452 return false;
453
454 default:
455 return false;
456 }
457
458 return true;
459}
460
461
462/* Attempt to fold an assignment statement pointed-to by SI. Returns a
463 replacement rhs for the statement or NULL_TREE if no simplification
464 could be made. It is assumed that the operands have been previously
465 folded. */
466
467static tree
468fold_gimple_assign (gimple_stmt_iterator *si)
469{
470 gimple *stmt = gsi_stmt (*si);
471 enum tree_code subcode = gimple_assign_rhs_code (stmt);
472 location_t loc = gimple_location (stmt);
473
474 tree result = NULL_TREE(tree) __null;
475
476 switch (get_gimple_rhs_class (subcode))
477 {
478 case GIMPLE_SINGLE_RHS:
479 {
480 tree rhs = gimple_assign_rhs1 (stmt);
481
482 if (TREE_CLOBBER_P (rhs)(((enum tree_code) (rhs)->base.code) == CONSTRUCTOR &&
((rhs)->base.volatile_flag))
)
483 return NULL_TREE(tree) __null;
484
485 if (REFERENCE_CLASS_P (rhs)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (rhs)->base.code))] == tcc_reference)
)
486 return maybe_fold_reference (rhs);
487
488 else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == OBJ_TYPE_REF)
489 {
490 tree val = OBJ_TYPE_REF_EXPR (rhs)(*((const_cast<tree*> (tree_operand_check (((tree_check
((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 490, __FUNCTION__, (OBJ_TYPE_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 490, __FUNCTION__)))))
;
491 if (is_gimple_min_invariant (val))
492 return val;
493 else if (flag_devirtualizeglobal_options.x_flag_devirtualize && virtual_method_call_p (rhs))
494 {
495 bool final;
496 vec <cgraph_node *>targets
497 = possible_polymorphic_call_targets (rhs, stmt, &final);
498 if (final && targets.length () <= 1 && dbg_cnt (devirt))
499 {
500 if (dump_enabled_p ())
501 {
502 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
503 "resolving virtual function address "
504 "reference to function %s\n",
505 targets.length () == 1
506 ? targets[0]->name ()
507 : "NULL");
508 }
509 if (targets.length () == 1)
510 {
511 val = fold_convert (TREE_TYPE (val),fold_convert_loc (((location_t) 0), ((contains_struct_check (
(val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 511, __FUNCTION__))->typed.type), build_fold_addr_expr_loc
(loc, targets[0]->decl))
512 build_fold_addr_expr_locfold_convert_loc (((location_t) 0), ((contains_struct_check (
(val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 511, __FUNCTION__))->typed.type), build_fold_addr_expr_loc
(loc, targets[0]->decl))
513 (loc, targets[0]->decl))fold_convert_loc (((location_t) 0), ((contains_struct_check (
(val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 511, __FUNCTION__))->typed.type), build_fold_addr_expr_loc
(loc, targets[0]->decl))
;
514 STRIP_USELESS_TYPE_CONVERSION (val)(val) = tree_ssa_strip_useless_type_conversions (val);
515 }
516 else
517 /* We cannot use __builtin_unreachable here because it
518 cannot have address taken. */
519 val = build_int_cst (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 519, __FUNCTION__))->typed.type)
, 0);
520 return val;
521 }
522 }
523 }
524
525 else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == ADDR_EXPR)
526 {
527 tree ref = TREE_OPERAND (rhs, 0)(*((const_cast<tree*> (tree_operand_check ((rhs), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 527, __FUNCTION__)))))
;
528 if (TREE_CODE (ref)((enum tree_code) (ref)->base.code) == MEM_REF
529 && integer_zerop (TREE_OPERAND (ref, 1)(*((const_cast<tree*> (tree_operand_check ((ref), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 529, __FUNCTION__)))))
))
530 {
531 result = TREE_OPERAND (ref, 0)(*((const_cast<tree*> (tree_operand_check ((ref), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 531, __FUNCTION__)))))
;
532 if (!useless_type_conversion_p (TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 532, __FUNCTION__))->typed.type)
,
533 TREE_TYPE (result)((contains_struct_check ((result), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 533, __FUNCTION__))->typed.type)
))
534 result = build1 (NOP_EXPR, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 534, __FUNCTION__))->typed.type)
, result);
535 return result;
536 }
537 }
538
539 else if (TREE_CODE (rhs)((enum tree_code) (rhs)->base.code) == CONSTRUCTOR
540 && TREE_CODE (TREE_TYPE (rhs))((enum tree_code) (((contains_struct_check ((rhs), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 540, __FUNCTION__))->typed.type))->base.code)
== VECTOR_TYPE)
541 {
542 /* Fold a constant vector CONSTRUCTOR to VECTOR_CST. */
543 unsigned i;
544 tree val;
545
546 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)for (i = 0; (i >= vec_safe_length (((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 546, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))) ?
false : ((val = (*(((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 546, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))[
i].value), true); (i)++)
547 if (! CONSTANT_CLASS_P (val)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (val)->base.code))] == tcc_constant)
)
548 return NULL_TREE(tree) __null;
549
550 return build_vector_from_ctor (TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 550, __FUNCTION__))->typed.type)
,
551 CONSTRUCTOR_ELTS (rhs)((tree_check ((rhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 551, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)
);
552 }
553
554 else if (DECL_P (rhs)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (rhs)->base.code))] == tcc_declaration)
555 && is_gimple_reg_type (TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 555, __FUNCTION__))->typed.type)
))
556 return get_symbol_constant_value (rhs);
557 }
558 break;
559
560 case GIMPLE_UNARY_RHS:
561 break;
562
563 case GIMPLE_BINARY_RHS:
564 break;
565
566 case GIMPLE_TERNARY_RHS:
567 result = fold_ternary_loc (loc, subcode,
568 TREE_TYPE (gimple_assign_lhs (stmt))((contains_struct_check ((gimple_assign_lhs (stmt)), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 568, __FUNCTION__))->typed.type)
,
569 gimple_assign_rhs1 (stmt),
570 gimple_assign_rhs2 (stmt),
571 gimple_assign_rhs3 (stmt));
572
573 if (result)
574 {
575 STRIP_USELESS_TYPE_CONVERSION (result)(result) = tree_ssa_strip_useless_type_conversions (result);
576 if (valid_gimple_rhs_p (result))
577 return result;
578 }
579 break;
580
581 case GIMPLE_INVALID_RHS:
582 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 582, __FUNCTION__))
;
583 }
584
585 return NULL_TREE(tree) __null;
586}
587
588
589/* Replace a statement at *SI_P with a sequence of statements in STMTS,
590 adjusting the replacement stmts location and virtual operands.
591 If the statement has a lhs the last stmt in the sequence is expected
592 to assign to that lhs. */
593
594void
595gsi_replace_with_seq_vops (gimple_stmt_iterator *si_p, gimple_seq stmts)
596{
597 gimple *stmt = gsi_stmt (*si_p);
598
599 if (gimple_has_location (stmt))
600 annotate_all_with_location (stmts, gimple_location (stmt));
601
602 /* First iterate over the replacement statements backward, assigning
603 virtual operands to their defining statements. */
604 gimple *laststore = NULL__null;
605 for (gimple_stmt_iterator i = gsi_last (stmts);
606 !gsi_end_p (i); gsi_prev (&i))
607 {
608 gimple *new_stmt = gsi_stmt (i);
609 if ((gimple_assign_single_p (new_stmt)
610 && !is_gimple_reg (gimple_assign_lhs (new_stmt)))
611 || (is_gimple_call (new_stmt)
612 && (gimple_call_flags (new_stmt)
613 & (ECF_NOVOPS(1 << 9) | ECF_PURE(1 << 1) | ECF_CONST(1 << 0) | ECF_NORETURN(1 << 3))) == 0))
614 {
615 tree vdef;
616 if (!laststore)
617 vdef = gimple_vdef (stmt);
618 else
619 vdef = make_ssa_name (gimple_vop (cfun(cfun + 0)), new_stmt);
620 gimple_set_vdef (new_stmt, vdef);
621 if (vdef && TREE_CODE (vdef)((enum tree_code) (vdef)->base.code) == SSA_NAME)
622 SSA_NAME_DEF_STMT (vdef)(tree_check ((vdef), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 622, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
= new_stmt;
623 laststore = new_stmt;
624 }
625 }
626
627 /* Second iterate over the statements forward, assigning virtual
628 operands to their uses. */
629 tree reaching_vuse = gimple_vuse (stmt);
630 for (gimple_stmt_iterator i = gsi_start (stmts);
631 !gsi_end_p (i); gsi_next (&i))
632 {
633 gimple *new_stmt = gsi_stmt (i);
634 /* If the new statement possibly has a VUSE, update it with exact SSA
635 name we know will reach this one. */
636 if (gimple_has_mem_ops (new_stmt))
637 gimple_set_vuse (new_stmt, reaching_vuse);
638 gimple_set_modified (new_stmt, true);
639 if (gimple_vdef (new_stmt))
640 reaching_vuse = gimple_vdef (new_stmt);
641 }
642
643 /* If the new sequence does not do a store release the virtual
644 definition of the original statement. */
645 if (reaching_vuse
646 && reaching_vuse == gimple_vuse (stmt))
647 {
648 tree vdef = gimple_vdef (stmt);
649 if (vdef
650 && TREE_CODE (vdef)((enum tree_code) (vdef)->base.code) == SSA_NAME)
651 {
652 unlink_stmt_vdef (stmt);
653 release_ssa_name (vdef);
654 }
655 }
656
657 /* Finally replace the original statement with the sequence. */
658 gsi_replace_with_seq (si_p, stmts, false);
659}
660
661/* Helper function for update_gimple_call and
662 gimplify_and_update_call_from_tree. A GIMPLE_CALL STMT is being replaced
663 with GIMPLE_CALL NEW_STMT. */
664
665static void
666finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
667 gimple *stmt)
668{
669 tree lhs = gimple_call_lhs (stmt);
670 gimple_call_set_lhs (new_stmt, lhs);
671 if (lhs && TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME)
672 SSA_NAME_DEF_STMT (lhs)(tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 672, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
= new_stmt;
673 gimple_move_vops (new_stmt, stmt);
674 gimple_set_location (new_stmt, gimple_location (stmt));
675 if (gimple_block (new_stmt) == NULL_TREE(tree) __null)
676 gimple_set_block (new_stmt, gimple_block (stmt));
677 gsi_replace (si_p, new_stmt, false);
678}
679
680/* Update a GIMPLE_CALL statement at iterator *SI_P to call to FN
681 with number of arguments NARGS, where the arguments in GIMPLE form
682 follow NARGS argument. */
683
684bool
685update_gimple_call (gimple_stmt_iterator *si_p, tree fn, int nargs, ...)
686{
687 va_list ap;
688 gcall *new_stmt, *stmt = as_a <gcall *> (gsi_stmt (*si_p));
689
690 gcc_assert (is_gimple_call (stmt))((void)(!(is_gimple_call (stmt)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 690, __FUNCTION__), 0 : 0))
;
691 va_start (ap, nargs)__builtin_va_start(ap, nargs);
692 new_stmt = gimple_build_call_valist (fn, nargs, ap);
693 finish_update_gimple_call (si_p, new_stmt, stmt);
694 va_end (ap)__builtin_va_end(ap);
695 return true;
696}
697
698/* Return true if EXPR is a CALL_EXPR suitable for representation
699 as a single GIMPLE_CALL statement. If the arguments require
700 further gimplification, return false. */
701
702static bool
703valid_gimple_call_p (tree expr)
704{
705 unsigned i, nargs;
706
707 if (TREE_CODE (expr)((enum tree_code) (expr)->base.code) != CALL_EXPR)
708 return false;
709
710 nargs = call_expr_nargs (expr)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check
((expr), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 710, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 710, __FUNCTION__)))) - 3)
;
711 for (i = 0; i < nargs; i++)
712 {
713 tree arg = CALL_EXPR_ARG (expr, i)(*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 713, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 713, __FUNCTION__)))))
;
714 if (is_gimple_reg_type (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 714, __FUNCTION__))->typed.type)
))
715 {
716 if (!is_gimple_val (arg))
717 return false;
718 }
719 else
720 if (!is_gimple_lvalue (arg))
721 return false;
722 }
723
724 return true;
725}
726
727/* Convert EXPR into a GIMPLE value suitable for substitution on the
728 RHS of an assignment. Insert the necessary statements before
729 iterator *SI_P. The statement at *SI_P, which must be a GIMPLE_CALL
730 is replaced. If the call is expected to produces a result, then it
731 is replaced by an assignment of the new RHS to the result variable.
732 If the result is to be ignored, then the call is replaced by a
733 GIMPLE_NOP. A proper VDEF chain is retained by making the first
734 VUSE and the last VDEF of the whole sequence be the same as the replaced
735 statement and using new SSA names for stores in between. */
736
737void
738gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
739{
740 tree lhs;
741 gimple *stmt, *new_stmt;
742 gimple_stmt_iterator i;
743 gimple_seq stmts = NULL__null;
744
745 stmt = gsi_stmt (*si_p);
746
747 gcc_assert (is_gimple_call (stmt))((void)(!(is_gimple_call (stmt)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 747, __FUNCTION__), 0 : 0))
;
748
749 if (valid_gimple_call_p (expr))
750 {
751 /* The call has simplified to another call. */
752 tree fn = CALL_EXPR_FN (expr)(*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 752, __FUNCTION__, (CALL_EXPR)))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 752, __FUNCTION__)))))
;
753 unsigned i;
754 unsigned nargs = call_expr_nargs (expr)(((int)((unsigned long) (*tree_int_cst_elt_check (((tree_class_check
((expr), (tcc_vl_exp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 754, __FUNCTION__))->exp.operands[0]), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 754, __FUNCTION__)))) - 3)
;
755 vec<tree> args = vNULL;
756 gcall *new_stmt;
757
758 if (nargs > 0)
759 {
760 args.create (nargs);
761 args.safe_grow_cleared (nargs, true);
762
763 for (i = 0; i < nargs; i++)
764 args[i] = CALL_EXPR_ARG (expr, i)(*((const_cast<tree*> (tree_operand_check (((tree_check
((expr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 764, __FUNCTION__, (CALL_EXPR)))), ((i) + 3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 764, __FUNCTION__)))))
;
765 }
766
767 new_stmt = gimple_build_call_vec (fn, args);
768 finish_update_gimple_call (si_p, new_stmt, stmt);
769 args.release ();
770 return;
771 }
772
773 lhs = gimple_call_lhs (stmt);
774 if (lhs == NULL_TREE(tree) __null)
775 {
776 push_gimplify_context (gimple_in_ssa_p (cfun(cfun + 0)));
777 gimplify_and_add (expr, &stmts);
778 pop_gimplify_context (NULL__null);
779
780 /* We can end up with folding a memcpy of an empty class assignment
781 which gets optimized away by C++ gimplification. */
782 if (gimple_seq_empty_p (stmts))
783 {
784 if (gimple_in_ssa_p (cfun(cfun + 0)))
785 {
786 unlink_stmt_vdef (stmt);
787 release_defs (stmt);
788 }
789 gsi_replace (si_p, gimple_build_nop (), false);
790 return;
791 }
792 }
793 else
794 {
795 tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE(tree) __null);
796 new_stmt = gimple_build_assign (lhs, tmp);
797 i = gsi_last (stmts);
798 gsi_insert_after_without_update (&i, new_stmt,
799 GSI_CONTINUE_LINKING);
800 }
801
802 gsi_replace_with_seq_vops (si_p, stmts);
803}
804
805
806/* Replace the call at *GSI with the gimple value VAL. */
807
808void
809replace_call_with_value (gimple_stmt_iterator *gsi, tree val)
810{
811 gimple *stmt = gsi_stmt (*gsi);
812 tree lhs = gimple_call_lhs (stmt);
813 gimple *repl;
814 if (lhs)
815 {
816 if (!useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 816, __FUNCTION__))->typed.type)
, TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 816, __FUNCTION__))->typed.type)
))
817 val = fold_convert (TREE_TYPE (lhs), val)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 817, __FUNCTION__))->typed.type), val)
;
818 repl = gimple_build_assign (lhs, val);
819 }
820 else
821 repl = gimple_build_nop ();
822 tree vdef = gimple_vdef (stmt);
823 if (vdef && TREE_CODE (vdef)((enum tree_code) (vdef)->base.code) == SSA_NAME)
824 {
825 unlink_stmt_vdef (stmt);
826 release_ssa_name (vdef);
827 }
828 gsi_replace (gsi, repl, false);
829}
830
831/* Replace the call at *GSI with the new call REPL and fold that
832 again. */
833
834static void
835replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
836{
837 gimple *stmt = gsi_stmt (*gsi);
838 gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
839 gimple_set_location (repl, gimple_location (stmt));
840 gimple_move_vops (repl, stmt);
841 gsi_replace (gsi, repl, false);
842 fold_stmt (gsi);
843}
844
845/* Return true if VAR is a VAR_DECL or a component thereof. */
846
847static bool
848var_decl_component_p (tree var)
849{
850 tree inner = var;
851 while (handled_component_p (inner))
852 inner = TREE_OPERAND (inner, 0)(*((const_cast<tree*> (tree_operand_check ((inner), (0)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 852, __FUNCTION__)))))
;
853 return (DECL_P (inner)(tree_code_type_tmpl <0>::tree_code_type[(int) (((enum tree_code
) (inner)->base.code))] == tcc_declaration)
854 || (TREE_CODE (inner)((enum tree_code) (inner)->base.code) == MEM_REF
855 && TREE_CODE (TREE_OPERAND (inner, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((inner), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 855, __FUNCTION__))))))->base.code)
== ADDR_EXPR));
856}
857
858/* Return TRUE if the SIZE argument, representing the size of an
859 object, is in a range of values of which exactly zero is valid. */
860
861static bool
862size_must_be_zero_p (tree size)
863{
864 if (integer_zerop (size))
865 return true;
866
867 if (TREE_CODE (size)((enum tree_code) (size)->base.code) != SSA_NAME || !INTEGRAL_TYPE_P (TREE_TYPE (size))(((enum tree_code) (((contains_struct_check ((size), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 867, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((size), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 867, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((size), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 867, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)
)
868 return false;
869
870 tree type = TREE_TYPE (size)((contains_struct_check ((size), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 870, __FUNCTION__))->typed.type)
;
871 int prec = TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 871, __FUNCTION__))->type_common.precision)
;
872
873 /* Compute the value of SSIZE_MAX, the largest positive value that
874 can be stored in ssize_t, the signed counterpart of size_t. */
875 wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
876 value_range valid_range (build_int_cst (type, 0),
877 wide_int_to_tree (type, ssize_max));
878 value_range vr;
879 if (cfun(cfun + 0))
880 get_range_query (cfun(cfun + 0))->range_of_expr (vr, size);
881 else
882 get_global_range_query ()->range_of_expr (vr, size);
883 if (vr.undefined_p ())
884 vr.set_varying (TREE_TYPE (size)((contains_struct_check ((size), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 884, __FUNCTION__))->typed.type)
);
885 vr.intersect (valid_range);
886 return vr.zero_p ();
887}
888
889/* Fold function call to builtin mem{{,p}cpy,move}. Try to detect and
890 diagnose (otherwise undefined) overlapping copies without preventing
891 folding. When folded, GCC guarantees that overlapping memcpy has
892 the same semantics as memmove. Call to the library memcpy need not
893 provide the same guarantee. Return false if no simplification can
894 be made. */
895
896static bool
897gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
898 tree dest, tree src, enum built_in_function code)
899{
900 gimple *stmt = gsi_stmt (*gsi);
901 tree lhs = gimple_call_lhs (stmt);
902 tree len = gimple_call_arg (stmt, 2);
903 location_t loc = gimple_location (stmt);
904
905 /* If the LEN parameter is a constant zero or in range where
906 the only valid value is zero, return DEST. */
907 if (size_must_be_zero_p (len))
908 {
909 gimple *repl;
910 if (gimple_call_lhs (stmt))
911 repl = gimple_build_assign (gimple_call_lhs (stmt), dest);
912 else
913 repl = gimple_build_nop ();
914 tree vdef = gimple_vdef (stmt);
915 if (vdef && TREE_CODE (vdef)((enum tree_code) (vdef)->base.code) == SSA_NAME)
916 {
917 unlink_stmt_vdef (stmt);
918 release_ssa_name (vdef);
919 }
920 gsi_replace (gsi, repl, false);
921 return true;
922 }
923
924 /* If SRC and DEST are the same (and not volatile), return
925 DEST{,+LEN,+LEN-1}. */
926 if (operand_equal_p (src, dest, 0))
927 {
928 /* Avoid diagnosing exact overlap in calls to __builtin_memcpy.
929 It's safe and may even be emitted by GCC itself (see bug
930 32667). */
931 unlink_stmt_vdef (stmt);
932 if (gimple_vdef (stmt) && TREE_CODE (gimple_vdef (stmt))((enum tree_code) (gimple_vdef (stmt))->base.code) == SSA_NAME)
933 release_ssa_name (gimple_vdef (stmt));
934 if (!lhs)
935 {
936 gsi_replace (gsi, gimple_build_nop (), false);
937 return true;
938 }
939 goto done;
940 }
941 else
942 {
943 /* We cannot (easily) change the type of the copy if it is a storage
944 order barrier, i.e. is equivalent to a VIEW_CONVERT_EXPR that can
945 modify the storage order of objects (see storage_order_barrier_p). */
946 tree srctype
947 = POINTER_TYPE_P (TREE_TYPE (src))(((enum tree_code) (((contains_struct_check ((src), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 947, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((src), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 947, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
948 ? TREE_TYPE (TREE_TYPE (src))((contains_struct_check ((((contains_struct_check ((src), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 948, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 948, __FUNCTION__))->typed.type)
: NULL_TREE(tree) __null;
949 tree desttype
950 = POINTER_TYPE_P (TREE_TYPE (dest))(((enum tree_code) (((contains_struct_check ((dest), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 950, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((dest), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 950, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
951 ? TREE_TYPE (TREE_TYPE (dest))((contains_struct_check ((((contains_struct_check ((dest), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 951, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 951, __FUNCTION__))->typed.type)
: NULL_TREE(tree) __null;
952 tree destvar, srcvar, srcoff;
953 unsigned int src_align, dest_align;
954 unsigned HOST_WIDE_INTlong tmp_len;
955 const char *tmp_str;
956
957 /* Build accesses at offset zero with a ref-all character type. */
958 tree off0
959 = build_int_cst (build_pointer_type_for_mode (char_type_nodeinteger_types[itk_char],
960 ptr_mode, true), 0);
961
962 /* If we can perform the copy efficiently with first doing all loads
963 and then all stores inline it that way. Currently efficiently
964 means that we can load all the memory into a single integer
965 register which is what MOVE_MAX gives us. */
966 src_align = get_pointer_alignment (src);
967 dest_align = get_pointer_alignment (dest);
968 if (tree_fits_uhwi_p (len)
969 && compare_tree_int (len, MOVE_MAX((((global_options.x_ix86_isa_flags & (1UL << 15)) !=
0) && (global_options.x_ix86_move_max == PVW_AVX512 ||
global_options.x_ix86_store_max == PVW_AVX512)) ? 64 : ((((global_options
.x_ix86_isa_flags & (1UL << 8)) != 0) && (global_options
.x_ix86_move_max >= PVW_AVX256 || global_options.x_ix86_store_max
>= PVW_AVX256)) ? 32 : ((((global_options.x_ix86_isa_flags
& (1UL << 51)) != 0) && ix86_tune_features
[X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL] && ix86_tune_features
[X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL]) ? 16 : (((global_options
.x_ix86_isa_flags & (1UL << 1)) != 0) ? 8 : 4))))
) <= 0
970 /* FIXME: Don't transform copies from strings with known length.
971 Until GCC 9 this prevented a case in gcc.dg/strlenopt-8.c
972 from being handled, and the case was XFAILed for that reason.
973 Now that it is handled and the XFAIL removed, as soon as other
974 strlenopt tests that rely on it for passing are adjusted, this
975 hack can be removed. */
976 && !c_strlen (src, 1)
977 && !((tmp_str = getbyterep (src, &tmp_len)) != NULL__null
978 && memchr (tmp_str, 0, tmp_len) == NULL__null)
979 && !(srctype
980 && AGGREGATE_TYPE_P (srctype)(((enum tree_code) (srctype)->base.code) == ARRAY_TYPE || (
((enum tree_code) (srctype)->base.code) == RECORD_TYPE || (
(enum tree_code) (srctype)->base.code) == UNION_TYPE || ((
enum tree_code) (srctype)->base.code) == QUAL_UNION_TYPE))
981 && TYPE_REVERSE_STORAGE_ORDER (srctype)((tree_check4 ((srctype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 981, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
), (ARRAY_TYPE)))->base.u.bits.saturating_flag)
)
982 && !(desttype
983 && AGGREGATE_TYPE_P (desttype)(((enum tree_code) (desttype)->base.code) == ARRAY_TYPE ||
(((enum tree_code) (desttype)->base.code) == RECORD_TYPE ||
((enum tree_code) (desttype)->base.code) == UNION_TYPE ||
((enum tree_code) (desttype)->base.code) == QUAL_UNION_TYPE
))
984 && TYPE_REVERSE_STORAGE_ORDER (desttype)((tree_check4 ((desttype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 984, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
), (ARRAY_TYPE)))->base.u.bits.saturating_flag)
))
985 {
986 unsigned ilen = tree_to_uhwi (len);
987 if (pow2p_hwi (ilen))
988 {
989 /* Detect out-of-bounds accesses without issuing warnings.
990 Avoid folding out-of-bounds copies but to avoid false
991 positives for unreachable code defer warning until after
992 DCE has worked its magic.
993 -Wrestrict is still diagnosed. */
994 if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
995 dest, src, len, len,
996 false, false))
997 if (warning != OPT_Wrestrict)
998 return false;
999
1000 scalar_int_mode mode;
1001 if (int_mode_for_size (ilen * 8, 0).exists (&mode)
1002 && GET_MODE_SIZE (mode) * BITS_PER_UNIT(8) == ilen * 8
1003 /* If the destination pointer is not aligned we must be able
1004 to emit an unaligned store. */
1005 && (dest_align >= GET_MODE_ALIGNMENT (mode)get_mode_alignment (mode)
1006 || !targetm.slow_unaligned_access (mode, dest_align)
1007 || (optab_handler (movmisalign_optab, mode)
1008 != CODE_FOR_nothing)))
1009 {
1010 tree type = build_nonstandard_integer_type (ilen * 8, 1);
1011 tree srctype = type;
1012 tree desttype = type;
1013 if (src_align < GET_MODE_ALIGNMENT (mode)get_mode_alignment (mode))
1014 srctype = build_aligned_type (type, src_align);
1015 tree srcmem = fold_build2 (MEM_REF, srctype, src, off0)fold_build2_loc (((location_t) 0), MEM_REF, srctype, src, off0
)
;
1016 tree tem = fold_const_aggregate_ref (srcmem);
1017 if (tem)
1018 srcmem = tem;
1019 else if (src_align < GET_MODE_ALIGNMENT (mode)get_mode_alignment (mode)
1020 && targetm.slow_unaligned_access (mode, src_align)
1021 && (optab_handler (movmisalign_optab, mode)
1022 == CODE_FOR_nothing))
1023 srcmem = NULL_TREE(tree) __null;
1024 if (srcmem)
1025 {
1026 gimple *new_stmt;
1027 if (is_gimple_reg_type (TREE_TYPE (srcmem)((contains_struct_check ((srcmem), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1027, __FUNCTION__))->typed.type)
))
1028 {
1029 new_stmt = gimple_build_assign (NULL_TREE(tree) __null, srcmem);
1030 srcmem
1031 = create_tmp_reg_or_ssa_name (TREE_TYPE (srcmem)((contains_struct_check ((srcmem), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1031, __FUNCTION__))->typed.type)
,
1032 new_stmt);
1033 gimple_assign_set_lhs (new_stmt, srcmem);
1034 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1035 gimple_set_location (new_stmt, loc);
1036 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1037 }
1038 if (dest_align < GET_MODE_ALIGNMENT (mode)get_mode_alignment (mode))
1039 desttype = build_aligned_type (type, dest_align);
1040 new_stmt
1041 = gimple_build_assign (fold_build2 (MEM_REF, desttype,fold_build2_loc (((location_t) 0), MEM_REF, desttype, dest, off0
)
1042 dest, off0)fold_build2_loc (((location_t) 0), MEM_REF, desttype, dest, off0
)
,
1043 srcmem);
1044 gimple_move_vops (new_stmt, stmt);
1045 if (!lhs)
1046 {
1047 gsi_replace (gsi, new_stmt, false);
1048 return true;
1049 }
1050 gimple_set_location (new_stmt, loc);
1051 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1052 goto done;
1053 }
1054 }
1055 }
1056 }
1057
1058 if (code == BUILT_IN_MEMMOVE)
1059 {
1060 /* Both DEST and SRC must be pointer types.
1061 ??? This is what old code did. Is the testing for pointer types
1062 really mandatory?
1063
1064 If either SRC is readonly or length is 1, we can use memcpy. */
1065 if (!dest_align || !src_align)
1066 return false;
1067 if (readonly_data_expr (src)
1068 || (tree_fits_uhwi_p (len)
1069 && (MIN (src_align, dest_align)((src_align) < (dest_align) ? (src_align) : (dest_align)) / BITS_PER_UNIT(8)
1070 >= tree_to_uhwi (len))))
1071 {
1072 tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1073 if (!fn)
1074 return false;
1075 gimple_call_set_fndecl (stmt, fn);
1076 gimple_call_set_arg (stmt, 0, dest);
1077 gimple_call_set_arg (stmt, 1, src);
1078 fold_stmt (gsi);
1079 return true;
1080 }
1081
1082 /* If *src and *dest can't overlap, optimize into memcpy as well. */
1083 if (TREE_CODE (src)((enum tree_code) (src)->base.code) == ADDR_EXPR
1084 && TREE_CODE (dest)((enum tree_code) (dest)->base.code) == ADDR_EXPR)
1085 {
1086 tree src_base, dest_base, fn;
1087 poly_int64 src_offset = 0, dest_offset = 0;
1088 poly_uint64 maxsize;
1089
1090 srcvar = TREE_OPERAND (src, 0)(*((const_cast<tree*> (tree_operand_check ((src), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1090, __FUNCTION__)))))
;
1091 src_base = get_addr_base_and_unit_offset (srcvar, &src_offset);
1092 if (src_base == NULL__null)
1093 src_base = srcvar;
1094 destvar = TREE_OPERAND (dest, 0)(*((const_cast<tree*> (tree_operand_check ((dest), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1094, __FUNCTION__)))))
;
1095 dest_base = get_addr_base_and_unit_offset (destvar,
1096 &dest_offset);
1097 if (dest_base == NULL__null)
1098 dest_base = destvar;
1099 if (!poly_int_tree_p (len, &maxsize))
1100 maxsize = -1;
1101 if (SSA_VAR_P (src_base)(((enum tree_code) (src_base)->base.code) == VAR_DECL || (
(enum tree_code) (src_base)->base.code) == PARM_DECL || ((
enum tree_code) (src_base)->base.code) == RESULT_DECL || (
(enum tree_code) (src_base)->base.code) == SSA_NAME)
1102 && SSA_VAR_P (dest_base)(((enum tree_code) (dest_base)->base.code) == VAR_DECL || (
(enum tree_code) (dest_base)->base.code) == PARM_DECL || (
(enum tree_code) (dest_base)->base.code) == RESULT_DECL ||
((enum tree_code) (dest_base)->base.code) == SSA_NAME)
)
1103 {
1104 if (operand_equal_p (src_base, dest_base, 0)
1105 && ranges_maybe_overlap_p (src_offset, maxsize,
1106 dest_offset, maxsize))
1107 return false;
1108 }
1109 else if (TREE_CODE (src_base)((enum tree_code) (src_base)->base.code) == MEM_REF
1110 && TREE_CODE (dest_base)((enum tree_code) (dest_base)->base.code) == MEM_REF)
1111 {
1112 if (! operand_equal_p (TREE_OPERAND (src_base, 0)(*((const_cast<tree*> (tree_operand_check ((src_base), (
0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1112, __FUNCTION__)))))
,
1113 TREE_OPERAND (dest_base, 0)(*((const_cast<tree*> (tree_operand_check ((dest_base),
(0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1113, __FUNCTION__)))))
, 0))
1114 return false;
1115 poly_offset_int full_src_offset
1116 = mem_ref_offset (src_base) + src_offset;
1117 poly_offset_int full_dest_offset
1118 = mem_ref_offset (dest_base) + dest_offset;
1119 if (ranges_maybe_overlap_p (full_src_offset, maxsize,
1120 full_dest_offset, maxsize))
1121 return false;
1122 }
1123 else
1124 return false;
1125
1126 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1127 if (!fn)
1128 return false;
1129 gimple_call_set_fndecl (stmt, fn);
1130 gimple_call_set_arg (stmt, 0, dest);
1131 gimple_call_set_arg (stmt, 1, src);
1132 fold_stmt (gsi);
1133 return true;
1134 }
1135
1136 /* If the destination and source do not alias optimize into
1137 memcpy as well. */
1138 if ((is_gimple_min_invariant (dest)
1139 || TREE_CODE (dest)((enum tree_code) (dest)->base.code) == SSA_NAME)
1140 && (is_gimple_min_invariant (src)
1141 || TREE_CODE (src)((enum tree_code) (src)->base.code) == SSA_NAME))
1142 {
1143 ao_ref destr, srcr;
1144 ao_ref_init_from_ptr_and_size (&destr, dest, len);
1145 ao_ref_init_from_ptr_and_size (&srcr, src, len);
1146 if (!refs_may_alias_p_1 (&destr, &srcr, false))
1147 {
1148 tree fn;
1149 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
1150 if (!fn)
1151 return false;
1152 gimple_call_set_fndecl (stmt, fn);
1153 gimple_call_set_arg (stmt, 0, dest);
1154 gimple_call_set_arg (stmt, 1, src);
1155 fold_stmt (gsi);
1156 return true;
1157 }
1158 }
1159
1160 return false;
1161 }
1162
1163 if (!tree_fits_shwi_p (len))
1164 return false;
1165 if (!srctype
1166 || (AGGREGATE_TYPE_P (srctype)(((enum tree_code) (srctype)->base.code) == ARRAY_TYPE || (
((enum tree_code) (srctype)->base.code) == RECORD_TYPE || (
(enum tree_code) (srctype)->base.code) == UNION_TYPE || ((
enum tree_code) (srctype)->base.code) == QUAL_UNION_TYPE))
1167 && TYPE_REVERSE_STORAGE_ORDER (srctype)((tree_check4 ((srctype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1167, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
), (ARRAY_TYPE)))->base.u.bits.saturating_flag)
))
1168 return false;
1169 if (!desttype
1170 || (AGGREGATE_TYPE_P (desttype)(((enum tree_code) (desttype)->base.code) == ARRAY_TYPE ||
(((enum tree_code) (desttype)->base.code) == RECORD_TYPE ||
((enum tree_code) (desttype)->base.code) == UNION_TYPE ||
((enum tree_code) (desttype)->base.code) == QUAL_UNION_TYPE
))
1171 && TYPE_REVERSE_STORAGE_ORDER (desttype)((tree_check4 ((desttype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1171, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
), (ARRAY_TYPE)))->base.u.bits.saturating_flag)
))
1172 return false;
1173 /* In the following try to find a type that is most natural to be
1174 used for the memcpy source and destination and that allows
1175 the most optimization when memcpy is turned into a plain assignment
1176 using that type. In theory we could always use a char[len] type
1177 but that only gains us that the destination and source possibly
1178 no longer will have their address taken. */
1179 if (TREE_CODE (srctype)((enum tree_code) (srctype)->base.code) == ARRAY_TYPE
1180 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype)((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1180, __FUNCTION__))->type_common.size_unit)
, len))
1181 srctype = TREE_TYPE (srctype)((contains_struct_check ((srctype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1181, __FUNCTION__))->typed.type)
;
1182 if (TREE_CODE (desttype)((enum tree_code) (desttype)->base.code) == ARRAY_TYPE
1183 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype)((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1183, __FUNCTION__))->type_common.size_unit)
, len))
1184 desttype = TREE_TYPE (desttype)((contains_struct_check ((desttype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1184, __FUNCTION__))->typed.type)
;
1185 if (TREE_ADDRESSABLE (srctype)((srctype)->base.addressable_flag)
1186 || TREE_ADDRESSABLE (desttype)((desttype)->base.addressable_flag))
1187 return false;
1188
1189 /* Make sure we are not copying using a floating-point mode or
1190 a type whose size possibly does not match its precision. */
1191 if (FLOAT_MODE_P (TYPE_MODE (desttype))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1191, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)]) == MODE_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1191, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)]) == MODE_DECIMAL_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1191, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)]) == MODE_COMPLEX_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1191, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)]) == MODE_VECTOR_FLOAT
)
1192 || TREE_CODE (desttype)((enum tree_code) (desttype)->base.code) == BOOLEAN_TYPE
1193 || TREE_CODE (desttype)((enum tree_code) (desttype)->base.code) == ENUMERAL_TYPE)
1194 desttype = bitwise_type_for_mode (TYPE_MODE (desttype)((((enum tree_code) ((tree_class_check ((desttype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1194, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)
);
1195 if (FLOAT_MODE_P (TYPE_MODE (srctype))(((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1195, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)]) == MODE_FLOAT ||
((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1195, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)]) == MODE_DECIMAL_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1195, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)]) == MODE_COMPLEX_FLOAT
|| ((enum mode_class) mode_class[((((enum tree_code) ((tree_class_check
((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1195, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)]) == MODE_VECTOR_FLOAT
)
1196 || TREE_CODE (srctype)((enum tree_code) (srctype)->base.code) == BOOLEAN_TYPE
1197 || TREE_CODE (srctype)((enum tree_code) (srctype)->base.code) == ENUMERAL_TYPE)
1198 srctype = bitwise_type_for_mode (TYPE_MODE (srctype)((((enum tree_code) ((tree_class_check ((srctype), (tcc_type)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1198, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)
);
1199 if (!srctype)
1200 srctype = desttype;
1201 if (!desttype)
1202 desttype = srctype;
1203 if (!srctype)
1204 return false;
1205
1206 src_align = get_pointer_alignment (src);
1207 dest_align = get_pointer_alignment (dest);
1208
1209 /* Choose between src and destination type for the access based
1210 on alignment, whether the access constitutes a register access
1211 and whether it may actually expose a declaration for SSA rewrite
1212 or SRA decomposition. Also try to expose a string constant, we
1213 might be able to concatenate several of them later into a single
1214 string store. */
1215 destvar = NULL_TREE(tree) __null;
1216 srcvar = NULL_TREE(tree) __null;
1217 if (TREE_CODE (dest)((enum tree_code) (dest)->base.code) == ADDR_EXPR
1218 && var_decl_component_p (TREE_OPERAND (dest, 0)(*((const_cast<tree*> (tree_operand_check ((dest), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1218, __FUNCTION__)))))
)
1219 && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype)((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1219, __FUNCTION__))->type_common.size_unit)
, len)
1220 && dest_align >= TYPE_ALIGN (desttype)(((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1220, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1220, __FUNCTION__))->type_common.align) - 1) : 0)
1221 && (is_gimple_reg_type (desttype)
1222 || src_align >= TYPE_ALIGN (desttype)(((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1222, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1222, __FUNCTION__))->type_common.align) - 1) : 0)
))
1223 destvar = fold_build2 (MEM_REF, desttype, dest, off0)fold_build2_loc (((location_t) 0), MEM_REF, desttype, dest, off0
)
;
1224 else if (TREE_CODE (src)((enum tree_code) (src)->base.code) == ADDR_EXPR
1225 && var_decl_component_p (TREE_OPERAND (src, 0)(*((const_cast<tree*> (tree_operand_check ((src), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1225, __FUNCTION__)))))
)
1226 && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype)((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1226, __FUNCTION__))->type_common.size_unit)
, len)
1227 && src_align >= TYPE_ALIGN (srctype)(((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1227, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1227, __FUNCTION__))->type_common.align) - 1) : 0)
1228 && (is_gimple_reg_type (srctype)
1229 || dest_align >= TYPE_ALIGN (srctype)(((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1229, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1229, __FUNCTION__))->type_common.align) - 1) : 0)
))
1230 srcvar = fold_build2 (MEM_REF, srctype, src, off0)fold_build2_loc (((location_t) 0), MEM_REF, srctype, src, off0
)
;
1231 /* FIXME: Don't transform copies from strings with known original length.
1232 As soon as strlenopt tests that rely on it for passing are adjusted,
1233 this hack can be removed. */
1234 else if (gimple_call_alloca_for_var_p (stmt)
1235 && (srcvar = string_constant (src, &srcoff, NULL__null, NULL__null))
1236 && integer_zerop (srcoff)
1237 && tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (srcvar))((tree_class_check ((((contains_struct_check ((srcvar), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1237, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1237, __FUNCTION__))->type_common.size_unit)
, len)
1238 && dest_align >= TYPE_ALIGN (TREE_TYPE (srcvar))(((tree_class_check ((((contains_struct_check ((srcvar), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1238, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1238, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((((contains_struct_check ((srcvar
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1238, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1238, __FUNCTION__))->type_common.align) - 1) : 0)
)
1239 srctype = TREE_TYPE (srcvar)((contains_struct_check ((srcvar), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1239, __FUNCTION__))->typed.type)
;
1240 else
1241 return false;
1242
1243 /* Now that we chose an access type express the other side in
1244 terms of it if the target allows that with respect to alignment
1245 constraints. */
1246 if (srcvar == NULL_TREE(tree) __null)
1247 {
1248 if (src_align >= TYPE_ALIGN (desttype)(((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1248, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1248, __FUNCTION__))->type_common.align) - 1) : 0)
)
1249 srcvar = fold_build2 (MEM_REF, desttype, src, off0)fold_build2_loc (((location_t) 0), MEM_REF, desttype, src, off0
)
;
1250 else
1251 {
1252 enum machine_mode mode = TYPE_MODE (desttype)((((enum tree_code) ((tree_class_check ((desttype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1252, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(desttype) : (desttype)->type_common.mode)
;
1253 if ((mode == BLKmode((void) 0, E_BLKmode) && STRICT_ALIGNMENT0)
1254 || (targetm.slow_unaligned_access (mode, src_align)
1255 && (optab_handler (movmisalign_optab, mode)
1256 == CODE_FOR_nothing)))
1257 return false;
1258 srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype)((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1258, __FUNCTION__))->type_common.main_variant)
,
1259 src_align);
1260 srcvar = fold_build2 (MEM_REF, srctype, src, off0)fold_build2_loc (((location_t) 0), MEM_REF, srctype, src, off0
)
;
1261 }
1262 }
1263 else if (destvar == NULL_TREE(tree) __null)
1264 {
1265 if (dest_align >= TYPE_ALIGN (srctype)(((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1265, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1265, __FUNCTION__))->type_common.align) - 1) : 0)
)
1266 destvar = fold_build2 (MEM_REF, srctype, dest, off0)fold_build2_loc (((location_t) 0), MEM_REF, srctype, dest, off0
)
;
1267 else
1268 {
1269 enum machine_mode mode = TYPE_MODE (srctype)((((enum tree_code) ((tree_class_check ((srctype), (tcc_type)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1269, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(srctype) : (srctype)->type_common.mode)
;
1270 if ((mode == BLKmode((void) 0, E_BLKmode) && STRICT_ALIGNMENT0)
1271 || (targetm.slow_unaligned_access (mode, dest_align)
1272 && (optab_handler (movmisalign_optab, mode)
1273 == CODE_FOR_nothing)))
1274 return false;
1275 desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype)((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1275, __FUNCTION__))->type_common.main_variant)
,
1276 dest_align);
1277 destvar = fold_build2 (MEM_REF, desttype, dest, off0)fold_build2_loc (((location_t) 0), MEM_REF, desttype, dest, off0
)
;
1278 }
1279 }
1280
1281 /* Same as above, detect out-of-bounds accesses without issuing
1282 warnings. Avoid folding out-of-bounds copies but to avoid
1283 false positives for unreachable code defer warning until
1284 after DCE has worked its magic.
1285 -Wrestrict is still diagnosed. */
1286 if (int warning = check_bounds_or_overlap (as_a <gcall *>(stmt),
1287 dest, src, len, len,
1288 false, false))
1289 if (warning != OPT_Wrestrict)
1290 return false;
1291
1292 gimple *new_stmt;
1293 if (is_gimple_reg_type (TREE_TYPE (srcvar)((contains_struct_check ((srcvar), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1293, __FUNCTION__))->typed.type)
))
1294 {
1295 tree tem = fold_const_aggregate_ref (srcvar);
1296 if (tem)
1297 srcvar = tem;
1298 if (! is_gimple_min_invariant (srcvar))
1299 {
1300 new_stmt = gimple_build_assign (NULL_TREE(tree) __null, srcvar);
1301 srcvar = create_tmp_reg_or_ssa_name (TREE_TYPE (srcvar)((contains_struct_check ((srcvar), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1301, __FUNCTION__))->typed.type)
,
1302 new_stmt);
1303 gimple_assign_set_lhs (new_stmt, srcvar);
1304 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
1305 gimple_set_location (new_stmt, loc);
1306 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1307 }
1308 new_stmt = gimple_build_assign (destvar, srcvar);
1309 goto set_vop_and_replace;
1310 }
1311
1312 /* We get an aggregate copy. If the source is a STRING_CST, then
1313 directly use its type to perform the copy. */
1314 if (TREE_CODE (srcvar)((enum tree_code) (srcvar)->base.code) == STRING_CST)
1315 desttype = srctype;
1316
1317 /* Or else, use an unsigned char[] type to perform the copy in order
1318 to preserve padding and to avoid any issues with TREE_ADDRESSABLE
1319 types or float modes behavior on copying. */
1320 else
1321 {
1322 desttype = build_array_type_nelts (unsigned_char_type_nodeinteger_types[itk_unsigned_char],
1323 tree_to_uhwi (len));
1324 srctype = desttype;
1325 if (src_align > TYPE_ALIGN (srctype)(((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1325, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((srctype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1325, __FUNCTION__))->type_common.align) - 1) : 0)
)
1326 srctype = build_aligned_type (srctype, src_align);
1327 srcvar = fold_build2 (MEM_REF, srctype, src, off0)fold_build2_loc (((location_t) 0), MEM_REF, srctype, src, off0
)
;
1328 }
1329
1330 if (dest_align > TYPE_ALIGN (desttype)(((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1330, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((desttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1330, __FUNCTION__))->type_common.align) - 1) : 0)
)
1331 desttype = build_aligned_type (desttype, dest_align);
1332 destvar = fold_build2 (MEM_REF, desttype, dest, off0)fold_build2_loc (((location_t) 0), MEM_REF, desttype, dest, off0
)
;
1333 new_stmt = gimple_build_assign (destvar, srcvar);
1334
1335set_vop_and_replace:
1336 gimple_move_vops (new_stmt, stmt);
1337 if (!lhs)
1338 {
1339 gsi_replace (gsi, new_stmt, false);
1340 return true;
1341 }
1342 gimple_set_location (new_stmt, loc);
1343 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
1344 }
1345
1346done:
1347 gimple_seq stmts = NULL__null;
1348 if (code == BUILT_IN_MEMCPY || code == BUILT_IN_MEMMOVE)
1349 len = NULL_TREE(tree) __null;
1350 else if (code == BUILT_IN_MEMPCPY)
1351 {
1352 len = gimple_convert_to_ptrofftype (&stmts, loc, len);
1353 dest = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
1354 TREE_TYPE (dest)((contains_struct_check ((dest), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1354, __FUNCTION__))->typed.type)
, dest, len);
1355 }
1356 else
1357 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1357, __FUNCTION__))
;
1358
1359 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
1360 gimple *repl = gimple_build_assign (lhs, dest);
1361 gsi_replace (gsi, repl, false);
1362 return true;
1363}
1364
1365/* Transform a call to built-in bcmp(a, b, len) at *GSI into one
1366 to built-in memcmp (a, b, len). */
1367
1368static bool
1369gimple_fold_builtin_bcmp (gimple_stmt_iterator *gsi)
1370{
1371 tree fn = builtin_decl_implicit (BUILT_IN_MEMCMP);
1372
1373 if (!fn)
1374 return false;
1375
1376 /* Transform bcmp (a, b, len) into memcmp (a, b, len). */
1377
1378 gimple *stmt = gsi_stmt (*gsi);
1379 tree a = gimple_call_arg (stmt, 0);
1380 tree b = gimple_call_arg (stmt, 1);
1381 tree len = gimple_call_arg (stmt, 2);
1382
1383 gimple *repl = gimple_build_call (fn, 3, a, b, len);
1384 replace_call_with_call_and_fold (gsi, repl);
1385
1386 return true;
1387}
1388
1389/* Transform a call to built-in bcopy (src, dest, len) at *GSI into one
1390 to built-in memmove (dest, src, len). */
1391
1392static bool
1393gimple_fold_builtin_bcopy (gimple_stmt_iterator *gsi)
1394{
1395 tree fn = builtin_decl_implicit (BUILT_IN_MEMMOVE);
1396
1397 if (!fn)
1398 return false;
1399
1400 /* bcopy has been removed from POSIX in Issue 7 but Issue 6 specifies
1401 it's quivalent to memmove (not memcpy). Transform bcopy (src, dest,
1402 len) into memmove (dest, src, len). */
1403
1404 gimple *stmt = gsi_stmt (*gsi);
1405 tree src = gimple_call_arg (stmt, 0);
1406 tree dest = gimple_call_arg (stmt, 1);
1407 tree len = gimple_call_arg (stmt, 2);
1408
1409 gimple *repl = gimple_build_call (fn, 3, dest, src, len);
1410 gimple_call_set_fntype (as_a <gcall *> (stmt), TREE_TYPE (fn)((contains_struct_check ((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1410, __FUNCTION__))->typed.type)
);
1411 replace_call_with_call_and_fold (gsi, repl);
1412
1413 return true;
1414}
1415
1416/* Transform a call to built-in bzero (dest, len) at *GSI into one
1417 to built-in memset (dest, 0, len). */
1418
1419static bool
1420gimple_fold_builtin_bzero (gimple_stmt_iterator *gsi)
1421{
1422 tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
1423
1424 if (!fn)
1425 return false;
1426
1427 /* Transform bzero (dest, len) into memset (dest, 0, len). */
1428
1429 gimple *stmt = gsi_stmt (*gsi);
1430 tree dest = gimple_call_arg (stmt, 0);
1431 tree len = gimple_call_arg (stmt, 1);
1432
1433 gimple_seq seq = NULL__null;
1434 gimple *repl = gimple_build_call (fn, 3, dest, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO], len);
1435 gimple_seq_add_stmt_without_update (&seq, repl);
1436 gsi_replace_with_seq_vops (gsi, seq);
1437 fold_stmt (gsi);
1438
1439 return true;
1440}
1441
1442/* Fold function call to builtin memset or bzero at *GSI setting the
1443 memory of size LEN to VAL. Return whether a simplification was made. */
1444
1445static bool
1446gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
1447{
1448 gimple *stmt = gsi_stmt (*gsi);
1449 tree etype;
1450 unsigned HOST_WIDE_INTlong length, cval;
1451
1452 /* If the LEN parameter is zero, return DEST. */
1453 if (integer_zerop (len))
1454 {
1455 replace_call_with_value (gsi, gimple_call_arg (stmt, 0));
1456 return true;
1457 }
1458
1459 if (! tree_fits_uhwi_p (len))
1460 return false;
1461
1462 if (TREE_CODE (c)((enum tree_code) (c)->base.code) != INTEGER_CST)
1463 return false;
1464
1465 tree dest = gimple_call_arg (stmt, 0);
1466 tree var = dest;
1467 if (TREE_CODE (var)((enum tree_code) (var)->base.code) != ADDR_EXPR)
1468 return false;
1469
1470 var = TREE_OPERAND (var, 0)(*((const_cast<tree*> (tree_operand_check ((var), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1470, __FUNCTION__)))))
;
1471 if (TREE_THIS_VOLATILE (var)((var)->base.volatile_flag))
1472 return false;
1473
1474 etype = TREE_TYPE (var)((contains_struct_check ((var), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1474, __FUNCTION__))->typed.type)
;
1475 if (TREE_CODE (etype)((enum tree_code) (etype)->base.code) == ARRAY_TYPE)
1476 etype = TREE_TYPE (etype)((contains_struct_check ((etype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1476, __FUNCTION__))->typed.type)
;
1477
1478 if (!INTEGRAL_TYPE_P (etype)(((enum tree_code) (etype)->base.code) == ENUMERAL_TYPE ||
((enum tree_code) (etype)->base.code) == BOOLEAN_TYPE || (
(enum tree_code) (etype)->base.code) == INTEGER_TYPE)
1479 && !POINTER_TYPE_P (etype)(((enum tree_code) (etype)->base.code) == POINTER_TYPE || (
(enum tree_code) (etype)->base.code) == REFERENCE_TYPE)
)
1480 return NULL_TREE(tree) __null;
1481
1482 if (! var_decl_component_p (var))
1483 return NULL_TREE(tree) __null;
1484
1485 length = tree_to_uhwi (len);
1486 if (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (etype)(as_a <scalar_int_mode> ((tree_class_check ((etype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1486, __FUNCTION__))->type_common.mode))
) != length
1487 || (GET_MODE_PRECISION (SCALAR_INT_TYPE_MODE (etype)(as_a <scalar_int_mode> ((tree_class_check ((etype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1487, __FUNCTION__))->type_common.mode))
)
1488 != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (etype)(as_a <scalar_int_mode> ((tree_class_check ((etype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1488, __FUNCTION__))->type_common.mode))
))
1489 || get_pointer_alignment (dest) / BITS_PER_UNIT(8) < length)
1490 return NULL_TREE(tree) __null;
1491
1492 if (length > HOST_BITS_PER_WIDE_INT64 / BITS_PER_UNIT(8))
1493 return NULL_TREE(tree) __null;
1494
1495 if (!type_has_mode_precision_p (etype))
1496 etype = lang_hooks.types.type_for_mode (SCALAR_INT_TYPE_MODE (etype)(as_a <scalar_int_mode> ((tree_class_check ((etype), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1496, __FUNCTION__))->type_common.mode))
,
1497 TYPE_UNSIGNED (etype)((tree_class_check ((etype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1497, __FUNCTION__))->base.u.bits.unsigned_flag)
);
1498
1499 if (integer_zerop (c))
1500 cval = 0;
1501 else
1502 {
1503 if (CHAR_BIT8 != 8 || BITS_PER_UNIT(8) != 8 || HOST_BITS_PER_WIDE_INT64 > 64)
1504 return NULL_TREE(tree) __null;
1505
1506 cval = TREE_INT_CST_LOW (c)((unsigned long) (*tree_int_cst_elt_check ((c), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1506, __FUNCTION__)))
;
1507 cval &= 0xff;
1508 cval |= cval << 8;
1509 cval |= cval << 16;
1510 cval |= (cval << 31) << 1;
1511 }
1512
1513 var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0))fold_build2_loc (((location_t) 0), MEM_REF, etype, dest, build_int_cst
(global_trees[TI_PTR_TYPE], 0) )
;
1514 gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
1515 gimple_move_vops (store, stmt);
1516 gimple_set_location (store, gimple_location (stmt));
1517 gsi_insert_before (gsi, store, GSI_SAME_STMT);
1518 if (gimple_call_lhs (stmt))
1519 {
1520 gimple *asgn = gimple_build_assign (gimple_call_lhs (stmt), dest);
1521 gsi_replace (gsi, asgn, false);
1522 }
1523 else
1524 {
1525 gimple_stmt_iterator gsi2 = *gsi;
1526 gsi_prev (gsi);
1527 gsi_remove (&gsi2, true);
1528 }
1529
1530 return true;
1531}
1532
1533/* Helper of get_range_strlen for ARG that is not an SSA_NAME. */
1534
1535static bool
1536get_range_strlen_tree (tree arg, bitmap visited, strlen_range_kind rkind,
1537 c_strlen_data *pdata, unsigned eltsize)
1538{
1539 gcc_assert (TREE_CODE (arg) != SSA_NAME)((void)(!(((enum tree_code) (arg)->base.code) != SSA_NAME)
? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1539, __FUNCTION__), 0 : 0))
;
1540
1541 /* The length computed by this invocation of the function. */
1542 tree val = NULL_TREE(tree) __null;
1543
1544 /* True if VAL is an optimistic (tight) bound determined from
1545 the size of the character array in which the string may be
1546 stored. In that case, the computed VAL is used to set
1547 PDATA->MAXBOUND. */
1548 bool tight_bound = false;
1549
1550 /* We can end up with &(*iftmp_1)[0] here as well, so handle it. */
1551 if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == ADDR_EXPR
1552 && TREE_CODE (TREE_OPERAND (arg, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1552, __FUNCTION__))))))->base.code)
== ARRAY_REF)
1553 {
1554 tree op = TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1554, __FUNCTION__)))))
;
1555 if (integer_zerop (TREE_OPERAND (op, 1)(*((const_cast<tree*> (tree_operand_check ((op), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1555, __FUNCTION__)))))
))
1556 {
1557 tree aop0 = TREE_OPERAND (op, 0)(*((const_cast<tree*> (tree_operand_check ((op), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1557, __FUNCTION__)))))
;
1558 if (TREE_CODE (aop0)((enum tree_code) (aop0)->base.code) == INDIRECT_REF
1559 && TREE_CODE (TREE_OPERAND (aop0, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((aop0), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1559, __FUNCTION__))))))->base.code)
== SSA_NAME)
1560 return get_range_strlen (TREE_OPERAND (aop0, 0)(*((const_cast<tree*> (tree_operand_check ((aop0), (0),
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1560, __FUNCTION__)))))
, visited, rkind,
1561 pdata, eltsize);
1562 }
1563 else if (TREE_CODE (TREE_OPERAND (op, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((op), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1563, __FUNCTION__))))))->base.code)
== COMPONENT_REF
1564 && rkind == SRK_LENRANGE)
1565 {
1566 /* Fail if an array is the last member of a struct object
1567 since it could be treated as a (fake) flexible array
1568 member. */
1569 tree idx = TREE_OPERAND (op, 1)(*((const_cast<tree*> (tree_operand_check ((op), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1569, __FUNCTION__)))))
;
1570
1571 arg = TREE_OPERAND (op, 0)(*((const_cast<tree*> (tree_operand_check ((op), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1571, __FUNCTION__)))))
;
1572 tree optype = TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1572, __FUNCTION__))->typed.type)
;
1573 if (tree dom = TYPE_DOMAIN (optype)((tree_check ((optype), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1573, __FUNCTION__, (ARRAY_TYPE)))->type_non_common.values
)
)
1574 if (tree bound = TYPE_MAX_VALUE (dom)((tree_check5 ((dom), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1574, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE
), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval
)
)
1575 if (TREE_CODE (bound)((enum tree_code) (bound)->base.code) == INTEGER_CST
1576 && TREE_CODE (idx)((enum tree_code) (idx)->base.code) == INTEGER_CST
1577 && tree_int_cst_lt (bound, idx))
1578 return false;
1579 }
1580 }
1581
1582 if (rkind == SRK_INT_VALUE)
1583 {
1584 /* We are computing the maximum value (not string length). */
1585 val = arg;
1586 if (TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST
1587 || tree_int_cst_sgn (val) < 0)
1588 return false;
1589 }
1590 else
1591 {
1592 c_strlen_data lendata = { };
1593 val = c_strlen (arg, 1, &lendata, eltsize);
1594
1595 if (!val && lendata.decl)
1596 {
1597 /* ARG refers to an unterminated const character array.
1598 DATA.DECL with size DATA.LEN. */
1599 val = lendata.minlen;
1600 pdata->decl = lendata.decl;
1601 }
1602 }
1603
1604 /* Set if VAL represents the maximum length based on array size (set
1605 when exact length cannot be determined). */
1606 bool maxbound = false;
1607
1608 if (!val && rkind == SRK_LENRANGE)
1609 {
1610 if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == ADDR_EXPR)
1611 return get_range_strlen (TREE_OPERAND (arg, 0)(*((const_cast<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1611, __FUNCTION__)))))
, visited, rkind,
1612 pdata, eltsize);
1613
1614 if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == ARRAY_REF)
1615 {
1616 tree optype = TREE_TYPE (TREE_OPERAND (arg, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1616, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1616, __FUNCTION__))->typed.type)
;
1617
1618 /* Determine the "innermost" array type. */
1619 while (TREE_CODE (optype)((enum tree_code) (optype)->base.code) == ARRAY_TYPE
1620 && TREE_CODE (TREE_TYPE (optype))((enum tree_code) (((contains_struct_check ((optype), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1620, __FUNCTION__))->typed.type))->base.code)
== ARRAY_TYPE)
1621 optype = TREE_TYPE (optype)((contains_struct_check ((optype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1621, __FUNCTION__))->typed.type)
;
1622
1623 /* Avoid arrays of pointers. */
1624 tree eltype = TREE_TYPE (optype)((contains_struct_check ((optype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1624, __FUNCTION__))->typed.type)
;
1625 if (TREE_CODE (optype)((enum tree_code) (optype)->base.code) != ARRAY_TYPE
1626 || !INTEGRAL_TYPE_P (eltype)(((enum tree_code) (eltype)->base.code) == ENUMERAL_TYPE ||
((enum tree_code) (eltype)->base.code) == BOOLEAN_TYPE ||
((enum tree_code) (eltype)->base.code) == INTEGER_TYPE)
)
1627 return false;
1628
1629 /* Fail when the array bound is unknown or zero. */
1630 val = TYPE_SIZE_UNIT (optype)((tree_class_check ((optype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1630, __FUNCTION__))->type_common.size_unit)
;
1631 if (!val
1632 || TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST
1633 || integer_zerop (val))
1634 return false;
1635
1636 val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1636, __FUNCTION__))->typed.type), val, global_trees[TI_INTEGER_ONE
] )
1637 integer_one_node)fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1636, __FUNCTION__))->typed.type), val, global_trees[TI_INTEGER_ONE
] )
;
1638
1639 /* Set the minimum size to zero since the string in
1640 the array could have zero length. */
1641 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1642
1643 tight_bound = true;
1644 }
1645 else if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == COMPONENT_REF
1646 && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1)))((enum tree_code) (((contains_struct_check (((*((const_cast<
tree*> (tree_operand_check ((arg), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1646, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1646, __FUNCTION__))->typed.type))->base.code)
1647 == ARRAY_TYPE))
1648 {
1649 /* Use the type of the member array to determine the upper
1650 bound on the length of the array. This may be overly
1651 optimistic if the array itself isn't NUL-terminated and
1652 the caller relies on the subsequent member to contain
1653 the NUL but that would only be considered valid if
1654 the array were the last member of a struct. */
1655
1656 tree fld = TREE_OPERAND (arg, 1)(*((const_cast<tree*> (tree_operand_check ((arg), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1656, __FUNCTION__)))))
;
1657
1658 tree optype = TREE_TYPE (fld)((contains_struct_check ((fld), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1658, __FUNCTION__))->typed.type)
;
1659
1660 /* Determine the "innermost" array type. */
1661 while (TREE_CODE (optype)((enum tree_code) (optype)->base.code) == ARRAY_TYPE
1662 && TREE_CODE (TREE_TYPE (optype))((enum tree_code) (((contains_struct_check ((optype), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1662, __FUNCTION__))->typed.type))->base.code)
== ARRAY_TYPE)
1663 optype = TREE_TYPE (optype)((contains_struct_check ((optype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1663, __FUNCTION__))->typed.type)
;
1664
1665 /* Fail when the array bound is unknown or zero. */
1666 val = TYPE_SIZE_UNIT (optype)((tree_class_check ((optype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1666, __FUNCTION__))->type_common.size_unit)
;
1667 if (!val
1668 || TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST
1669 || integer_zerop (val))
1670 return false;
1671 val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1671, __FUNCTION__))->typed.type), val, global_trees[TI_INTEGER_ONE
] )
1672 integer_one_node)fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1671, __FUNCTION__))->typed.type), val, global_trees[TI_INTEGER_ONE
] )
;
1673
1674 /* Set the minimum size to zero since the string in
1675 the array could have zero length. */
1676 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1677
1678 /* The array size determined above is an optimistic bound
1679 on the length. If the array isn't nul-terminated the
1680 length computed by the library function would be greater.
1681 Even though using strlen to cross the subobject boundary
1682 is undefined, avoid drawing conclusions from the member
1683 type about the length here. */
1684 tight_bound = true;
1685 }
1686 else if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == MEM_REF
1687 && TREE_CODE (TREE_TYPE (arg))((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1687, __FUNCTION__))->typed.type))->base.code)
== ARRAY_TYPE
1688 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg)))((enum tree_code) (((contains_struct_check ((((contains_struct_check
((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1688, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1688, __FUNCTION__))->typed.type))->base.code)
== INTEGER_TYPE
1689 && TREE_CODE (TREE_OPERAND (arg, 0))((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1689, __FUNCTION__))))))->base.code)
== ADDR_EXPR)
1690 {
1691 /* Handle a MEM_REF into a DECL accessing an array of integers,
1692 being conservative about references to extern structures with
1693 flexible array members that can be initialized to arbitrary
1694 numbers of elements as an extension (static structs are okay). */
1695 tree ref = TREE_OPERAND (TREE_OPERAND (arg, 0), 0)(*((const_cast<tree*> (tree_operand_check (((*((const_cast
<tree*> (tree_operand_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1695, __FUNCTION__)))))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1695, __FUNCTION__)))))
;
1696 if ((TREE_CODE (ref)((enum tree_code) (ref)->base.code) == PARM_DECL || VAR_P (ref)(((enum tree_code) (ref)->base.code) == VAR_DECL))
1697 && (decl_binds_to_current_def_p (ref)
1698 || !array_ref_flexible_size_p (arg)))
1699 {
1700 /* Fail if the offset is out of bounds. Such accesses
1701 should be diagnosed at some point. */
1702 val = DECL_SIZE_UNIT (ref)((contains_struct_check ((ref), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1702, __FUNCTION__))->decl_common.size_unit)
;
1703 if (!val
1704 || TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST
1705 || integer_zerop (val))
1706 return false;
1707
1708 poly_offset_int psiz = wi::to_offset (val);
1709 poly_offset_int poff = mem_ref_offset (arg);
1710 if (known_le (psiz, poff)(!maybe_lt (poff, psiz)))
1711 return false;
1712
1713 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1714
1715 /* Subtract the offset and one for the terminating nul. */
1716 psiz -= poff;
1717 psiz -= 1;
1718 val = wide_int_to_tree (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1718, __FUNCTION__))->typed.type)
, psiz);
1719 /* Since VAL reflects the size of a declared object
1720 rather the type of the access it is not a tight bound. */
1721 }
1722 }
1723 else if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) == PARM_DECL || VAR_P (arg)(((enum tree_code) (arg)->base.code) == VAR_DECL))
1724 {
1725 /* Avoid handling pointers to arrays. GCC might misuse
1726 a pointer to an array of one bound to point to an array
1727 object of a greater bound. */
1728 tree argtype = TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1728, __FUNCTION__))->typed.type)
;
1729 if (TREE_CODE (argtype)((enum tree_code) (argtype)->base.code) == ARRAY_TYPE)
1730 {
1731 val = TYPE_SIZE_UNIT (argtype)((tree_class_check ((argtype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1731, __FUNCTION__))->type_common.size_unit)
;
1732 if (!val
1733 || TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST
1734 || integer_zerop (val))
1735 return false;
1736 val = wide_int_to_tree (TREE_TYPE (val)((contains_struct_check ((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1736, __FUNCTION__))->typed.type)
,
1737 wi::sub (wi::to_wide (val), 1));
1738
1739 /* Set the minimum size to zero since the string in
1740 the array could have zero length. */
1741 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1742 }
1743 }
1744 maxbound = true;
1745 }
1746
1747 if (!val)
1748 return false;
1749
1750 /* Adjust the lower bound on the string length as necessary. */
1751 if (!pdata->minlen
1752 || (rkind != SRK_STRLEN
1753 && TREE_CODE (pdata->minlen)((enum tree_code) (pdata->minlen)->base.code) == INTEGER_CST
1754 && TREE_CODE (val)((enum tree_code) (val)->base.code) == INTEGER_CST
1755 && tree_int_cst_lt (val, pdata->minlen)))
1756 pdata->minlen = val;
1757
1758 if (pdata->maxbound && TREE_CODE (pdata->maxbound)((enum tree_code) (pdata->maxbound)->base.code) == INTEGER_CST)
1759 {
1760 /* Adjust the tighter (more optimistic) string length bound
1761 if necessary and proceed to adjust the more conservative
1762 bound. */
1763 if (TREE_CODE (val)((enum tree_code) (val)->base.code) == INTEGER_CST)
1764 {
1765 if (tree_int_cst_lt (pdata->maxbound, val))
1766 pdata->maxbound = val;
1767 }
1768 else
1769 pdata->maxbound = val;
1770 }
1771 else if (pdata->maxbound || maxbound)
1772 /* Set PDATA->MAXBOUND only if it either isn't INTEGER_CST or
1773 if VAL corresponds to the maximum length determined based
1774 on the type of the object. */
1775 pdata->maxbound = val;
1776
1777 if (tight_bound)
1778 {
1779 /* VAL computed above represents an optimistically tight bound
1780 on the length of the string based on the referenced object's
1781 or subobject's type. Determine the conservative upper bound
1782 based on the enclosing object's size if possible. */
1783 if (rkind == SRK_LENRANGE)
1784 {
1785 poly_int64 offset;
1786 tree base = get_addr_base_and_unit_offset (arg, &offset);
1787 if (!base)
1788 {
1789 /* When the call above fails due to a non-constant offset
1790 assume the offset is zero and use the size of the whole
1791 enclosing object instead. */
1792 base = get_base_address (arg);
1793 offset = 0;
1794 }
1795 /* If the base object is a pointer no upper bound on the length
1796 can be determined. Otherwise the maximum length is equal to
1797 the size of the enclosing object minus the offset of
1798 the referenced subobject minus 1 (for the terminating nul). */
1799 tree type = TREE_TYPE (base)((contains_struct_check ((base), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1799, __FUNCTION__))->typed.type)
;
1800 if (TREE_CODE (type)((enum tree_code) (type)->base.code) == POINTER_TYPE
1801 || (TREE_CODE (base)((enum tree_code) (base)->base.code) != PARM_DECL && !VAR_P (base)(((enum tree_code) (base)->base.code) == VAR_DECL))
1802 || !(val = DECL_SIZE_UNIT (base)((contains_struct_check ((base), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1802, __FUNCTION__))->decl_common.size_unit)
))
Although the value stored to 'val' is used in the enclosing expression, the value is never actually read from 'val'
1803 val = build_all_ones_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
1804 else
1805 {
1806 val = DECL_SIZE_UNIT (base)((contains_struct_check ((base), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1806, __FUNCTION__))->decl_common.size_unit)
;
1807 val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val,fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1807, __FUNCTION__))->typed.type), val, size_int_kind (offset
+ 1, stk_sizetype) )
1808 size_int (offset + 1))fold_build2_loc (((location_t) 0), MINUS_EXPR, ((contains_struct_check
((val), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1807, __FUNCTION__))->typed.type), val, size_int_kind (offset
+ 1, stk_sizetype) )
;
1809 }
1810 }
1811 else
1812 return false;
1813 }
1814
1815 if (pdata->maxlen)
1816 {
1817 /* Adjust the more conservative bound if possible/necessary
1818 and fail otherwise. */
1819 if (rkind != SRK_STRLEN)
1820 {
1821 if (TREE_CODE (pdata->maxlen)((enum tree_code) (pdata->maxlen)->base.code) != INTEGER_CST
1822 || TREE_CODE (val)((enum tree_code) (val)->base.code) != INTEGER_CST)
1823 return false;
1824
1825 if (tree_int_cst_lt (pdata->maxlen, val))
1826 pdata->maxlen = val;
1827 return true;
1828 }
1829 else if (simple_cst_equal (val, pdata->maxlen) != 1)
1830 {
1831 /* Fail if the length of this ARG is different from that
1832 previously determined from another ARG. */
1833 return false;
1834 }
1835 }
1836
1837 pdata->maxlen = val;
1838 return rkind == SRK_LENRANGE || !integer_all_onesp (val);
1839}
1840
1841/* For an ARG referencing one or more strings, try to obtain the range
1842 of their lengths, or the size of the largest array ARG referes to if
1843 the range of lengths cannot be determined, and store all in *PDATA.
1844 For an integer ARG (when RKIND == SRK_INT_VALUE), try to determine
1845 the maximum constant value.
1846 If ARG is an SSA_NAME, follow its use-def chains. When RKIND ==
1847 SRK_STRLEN, then if PDATA->MAXLEN is not equal to the determined
1848 length or if we are unable to determine the length, return false.
1849 VISITED is a bitmap of visited variables.
1850 RKIND determines the kind of value or range to obtain (see
1851 strlen_range_kind).
1852 Set PDATA->DECL if ARG refers to an unterminated constant array.
1853 On input, set ELTSIZE to 1 for normal single byte character strings,
1854 and either 2 or 4 for wide characer strings (the size of wchar_t).
1855 Return true if *PDATA was successfully populated and false otherwise. */
1856
1857static bool
1858get_range_strlen (tree arg, bitmap visited,
1859 strlen_range_kind rkind,
1860 c_strlen_data *pdata, unsigned eltsize)
1861{
1862
1863 if (TREE_CODE (arg)((enum tree_code) (arg)->base.code) != SSA_NAME)
1864 return get_range_strlen_tree (arg, visited, rkind, pdata, eltsize);
1865
1866 /* If ARG is registered for SSA update we cannot look at its defining
1867 statement. */
1868 if (name_registered_for_update_p (arg))
1869 return false;
1870
1871 /* If we were already here, break the infinite cycle. */
1872 if (!bitmap_set_bit (visited, SSA_NAME_VERSION (arg)(tree_check ((arg), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1872, __FUNCTION__, (SSA_NAME)))->base.u.version
))
1873 return true;
1874
1875 tree var = arg;
1876 gimple *def_stmt = SSA_NAME_DEF_STMT (var)(tree_check ((var), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 1876, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
;
1877
1878 switch (gimple_code (def_stmt))
1879 {
1880 case GIMPLE_ASSIGN:
1881 /* The RHS of the statement defining VAR must either have a
1882 constant length or come from another SSA_NAME with a constant
1883 length. */
1884 if (gimple_assign_single_p (def_stmt)
1885 || gimple_assign_unary_nop_p (def_stmt))
1886 {
1887 tree rhs = gimple_assign_rhs1 (def_stmt);
1888 return get_range_strlen (rhs, visited, rkind, pdata, eltsize);
1889 }
1890 else if (gimple_assign_rhs_code (def_stmt) == COND_EXPR)
1891 {
1892 tree ops[2] = { gimple_assign_rhs2 (def_stmt),
1893 gimple_assign_rhs3 (def_stmt) };
1894
1895 for (unsigned int i = 0; i < 2; i++)
1896 if (!get_range_strlen (ops[i], visited, rkind, pdata, eltsize))
1897 {
1898 if (rkind != SRK_LENRANGE)
1899 return false;
1900 /* Set the upper bound to the maximum to prevent
1901 it from being adjusted in the next iteration but
1902 leave MINLEN and the more conservative MAXBOUND
1903 determined so far alone (or leave them null if
1904 they haven't been set yet). That the MINLEN is
1905 in fact zero can be determined from MAXLEN being
1906 unbounded but the discovered minimum is used for
1907 diagnostics. */
1908 pdata->maxlen = build_all_ones_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
1909 }
1910 return true;
1911 }
1912 return false;
1913
1914 case GIMPLE_PHI:
1915 /* Unless RKIND == SRK_LENRANGE, all arguments of the PHI node
1916 must have a constant length. */
1917 for (unsigned i = 0; i < gimple_phi_num_args (def_stmt); i++)
1918 {
1919 tree arg = gimple_phi_arg (def_stmt, i)->def;
1920
1921 /* If this PHI has itself as an argument, we cannot
1922 determine the string length of this argument. However,
1923 if we can find a constant string length for the other
1924 PHI args then we can still be sure that this is a
1925 constant string length. So be optimistic and just
1926 continue with the next argument. */
1927 if (arg == gimple_phi_result (def_stmt))
1928 continue;
1929
1930 if (!get_range_strlen (arg, visited, rkind, pdata, eltsize))
1931 {
1932 if (rkind != SRK_LENRANGE)
1933 return false;
1934 /* Set the upper bound to the maximum to prevent
1935 it from being adjusted in the next iteration but
1936 leave MINLEN and the more conservative MAXBOUND
1937 determined so far alone (or leave them null if
1938 they haven't been set yet). That the MINLEN is
1939 in fact zero can be determined from MAXLEN being
1940 unbounded but the discovered minimum is used for
1941 diagnostics. */
1942 pdata->maxlen = build_all_ones_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
1943 }
1944 }
1945 return true;
1946
1947 default:
1948 return false;
1949 }
1950}
1951
1952/* Try to obtain the range of the lengths of the string(s) referenced
1953 by ARG, or the size of the largest array ARG refers to if the range
1954 of lengths cannot be determined, and store all in *PDATA which must
1955 be zero-initialized on input except PDATA->MAXBOUND may be set to
1956 a non-null tree node other than INTEGER_CST to request to have it
1957 set to the length of the longest string in a PHI. ELTSIZE is
1958 the expected size of the string element in bytes: 1 for char and
1959 some power of 2 for wide characters.
1960 Return true if the range [PDATA->MINLEN, PDATA->MAXLEN] is suitable
1961 for optimization. Returning false means that a nonzero PDATA->MINLEN
1962 doesn't reflect the true lower bound of the range when PDATA->MAXLEN
1963 is -1 (in that case, the actual range is indeterminate, i.e.,
1964 [0, PTRDIFF_MAX - 2]. */
1965
1966bool
1967get_range_strlen (tree arg, c_strlen_data *pdata, unsigned eltsize)
1968{
1969 auto_bitmap visited;
1970 tree maxbound = pdata->maxbound;
1971
1972 if (!get_range_strlen (arg, visited, SRK_LENRANGE, pdata, eltsize))
1973 {
1974 /* On failure extend the length range to an impossible maximum
1975 (a valid MAXLEN must be less than PTRDIFF_MAX - 1). Other
1976 members can stay unchanged regardless. */
1977 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1978 pdata->maxlen = build_all_ones_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
1979 }
1980 else if (!pdata->minlen)
1981 pdata->minlen = ssize_int (0)size_int_kind (0, stk_ssizetype);
1982
1983 /* If it's unchanged from it initial non-null value, set the conservative
1984 MAXBOUND to SIZE_MAX. Otherwise leave it null (if it is null). */
1985 if (maxbound && pdata->maxbound == maxbound)
1986 pdata->maxbound = build_all_ones_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
1987
1988 return !integer_all_onesp (pdata->maxlen);
1989}
1990
1991/* Return the maximum value for ARG given RKIND (see strlen_range_kind).
1992 For ARG of pointer types, NONSTR indicates if the caller is prepared
1993 to handle unterminated strings. For integer ARG and when RKIND ==
1994 SRK_INT_VALUE, NONSTR must be null.
1995
1996 If an unterminated array is discovered and our caller handles
1997 unterminated arrays, then bubble up the offending DECL and
1998 return the maximum size. Otherwise return NULL. */
1999
2000static tree
2001get_maxval_strlen (tree arg, strlen_range_kind rkind, tree *nonstr = NULL__null)
2002{
2003 /* A non-null NONSTR is meaningless when determining the maximum
2004 value of an integer ARG. */
2005 gcc_assert (rkind != SRK_INT_VALUE || nonstr == NULL)((void)(!(rkind != SRK_INT_VALUE || nonstr == __null) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2005, __FUNCTION__), 0 : 0))
;
2006 /* ARG must have an integral type when RKIND says so. */
2007 gcc_assert (rkind != SRK_INT_VALUE || INTEGRAL_TYPE_P (TREE_TYPE (arg)))((void)(!(rkind != SRK_INT_VALUE || (((enum tree_code) (((contains_struct_check
((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2007, __FUNCTION__))->typed.type))->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2007, __FUNCTION__))->typed.type))->base.code) == BOOLEAN_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2007, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2007, __FUNCTION__), 0 : 0))
;
2008
2009 auto_bitmap visited;
2010
2011 /* Reset DATA.MAXLEN if the call fails or when DATA.MAXLEN
2012 is unbounded. */
2013 c_strlen_data lendata = { };
2014 if (!get_range_strlen (arg, visited, rkind, &lendata, /* eltsize = */1))
2015 lendata.maxlen = NULL_TREE(tree) __null;
2016 else if (lendata.maxlen && integer_all_onesp (lendata.maxlen))
2017 lendata.maxlen = NULL_TREE(tree) __null;
2018
2019 if (nonstr)
2020 {
2021 /* For callers prepared to handle unterminated arrays set
2022 *NONSTR to point to the declaration of the array and return
2023 the maximum length/size. */
2024 *nonstr = lendata.decl;
2025 return lendata.maxlen;
2026 }
2027
2028 /* Fail if the constant array isn't nul-terminated. */
2029 return lendata.decl ? NULL_TREE(tree) __null : lendata.maxlen;
2030}
2031
2032/* Return true if LEN is known to be less than or equal to (or if STRICT is
2033 true, strictly less than) the lower bound of SIZE at compile time and false
2034 otherwise. */
2035
2036static bool
2037known_lower (gimple *stmt, tree len, tree size, bool strict = false)
2038{
2039 if (len == NULL_TREE(tree) __null)
2040 return false;
2041
2042 wide_int size_range[2];
2043 wide_int len_range[2];
2044 if (get_range (len, stmt, len_range) && get_range (size, stmt, size_range))
2045 {
2046 if (strict)
2047 return wi::ltu_p (len_range[1], size_range[0]);
2048 else
2049 return wi::leu_p (len_range[1], size_range[0]);
2050 }
2051
2052 return false;
2053}
2054
2055/* Fold function call to builtin strcpy with arguments DEST and SRC.
2056 If LEN is not NULL, it represents the length of the string to be
2057 copied. Return NULL_TREE if no simplification can be made. */
2058
2059static bool
2060gimple_fold_builtin_strcpy (gimple_stmt_iterator *gsi,
2061 tree dest, tree src)
2062{
2063 gimple *stmt = gsi_stmt (*gsi);
2064 location_t loc = gimple_location (stmt);
2065 tree fn;
2066
2067 /* If SRC and DEST are the same (and not volatile), return DEST. */
2068 if (operand_equal_p (src, dest, 0))
2069 {
2070 /* Issue -Wrestrict unless the pointers are null (those do
2071 not point to objects and so do not indicate an overlap;
2072 such calls could be the result of sanitization and jump
2073 threading). */
2074 if (!integer_zerop (dest) && !warning_suppressed_p (stmt, OPT_Wrestrict))
2075 {
2076 tree func = gimple_call_fndecl (stmt);
2077
2078 warning_at (loc, OPT_Wrestrict,
2079 "%qD source argument is the same as destination",
2080 func);
2081 }
2082
2083 replace_call_with_value (gsi, dest);
2084 return true;
2085 }
2086
2087 if (optimize_function_for_size_p (cfun(cfun + 0)))
2088 return false;
2089
2090 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2091 if (!fn)
2092 return false;
2093
2094 /* Set to non-null if ARG refers to an unterminated array. */
2095 tree nonstr = NULL__null;
2096 tree len = get_maxval_strlen (src, SRK_STRLEN, &nonstr);
2097
2098 if (nonstr)
2099 {
2100 /* Avoid folding calls with unterminated arrays. */
2101 if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
2102 warn_string_no_nul (loc, stmt, "strcpy", src, nonstr);
2103 suppress_warning (stmt, OPT_Wstringop_overread);
2104 return false;
2105 }
2106
2107 if (!len)
2108 return false;
2109
2110 len = fold_convert_loc (loc, size_type_nodeglobal_trees[TI_SIZE_TYPE], len);
2111 len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], 1));
2112 len = force_gimple_operand_gsi (gsi, len, true,
2113 NULL_TREE(tree) __null, true, GSI_SAME_STMT);
2114 gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2115 replace_call_with_call_and_fold (gsi, repl);
2116 return true;
2117}
2118
2119/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
2120 If SLEN is not NULL, it represents the length of the source string.
2121 Return NULL_TREE if no simplification can be made. */
2122
2123static bool
2124gimple_fold_builtin_strncpy (gimple_stmt_iterator *gsi,
2125 tree dest, tree src, tree len)
2126{
2127 gimple *stmt = gsi_stmt (*gsi);
2128 location_t loc = gimple_location (stmt);
2129 bool nonstring = get_attr_nonstring_decl (dest) != NULL_TREE(tree) __null;
2130
2131 /* If the LEN parameter is zero, return DEST. */
2132 if (integer_zerop (len))
2133 {
2134 /* Avoid warning if the destination refers to an array/pointer
2135 decorate with attribute nonstring. */
2136 if (!nonstring)
2137 {
2138 tree fndecl = gimple_call_fndecl (stmt);
2139
2140 /* Warn about the lack of nul termination: the result is not
2141 a (nul-terminated) string. */
2142 tree slen = get_maxval_strlen (src, SRK_STRLEN);
2143 if (slen && !integer_zerop (slen))
2144 warning_at (loc, OPT_Wstringop_truncation,
2145 "%qD destination unchanged after copying no bytes "
2146 "from a string of length %E",
2147 fndecl, slen);
2148 else
2149 warning_at (loc, OPT_Wstringop_truncation,
2150 "%qD destination unchanged after copying no bytes",
2151 fndecl);
2152 }
2153
2154 replace_call_with_value (gsi, dest);
2155 return true;
2156 }
2157
2158 /* We can't compare slen with len as constants below if len is not a
2159 constant. */
2160 if (TREE_CODE (len)((enum tree_code) (len)->base.code) != INTEGER_CST)
2161 return false;
2162
2163 /* Now, we must be passed a constant src ptr parameter. */
2164 tree slen = get_maxval_strlen (src, SRK_STRLEN);
2165 if (!slen || TREE_CODE (slen)((enum tree_code) (slen)->base.code) != INTEGER_CST)
2166 return false;
2167
2168 /* The size of the source string including the terminating nul. */
2169 tree ssize = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1)size_int_kind (1, stk_ssizetype));
2170
2171 /* We do not support simplification of this case, though we do
2172 support it when expanding trees into RTL. */
2173 /* FIXME: generate a call to __builtin_memset. */
2174 if (tree_int_cst_lt (ssize, len))
2175 return false;
2176
2177 /* Diagnose truncation that leaves the copy unterminated. */
2178 maybe_diag_stxncpy_trunc (*gsi, src, len);
2179
2180 /* OK transform into builtin memcpy. */
2181 tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2182 if (!fn)
2183 return false;
2184
2185 len = fold_convert_loc (loc, size_type_nodeglobal_trees[TI_SIZE_TYPE], len);
2186 len = force_gimple_operand_gsi (gsi, len, true,
2187 NULL_TREE(tree) __null, true, GSI_SAME_STMT);
2188 gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2189 replace_call_with_call_and_fold (gsi, repl);
2190
2191 return true;
2192}
2193
2194/* Fold function call to builtin strchr or strrchr.
2195 If both arguments are constant, evaluate and fold the result,
2196 otherwise simplify str(r)chr (str, 0) into str + strlen (str).
2197 In general strlen is significantly faster than strchr
2198 due to being a simpler operation. */
2199static bool
2200gimple_fold_builtin_strchr (gimple_stmt_iterator *gsi, bool is_strrchr)
2201{
2202 gimple *stmt = gsi_stmt (*gsi);
2203 tree str = gimple_call_arg (stmt, 0);
2204 tree c = gimple_call_arg (stmt, 1);
2205 location_t loc = gimple_location (stmt);
2206 const char *p;
2207 char ch;
2208
2209 if (!gimple_call_lhs (stmt))
2210 return false;
2211
2212 /* Avoid folding if the first argument is not a nul-terminated array.
2213 Defer warning until later. */
2214 if (!check_nul_terminated_array (NULL_TREE(tree) __null, str))
2215 return false;
2216
2217 if ((p = c_getstr (str)) && target_char_cst_p (c, &ch))
2218 {
2219 const char *p1 = is_strrchr ? strrchr (p, ch) : strchr (p, ch);
2220
2221 if (p1 == NULL__null)
2222 {
2223 replace_call_with_value (gsi, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]);
2224 return true;
2225 }
2226
2227 tree len = build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], p1 - p);
2228 gimple_seq stmts = NULL__null;
2229 gimple *new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
2230 POINTER_PLUS_EXPR, str, len);
2231 gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2232 gsi_replace_with_seq_vops (gsi, stmts);
2233 return true;
2234 }
2235
2236 if (!integer_zerop (c))
2237 return false;
2238
2239 /* Transform strrchr (s, 0) to strchr (s, 0) when optimizing for size. */
2240 if (is_strrchr && optimize_function_for_size_p (cfun(cfun + 0)))
2241 {
2242 tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
2243
2244 if (strchr_fn)
2245 {
2246 gimple *repl = gimple_build_call (strchr_fn, 2, str, c);
2247 replace_call_with_call_and_fold (gsi, repl);
2248 return true;
2249 }
2250
2251 return false;
2252 }
2253
2254 tree len;
2255 tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2256
2257 if (!strlen_fn)
2258 return false;
2259
2260 /* Create newstr = strlen (str). */
2261 gimple_seq stmts = NULL__null;
2262 gimple *new_stmt = gimple_build_call (strlen_fn, 1, str);
2263 gimple_set_location (new_stmt, loc);
2264 len = create_tmp_reg_or_ssa_name (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
2265 gimple_call_set_lhs (new_stmt, len);
2266 gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2267
2268 /* Create (str p+ strlen (str)). */
2269 new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
2270 POINTER_PLUS_EXPR, str, len);
2271 gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2272 gsi_replace_with_seq_vops (gsi, stmts);
2273 /* gsi now points at the assignment to the lhs, get a
2274 stmt iterator to the strlen.
2275 ??? We can't use gsi_for_stmt as that doesn't work when the
2276 CFG isn't built yet. */
2277 gimple_stmt_iterator gsi2 = *gsi;
2278 gsi_prev (&gsi2);
2279 fold_stmt (&gsi2);
2280 return true;
2281}
2282
2283/* Fold function call to builtin strstr.
2284 If both arguments are constant, evaluate and fold the result,
2285 additionally fold strstr (x, "") into x and strstr (x, "c")
2286 into strchr (x, 'c'). */
2287static bool
2288gimple_fold_builtin_strstr (gimple_stmt_iterator *gsi)
2289{
2290 gimple *stmt = gsi_stmt (*gsi);
2291 if (!gimple_call_lhs (stmt))
2292 return false;
2293
2294 tree haystack = gimple_call_arg (stmt, 0);
2295 tree needle = gimple_call_arg (stmt, 1);
2296
2297 /* Avoid folding if either argument is not a nul-terminated array.
2298 Defer warning until later. */
2299 if (!check_nul_terminated_array (NULL_TREE(tree) __null, haystack)
2300 || !check_nul_terminated_array (NULL_TREE(tree) __null, needle))
2301 return false;
2302
2303 const char *q = c_getstr (needle);
2304 if (q == NULL__null)
2305 return false;
2306
2307 if (const char *p = c_getstr (haystack))
2308 {
2309 const char *r = strstr (p, q);
2310
2311 if (r == NULL__null)
2312 {
2313 replace_call_with_value (gsi, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]);
2314 return true;
2315 }
2316
2317 tree len = build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], r - p);
2318 gimple_seq stmts = NULL__null;
2319 gimple *new_stmt
2320 = gimple_build_assign (gimple_call_lhs (stmt), POINTER_PLUS_EXPR,
2321 haystack, len);
2322 gimple_seq_add_stmt_without_update (&stmts, new_stmt);
2323 gsi_replace_with_seq_vops (gsi, stmts);
2324 return true;
2325 }
2326
2327 /* For strstr (x, "") return x. */
2328 if (q[0] == '\0')
2329 {
2330 replace_call_with_value (gsi, haystack);
2331 return true;
2332 }
2333
2334 /* Transform strstr (x, "c") into strchr (x, 'c'). */
2335 if (q[1] == '\0')
2336 {
2337 tree strchr_fn = builtin_decl_implicit (BUILT_IN_STRCHR);
2338 if (strchr_fn)
2339 {
2340 tree c = build_int_cst (integer_type_nodeinteger_types[itk_int], q[0]);
2341 gimple *repl = gimple_build_call (strchr_fn, 2, haystack, c);
2342 replace_call_with_call_and_fold (gsi, repl);
2343 return true;
2344 }
2345 }
2346
2347 return false;
2348}
2349
2350/* Simplify a call to the strcat builtin. DST and SRC are the arguments
2351 to the call.
2352
2353 Return NULL_TREE if no simplification was possible, otherwise return the
2354 simplified form of the call as a tree.
2355
2356 The simplified form may be a constant or other expression which
2357 computes the same value, but in a more efficient manner (including
2358 calls to other builtin functions).
2359
2360 The call may contain arguments which need to be evaluated, but
2361 which are not useful to determine the result of the call. In
2362 this case we return a chain of COMPOUND_EXPRs. The LHS of each
2363 COMPOUND_EXPR will be an argument which must be evaluated.
2364 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
2365 COMPOUND_EXPR in the chain will contain the tree for the simplified
2366 form of the builtin function call. */
2367
2368static bool
2369gimple_fold_builtin_strcat (gimple_stmt_iterator *gsi, tree dst, tree src)
2370{
2371 gimple *stmt = gsi_stmt (*gsi);
2372 location_t loc = gimple_location (stmt);
2373
2374 const char *p = c_getstr (src);
2375
2376 /* If the string length is zero, return the dst parameter. */
2377 if (p && *p == '\0')
2378 {
2379 replace_call_with_value (gsi, dst);
2380 return true;
2381 }
2382
2383 if (!optimize_bb_for_speed_p (gimple_bb (stmt)))
2384 return false;
2385
2386 /* See if we can store by pieces into (dst + strlen(dst)). */
2387 tree newdst;
2388 tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
2389 tree memcpy_fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2390
2391 if (!strlen_fn || !memcpy_fn)
2392 return false;
2393
2394 /* If the length of the source string isn't computable don't
2395 split strcat into strlen and memcpy. */
2396 tree len = get_maxval_strlen (src, SRK_STRLEN);
2397 if (! len)
2398 return false;
2399
2400 /* Create strlen (dst). */
2401 gimple_seq stmts = NULL__null, stmts2;
2402 gimple *repl = gimple_build_call (strlen_fn, 1, dst);
2403 gimple_set_location (repl, loc);
2404 newdst = create_tmp_reg_or_ssa_name (size_type_nodeglobal_trees[TI_SIZE_TYPE]);
2405 gimple_call_set_lhs (repl, newdst);
2406 gimple_seq_add_stmt_without_update (&stmts, repl);
2407
2408 /* Create (dst p+ strlen (dst)). */
2409 newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
2410 newdst = force_gimple_operand (newdst, &stmts2, true, NULL_TREE(tree) __null);
2411 gimple_seq_add_seq_without_update (&stmts, stmts2);
2412
2413 len = fold_convert_loc (loc, size_type_nodeglobal_trees[TI_SIZE_TYPE], len);
2414 len = size_binop_loc (loc, PLUS_EXPR, len,
2415 build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], 1));
2416 len = force_gimple_operand (len, &stmts2, true, NULL_TREE(tree) __null);
2417 gimple_seq_add_seq_without_update (&stmts, stmts2);
2418
2419 repl = gimple_build_call (memcpy_fn, 3, newdst, src, len);
2420 gimple_seq_add_stmt_without_update (&stmts, repl);
2421 if (gimple_call_lhs (stmt))
2422 {
2423 repl = gimple_build_assign (gimple_call_lhs (stmt), dst);
2424 gimple_seq_add_stmt_without_update (&stmts, repl);
2425 gsi_replace_with_seq_vops (gsi, stmts);
2426 /* gsi now points at the assignment to the lhs, get a
2427 stmt iterator to the memcpy call.
2428 ??? We can't use gsi_for_stmt as that doesn't work when the
2429 CFG isn't built yet. */
2430 gimple_stmt_iterator gsi2 = *gsi;
2431 gsi_prev (&gsi2);
2432 fold_stmt (&gsi2);
2433 }
2434 else
2435 {
2436 gsi_replace_with_seq_vops (gsi, stmts);
2437 fold_stmt (gsi);
2438 }
2439 return true;
2440}
2441
2442/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
2443 are the arguments to the call. */
2444
2445static bool
2446gimple_fold_builtin_strcat_chk (gimple_stmt_iterator *gsi)
2447{
2448 gimple *stmt = gsi_stmt (*gsi);
2449 tree dest = gimple_call_arg (stmt, 0);
2450 tree src = gimple_call_arg (stmt, 1);
2451 tree size = gimple_call_arg (stmt, 2);
2452 tree fn;
2453 const char *p;
2454
2455
2456 p = c_getstr (src);
2457 /* If the SRC parameter is "", return DEST. */
2458 if (p && *p == '\0')
2459 {
2460 replace_call_with_value (gsi, dest);
2461 return true;
2462 }
2463
2464 if (! tree_fits_uhwi_p (size) || ! integer_all_onesp (size))
2465 return false;
2466
2467 /* If __builtin_strcat_chk is used, assume strcat is available. */
2468 fn = builtin_decl_explicit (BUILT_IN_STRCAT);
2469 if (!fn)
2470 return false;
2471
2472 gimple *repl = gimple_build_call (fn, 2, dest, src);
2473 replace_call_with_call_and_fold (gsi, repl);
2474 return true;
2475}
2476
2477/* Simplify a call to the strncat builtin. */
2478
2479static bool
2480gimple_fold_builtin_strncat (gimple_stmt_iterator *gsi)
2481{
2482 gimple *stmt = gsi_stmt (*gsi);
2483 tree dst = gimple_call_arg (stmt, 0);
2484 tree src = gimple_call_arg (stmt, 1);
2485 tree len = gimple_call_arg (stmt, 2);
2486 tree src_len = c_strlen (src, 1);
2487
2488 /* If the requested length is zero, or the src parameter string
2489 length is zero, return the dst parameter. */
2490 if (integer_zerop (len) || (src_len && integer_zerop (src_len)))
2491 {
2492 replace_call_with_value (gsi, dst);
2493 return true;
2494 }
2495
2496 /* Return early if the requested len is less than the string length.
2497 Warnings will be issued elsewhere later. */
2498 if (!src_len || known_lower (stmt, len, src_len, true))
2499 return false;
2500
2501 /* Warn on constant LEN. */
2502 if (TREE_CODE (len)((enum tree_code) (len)->base.code) == INTEGER_CST)
2503 {
2504 bool nowarn = warning_suppressed_p (stmt, OPT_Wstringop_overflow_);
2505 tree dstsize;
2506
2507 if (!nowarn && compute_builtin_object_size (dst, 1, &dstsize)
2508 && TREE_CODE (dstsize)((enum tree_code) (dstsize)->base.code) == INTEGER_CST)
2509 {
2510 int cmpdst = tree_int_cst_compare (len, dstsize);
2511
2512 if (cmpdst >= 0)
2513 {
2514 tree fndecl = gimple_call_fndecl (stmt);
2515
2516 /* Strncat copies (at most) LEN bytes and always appends
2517 the terminating NUL so the specified bound should never
2518 be equal to (or greater than) the size of the destination.
2519 If it is, the copy could overflow. */
2520 location_t loc = gimple_location (stmt);
2521 nowarn = warning_at (loc, OPT_Wstringop_overflow_,
2522 cmpdst == 0
2523 ? G_("%qD specified bound %E equals ""%qD specified bound %E equals " "destination size"
2524 "destination size")"%qD specified bound %E equals " "destination size"
2525 : G_("%qD specified bound %E exceeds ""%qD specified bound %E exceeds " "destination size %E"
2526 "destination size %E")"%qD specified bound %E exceeds " "destination size %E",
2527 fndecl, len, dstsize);
2528 if (nowarn)
2529 suppress_warning (stmt, OPT_Wstringop_overflow_);
2530 }
2531 }
2532
2533 if (!nowarn && TREE_CODE (src_len)((enum tree_code) (src_len)->base.code) == INTEGER_CST
2534 && tree_int_cst_compare (src_len, len) == 0)
2535 {
2536 tree fndecl = gimple_call_fndecl (stmt);
2537 location_t loc = gimple_location (stmt);
2538
2539 /* To avoid possible overflow the specified bound should also
2540 not be equal to the length of the source, even when the size
2541 of the destination is unknown (it's not an uncommon mistake
2542 to specify as the bound to strncpy the length of the source). */
2543 if (warning_at (loc, OPT_Wstringop_overflow_,
2544 "%qD specified bound %E equals source length",
2545 fndecl, len))
2546 suppress_warning (stmt, OPT_Wstringop_overflow_);
2547 }
2548 }
2549
2550 if (!known_lower (stmt, src_len, len))
2551 return false;
2552
2553 tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
2554
2555 /* If the replacement _DECL isn't initialized, don't do the
2556 transformation. */
2557 if (!fn)
2558 return false;
2559
2560 /* Otherwise, emit a call to strcat. */
2561 gcall *repl = gimple_build_call (fn, 2, dst, src);
2562 replace_call_with_call_and_fold (gsi, repl);
2563 return true;
2564}
2565
2566/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
2567 LEN, and SIZE. */
2568
2569static bool
2570gimple_fold_builtin_strncat_chk (gimple_stmt_iterator *gsi)
2571{
2572 gimple *stmt = gsi_stmt (*gsi);
2573 tree dest = gimple_call_arg (stmt, 0);
2574 tree src = gimple_call_arg (stmt, 1);
2575 tree len = gimple_call_arg (stmt, 2);
2576 tree size = gimple_call_arg (stmt, 3);
2577 tree fn;
2578 const char *p;
2579
2580 p = c_getstr (src);
2581 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
2582 if ((p && *p == '\0')
2583 || integer_zerop (len))
2584 {
2585 replace_call_with_value (gsi, dest);
2586 return true;
2587 }
2588
2589 if (! integer_all_onesp (size))
2590 {
2591 tree src_len = c_strlen (src, 1);
2592 if (known_lower (stmt, src_len, len))
2593 {
2594 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
2595 fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
2596 if (!fn)
2597 return false;
2598
2599 gimple *repl = gimple_build_call (fn, 3, dest, src, size);
2600 replace_call_with_call_and_fold (gsi, repl);
2601 return true;
2602 }
2603 return false;
2604 }
2605
2606 /* If __builtin_strncat_chk is used, assume strncat is available. */
2607 fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
2608 if (!fn)
2609 return false;
2610
2611 gimple *repl = gimple_build_call (fn, 3, dest, src, len);
2612 replace_call_with_call_and_fold (gsi, repl);
2613 return true;
2614}
2615
2616/* Build and append gimple statements to STMTS that would load a first
2617 character of a memory location identified by STR. LOC is location
2618 of the statement. */
2619
2620static tree
2621gimple_load_first_char (location_t loc, tree str, gimple_seq *stmts)
2622{
2623 tree var;
2624
2625 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0)build_qualified_type ((integer_types[itk_unsigned_char]), ((1
) ? TYPE_QUAL_CONST : 0) | ((0) ? TYPE_QUAL_VOLATILE : 0))
;
2626 tree cst_uchar_ptr_node
2627 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
2628 tree off0 = build_int_cst (cst_uchar_ptr_node, 0);
2629
2630 tree temp = fold_build2_loc (loc, MEM_REF, cst_uchar_node, str, off0);
2631 gassign *stmt = gimple_build_assign (NULL_TREE(tree) __null, temp);
2632 var = create_tmp_reg_or_ssa_name (cst_uchar_node, stmt);
2633
2634 gimple_assign_set_lhs (stmt, var);
2635 gimple_seq_add_stmt_without_update (stmts, stmt);
2636
2637 return var;
2638}
2639
2640/* Fold a call to the str{n}{case}cmp builtin pointed by GSI iterator. */
2641
2642static bool
2643gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
2644{
2645 gimple *stmt = gsi_stmt (*gsi);
2646 tree callee = gimple_call_fndecl (stmt);
2647 enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
2648
2649 tree type = integer_type_nodeinteger_types[itk_int];
2650 tree str1 = gimple_call_arg (stmt, 0);
2651 tree str2 = gimple_call_arg (stmt, 1);
2652 tree lhs = gimple_call_lhs (stmt);
2653
2654 tree bound_node = NULL_TREE(tree) __null;
2655 unsigned HOST_WIDE_INTlong bound = HOST_WIDE_INT_M1U-1UL;
2656
2657 /* Handle strncmp and strncasecmp functions. */
2658 if (gimple_call_num_args (stmt) == 3)
2659 {
2660 bound_node = gimple_call_arg (stmt, 2);
2661 if (tree_fits_uhwi_p (bound_node))
2662 bound = tree_to_uhwi (bound_node);
2663 }
2664
2665 /* If the BOUND parameter is zero, return zero. */
2666 if (bound == 0)
2667 {
2668 replace_call_with_value (gsi, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]);
2669 return true;
2670 }
2671
2672 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
2673 if (operand_equal_p (str1, str2, 0))
2674 {
2675 replace_call_with_value (gsi, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]);
2676 return true;
2677 }
2678
2679 /* Initially set to the number of characters, including the terminating
2680 nul if each array has one. LENx == strnlen (Sx, LENx) implies that
2681 the array Sx is not terminated by a nul.
2682 For nul-terminated strings then adjusted to their length so that
2683 LENx == NULPOSx holds. */
2684 unsigned HOST_WIDE_INTlong len1 = HOST_WIDE_INT_MAX(~((long) (1UL << (64 - 1)))), len2 = len1;
2685 const char *p1 = getbyterep (str1, &len1);
2686 const char *p2 = getbyterep (str2, &len2);
2687
2688 /* The position of the terminating nul character if one exists, otherwise
2689 a value greater than LENx. */
2690 unsigned HOST_WIDE_INTlong nulpos1 = HOST_WIDE_INT_MAX(~((long) (1UL << (64 - 1)))), nulpos2 = nulpos1;
2691
2692 if (p1)
2693 {
2694 size_t n = strnlen (p1, len1);
2695 if (n < len1)
2696 len1 = nulpos1 = n;
2697 }
2698
2699 if (p2)
2700 {
2701 size_t n = strnlen (p2, len2);
2702 if (n < len2)
2703 len2 = nulpos2 = n;
2704 }
2705
2706 /* For known strings, return an immediate value. */
2707 if (p1 && p2)
2708 {
2709 int r = 0;
2710 bool known_result = false;
2711
2712 switch (fcode)
2713 {
2714 case BUILT_IN_STRCMP:
2715 case BUILT_IN_STRCMP_EQ:
2716 if (len1 != nulpos1 || len2 != nulpos2)
2717 break;
2718
2719 r = strcmp (p1, p2);
2720 known_result = true;
2721 break;
2722
2723 case BUILT_IN_STRNCMP:
2724 case BUILT_IN_STRNCMP_EQ:
2725 {
2726 if (bound == HOST_WIDE_INT_M1U-1UL)
2727 break;
2728
2729 /* Reduce the bound to be no more than the length
2730 of the shorter of the two strings, or the sizes
2731 of the unterminated arrays. */
2732 unsigned HOST_WIDE_INTlong n = bound;
2733
2734 if (len1 == nulpos1 && len1 < n)
2735 n = len1 + 1;
2736 if (len2 == nulpos2 && len2 < n)
2737 n = len2 + 1;
2738
2739 if (MIN (nulpos1, nulpos2)((nulpos1) < (nulpos2) ? (nulpos1) : (nulpos2)) + 1 < n)
2740 break;
2741
2742 r = strncmp (p1, p2, n);
2743 known_result = true;
2744 break;
2745 }
2746 /* Only handleable situation is where the string are equal (result 0),
2747 which is already handled by operand_equal_p case. */
2748 case BUILT_IN_STRCASECMP:
2749 break;
2750 case BUILT_IN_STRNCASECMP:
2751 {
2752 if (bound == HOST_WIDE_INT_M1U-1UL)
2753 break;
2754 r = strncmp (p1, p2, bound);
2755 if (r == 0)
2756 known_result = true;
2757 break;
2758 }
2759 default:
2760 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2760, __FUNCTION__))
;
2761 }
2762
2763 if (known_result)
2764 {
2765 replace_call_with_value (gsi, build_cmp_result (type, r));
2766 return true;
2767 }
2768 }
2769
2770 bool nonzero_bound = (bound >= 1 && bound < HOST_WIDE_INT_M1U-1UL)
2771 || fcode == BUILT_IN_STRCMP
2772 || fcode == BUILT_IN_STRCMP_EQ
2773 || fcode == BUILT_IN_STRCASECMP;
2774
2775 location_t loc = gimple_location (stmt);
2776
2777 /* If the second arg is "", return *(const unsigned char*)arg1. */
2778 if (p2 && *p2 == '\0' && nonzero_bound)
2779 {
2780 gimple_seq stmts = NULL__null;
2781 tree var = gimple_load_first_char (loc, str1, &stmts);
2782 if (lhs)
2783 {
2784 stmt = gimple_build_assign (lhs, NOP_EXPR, var);
2785 gimple_seq_add_stmt_without_update (&stmts, stmt);
2786 }
2787
2788 gsi_replace_with_seq_vops (gsi, stmts);
2789 return true;
2790 }
2791
2792 /* If the first arg is "", return -*(const unsigned char*)arg2. */
2793 if (p1 && *p1 == '\0' && nonzero_bound)
2794 {
2795 gimple_seq stmts = NULL__null;
2796 tree var = gimple_load_first_char (loc, str2, &stmts);
2797
2798 if (lhs)
2799 {
2800 tree c = create_tmp_reg_or_ssa_name (integer_type_nodeinteger_types[itk_int]);
2801 stmt = gimple_build_assign (c, NOP_EXPR, var);
2802 gimple_seq_add_stmt_without_update (&stmts, stmt);
2803
2804 stmt = gimple_build_assign (lhs, NEGATE_EXPR, c);
2805 gimple_seq_add_stmt_without_update (&stmts, stmt);
2806 }
2807
2808 gsi_replace_with_seq_vops (gsi, stmts);
2809 return true;
2810 }
2811
2812 /* If BOUND is one, return an expression corresponding to
2813 (*(const unsigned char*)arg2 - *(const unsigned char*)arg1). */
2814 if (fcode == BUILT_IN_STRNCMP && bound == 1)
2815 {
2816 gimple_seq stmts = NULL__null;
2817 tree temp1 = gimple_load_first_char (loc, str1, &stmts);
2818 tree temp2 = gimple_load_first_char (loc, str2, &stmts);
2819
2820 if (lhs)
2821 {
2822 tree c1 = create_tmp_reg_or_ssa_name (integer_type_nodeinteger_types[itk_int]);
2823 gassign *convert1 = gimple_build_assign (c1, NOP_EXPR, temp1);
2824 gimple_seq_add_stmt_without_update (&stmts, convert1);
2825
2826 tree c2 = create_tmp_reg_or_ssa_name (integer_type_nodeinteger_types[itk_int]);
2827 gassign *convert2 = gimple_build_assign (c2, NOP_EXPR, temp2);
2828 gimple_seq_add_stmt_without_update (&stmts, convert2);
2829
2830 stmt = gimple_build_assign (lhs, MINUS_EXPR, c1, c2);
2831 gimple_seq_add_stmt_without_update (&stmts, stmt);
2832 }
2833
2834 gsi_replace_with_seq_vops (gsi, stmts);
2835 return true;
2836 }
2837
2838 /* If BOUND is greater than the length of one constant string,
2839 and the other argument is also a nul-terminated string, replace
2840 strncmp with strcmp. */
2841 if (fcode == BUILT_IN_STRNCMP
2842 && bound > 0 && bound < HOST_WIDE_INT_M1U-1UL
2843 && ((p2 && len2 < bound && len2 == nulpos2)
2844 || (p1 && len1 < bound && len1 == nulpos1)))
2845 {
2846 tree fn = builtin_decl_implicit (BUILT_IN_STRCMP);
2847 if (!fn)
2848 return false;
2849 gimple *repl = gimple_build_call (fn, 2, str1, str2);
2850 replace_call_with_call_and_fold (gsi, repl);
2851 return true;
2852 }
2853
2854 return false;
2855}
2856
2857/* Fold a call to the memchr pointed by GSI iterator. */
2858
2859static bool
2860gimple_fold_builtin_memchr (gimple_stmt_iterator *gsi)
2861{
2862 gimple *stmt = gsi_stmt (*gsi);
2863 tree lhs = gimple_call_lhs (stmt);
2864 tree arg1 = gimple_call_arg (stmt, 0);
2865 tree arg2 = gimple_call_arg (stmt, 1);
2866 tree len = gimple_call_arg (stmt, 2);
2867
2868 /* If the LEN parameter is zero, return zero. */
2869 if (integer_zerop (len))
2870 {
2871 replace_call_with_value (gsi, build_int_cst (ptr_type_nodeglobal_trees[TI_PTR_TYPE], 0));
2872 return true;
2873 }
2874
2875 char c;
2876 if (TREE_CODE (arg2)((enum tree_code) (arg2)->base.code) != INTEGER_CST
2877 || !tree_fits_uhwi_p (len)
2878 || !target_char_cst_p (arg2, &c))
2879 return false;
2880
2881 unsigned HOST_WIDE_INTlong length = tree_to_uhwi (len);
2882 unsigned HOST_WIDE_INTlong string_length;
2883 const char *p1 = getbyterep (arg1, &string_length);
2884
2885 if (p1)
2886 {
2887 const char *r = (const char *)memchr (p1, c, MIN (length, string_length)((length) < (string_length) ? (length) : (string_length)));
2888 if (r == NULL__null)
2889 {
2890 tree mem_size, offset_node;
2891 byte_representation (arg1, &offset_node, &mem_size, NULL__null);
2892 unsigned HOST_WIDE_INTlong offset = (offset_node == NULL_TREE(tree) __null)
2893 ? 0 : tree_to_uhwi (offset_node);
2894 /* MEM_SIZE is the size of the array the string literal
2895 is stored in. */
2896 unsigned HOST_WIDE_INTlong string_size = tree_to_uhwi (mem_size) - offset;
2897 gcc_checking_assert (string_length <= string_size)((void)(!(string_length <= string_size) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 2897, __FUNCTION__), 0 : 0))
;
2898 if (length <= string_size)
2899 {
2900 replace_call_with_value (gsi, build_int_cst (ptr_type_nodeglobal_trees[TI_PTR_TYPE], 0));
2901 return true;
2902 }
2903 }
2904 else
2905 {
2906 unsigned HOST_WIDE_INTlong offset = r - p1;
2907 gimple_seq stmts = NULL__null;
2908 if (lhs != NULL_TREE(tree) __null)
2909 {
2910 tree offset_cst = build_int_cst (sizetypesizetype_tab[(int) stk_sizetype], offset);
2911 gassign *stmt = gimple_build_assign (lhs, POINTER_PLUS_EXPR,
2912 arg1, offset_cst);
2913 gimple_seq_add_stmt_without_update (&stmts, stmt);
2914 }
2915 else
2916 gimple_seq_add_stmt_without_update (&stmts,
2917 gimple_build_nop ());
2918
2919 gsi_replace_with_seq_vops (gsi, stmts);
2920 return true;
2921 }
2922 }
2923
2924 return false;
2925}
2926
2927/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
2928 to the call. IGNORE is true if the value returned
2929 by the builtin will be ignored. UNLOCKED is true is true if this
2930 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
2931 the known length of the string. Return NULL_TREE if no simplification
2932 was possible. */
2933
2934static bool
2935gimple_fold_builtin_fputs (gimple_stmt_iterator *gsi,
2936 tree arg0, tree arg1,
2937 bool unlocked)
2938{
2939 gimple *stmt = gsi_stmt (*gsi);
2940
2941 /* If we're using an unlocked function, assume the other unlocked
2942 functions exist explicitly. */
2943 tree const fn_fputc = (unlocked
2944 ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
2945 : builtin_decl_implicit (BUILT_IN_FPUTC));
2946 tree const fn_fwrite = (unlocked
2947 ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
2948 : builtin_decl_implicit (BUILT_IN_FWRITE));
2949
2950 /* If the return value is used, don't do the transformation. */
2951 if (gimple_call_lhs (stmt))
2952 return false;
2953
2954 /* Get the length of the string passed to fputs. If the length
2955 can't be determined, punt. */
2956 tree len = get_maxval_strlen (arg0, SRK_STRLEN);
2957 if (!len || TREE_CODE (len)((enum tree_code) (len)->base.code) != INTEGER_CST)
2958 return false;
2959
2960 switch (compare_tree_int (len, 1))
2961 {
2962 case -1: /* length is 0, delete the call entirely . */
2963 replace_call_with_value (gsi, integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]);
2964 return true;
2965
2966 case 0: /* length is 1, call fputc. */
2967 {
2968 const char *p = c_getstr (arg0);
2969 if (p != NULL__null)
2970 {
2971 if (!fn_fputc)
2972 return false;
2973
2974 gimple *repl
2975 = gimple_build_call (fn_fputc, 2,
2976 build_int_cst (integer_type_nodeinteger_types[itk_int], p[0]),
2977 arg1);
2978 replace_call_with_call_and_fold (gsi, repl);
2979 return true;
2980 }
2981 }
2982 /* FALLTHROUGH */
2983 case 1: /* length is greater than 1, call fwrite. */
2984 {
2985 /* If optimizing for size keep fputs. */
2986 if (optimize_function_for_size_p (cfun(cfun + 0)))
2987 return false;
2988 /* New argument list transforming fputs(string, stream) to
2989 fwrite(string, 1, len, stream). */
2990 if (!fn_fwrite)
2991 return false;
2992
2993 gimple *repl
2994 = gimple_build_call (fn_fwrite, 4, arg0, size_one_nodeglobal_trees[TI_SIZE_ONE],
2995 fold_convert (size_type_node, len)fold_convert_loc (((location_t) 0), global_trees[TI_SIZE_TYPE
], len)
, arg1);
2996 replace_call_with_call_and_fold (gsi, repl);
2997 return true;
2998 }
2999 default:
3000 gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3000, __FUNCTION__))
;
3001 }
3002}
3003
3004/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
3005 DEST, SRC, LEN, and SIZE are the arguments to the call.
3006 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
3007 code of the builtin. If MAXLEN is not NULL, it is maximum length
3008 passed as third argument. */
3009
3010static bool
3011gimple_fold_builtin_memory_chk (gimple_stmt_iterator *gsi,
3012 tree dest, tree src, tree len, tree size,
3013 enum built_in_function fcode)
3014{
3015 gimple *stmt = gsi_stmt (*gsi);
3016 location_t loc = gimple_location (stmt);
3017 bool ignore = gimple_call_lhs (stmt) == NULL_TREE(tree) __null;
3018 tree fn;
3019
3020 /* If SRC and DEST are the same (and not volatile), return DEST
3021 (resp. DEST+LEN for __mempcpy_chk). */
3022 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
3023 {
3024 if (fcode != BUILT_IN_MEMPCPY_CHK)
3025 {
3026 replace_call_with_value (gsi, dest);
3027 return true;
3028 }
3029 else
3030 {
3031 gimple_seq stmts = NULL__null;
3032 len = gimple_convert_to_ptrofftype (&stmts, loc, len);
3033 tree temp = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
3034 TREE_TYPE (dest)((contains_struct_check ((dest), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3034, __FUNCTION__))->typed.type)
, dest, len);
3035 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3036 replace_call_with_value (gsi, temp);
3037 return true;
3038 }
3039 }
3040
3041 tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3042 if (! integer_all_onesp (size)
3043 && !known_lower (stmt, len, size)
3044 && !known_lower (stmt, maxlen, size))
3045 {
3046 /* MAXLEN and LEN both cannot be proved to be less than SIZE, at
3047 least try to optimize (void) __mempcpy_chk () into
3048 (void) __memcpy_chk () */
3049 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
3050 {
3051 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3052 if (!fn)
3053 return false;
3054
3055 gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3056 replace_call_with_call_and_fold (gsi, repl);
3057 return true;
3058 }
3059 return false;
3060 }
3061
3062 fn = NULL_TREE(tree) __null;
3063 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
3064 mem{cpy,pcpy,move,set} is available. */
3065 switch (fcode)
3066 {
3067 case BUILT_IN_MEMCPY_CHK:
3068 fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
3069 break;
3070 case BUILT_IN_MEMPCPY_CHK:
3071 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
3072 break;
3073 case BUILT_IN_MEMMOVE_CHK:
3074 fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
3075 break;
3076 case BUILT_IN_MEMSET_CHK:
3077 fn = builtin_decl_explicit (BUILT_IN_MEMSET);
3078 break;
3079 default:
3080 break;
3081 }
3082
3083 if (!fn)
3084 return false;
3085
3086 gimple *repl = gimple_build_call (fn, 3, dest, src, len);
3087 replace_call_with_call_and_fold (gsi, repl);
3088 return true;
3089}
3090
3091/* Print a message in the dump file recording transformation of FROM to TO. */
3092
3093static void
3094dump_transformation (gcall *from, gcall *to)
3095{
3096 if (dump_enabled_p ())
3097 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, from, "simplified %T to %T\n",
3098 gimple_call_fn (from), gimple_call_fn (to));
3099}
3100
3101/* Fold a call to the __st[rp]cpy_chk builtin.
3102 DEST, SRC, and SIZE are the arguments to the call.
3103 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
3104 code of the builtin. If MAXLEN is not NULL, it is maximum length of
3105 strings passed as second argument. */
3106
3107static bool
3108gimple_fold_builtin_stxcpy_chk (gimple_stmt_iterator *gsi,
3109 tree dest,
3110 tree src, tree size,
3111 enum built_in_function fcode)
3112{
3113 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3114 location_t loc = gimple_location (stmt);
3115 bool ignore = gimple_call_lhs (stmt) == NULL_TREE(tree) __null;
3116 tree len, fn;
3117
3118 /* If SRC and DEST are the same (and not volatile), return DEST. */
3119 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
3120 {
3121 /* Issue -Wrestrict unless the pointers are null (those do
3122 not point to objects and so do not indicate an overlap;
3123 such calls could be the result of sanitization and jump
3124 threading). */
3125 if (!integer_zerop (dest)
3126 && !warning_suppressed_p (stmt, OPT_Wrestrict))
3127 {
3128 tree func = gimple_call_fndecl (stmt);
3129
3130 warning_at (loc, OPT_Wrestrict,
3131 "%qD source argument is the same as destination",
3132 func);
3133 }
3134
3135 replace_call_with_value (gsi, dest);
3136 return true;
3137 }
3138
3139 tree maxlen = get_maxval_strlen (src, SRK_STRLENMAX);
3140 if (! integer_all_onesp (size))
3141 {
3142 len = c_strlen (src, 1);
3143 if (!known_lower (stmt, len, size, true)
3144 && !known_lower (stmt, maxlen, size, true))
3145 {
3146 if (fcode == BUILT_IN_STPCPY_CHK)
3147 {
3148 if (! ignore)
3149 return false;
3150
3151 /* If return value of __stpcpy_chk is ignored,
3152 optimize into __strcpy_chk. */
3153 fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
3154 if (!fn)
3155 return false;
3156
3157 gimple *repl = gimple_build_call (fn, 3, dest, src, size);
3158 replace_call_with_call_and_fold (gsi, repl);
3159 return true;
3160 }
3161
3162 if (! len || TREE_SIDE_EFFECTS (len)((non_type_check ((len), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3162, __FUNCTION__))->base.side_effects_flag)
)
3163 return false;
3164
3165 /* If c_strlen returned something, but not provably less than size,
3166 transform __strcpy_chk into __memcpy_chk. */
3167 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
3168 if (!fn)
3169 return false;
3170
3171 gimple_seq stmts = NULL__null;
3172 len = force_gimple_operand (len, &stmts, true, NULL_TREE(tree) __null);
3173 len = gimple_convert (&stmts, loc, size_type_nodeglobal_trees[TI_SIZE_TYPE], len);
3174 len = gimple_build (&stmts, loc, PLUS_EXPR, size_type_nodeglobal_trees[TI_SIZE_TYPE], len,
3175 build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], 1));
3176 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3177 gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3178 replace_call_with_call_and_fold (gsi, repl);
3179 return true;
3180 }
3181 }
3182
3183 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
3184 fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK && !ignore
3185 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
3186 if (!fn)
3187 return false;
3188
3189 gcall *repl = gimple_build_call (fn, 2, dest, src);
3190 dump_transformation (stmt, repl);
3191 replace_call_with_call_and_fold (gsi, repl);
3192 return true;
3193}
3194
3195/* Fold a call to the __st{r,p}ncpy_chk builtin. DEST, SRC, LEN, and SIZE
3196 are the arguments to the call. If MAXLEN is not NULL, it is maximum
3197 length passed as third argument. IGNORE is true if return value can be
3198 ignored. FCODE is the BUILT_IN_* code of the builtin. */
3199
3200static bool
3201gimple_fold_builtin_stxncpy_chk (gimple_stmt_iterator *gsi,
3202 tree dest, tree src,
3203 tree len, tree size,
3204 enum built_in_function fcode)
3205{
3206 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3207 bool ignore = gimple_call_lhs (stmt) == NULL_TREE(tree) __null;
3208 tree fn;
3209
3210 tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3211 if (! integer_all_onesp (size)
3212 && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3213 {
3214 if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
3215 {
3216 /* If return value of __stpncpy_chk is ignored,
3217 optimize into __strncpy_chk. */
3218 fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
3219 if (fn)
3220 {
3221 gimple *repl = gimple_build_call (fn, 4, dest, src, len, size);
3222 replace_call_with_call_and_fold (gsi, repl);
3223 return true;
3224 }
3225 }
3226 return false;
3227 }
3228
3229 /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */
3230 fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK && !ignore
3231 ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
3232 if (!fn)
3233 return false;
3234
3235 gcall *repl = gimple_build_call (fn, 3, dest, src, len);
3236 dump_transformation (stmt, repl);
3237 replace_call_with_call_and_fold (gsi, repl);
3238 return true;
3239}
3240
3241/* Fold function call to builtin stpcpy with arguments DEST and SRC.
3242 Return NULL_TREE if no simplification can be made. */
3243
3244static bool
3245gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
3246{
3247 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3248 location_t loc = gimple_location (stmt);
3249 tree dest = gimple_call_arg (stmt, 0);
3250 tree src = gimple_call_arg (stmt, 1);
3251 tree fn, lenp1;
3252
3253 /* If the result is unused, replace stpcpy with strcpy. */
3254 if (gimple_call_lhs (stmt) == NULL_TREE(tree) __null)
3255 {
3256 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3257 if (!fn)
3258 return false;
3259 gimple_call_set_fndecl (stmt, fn);
3260 fold_stmt (gsi);
3261 return true;
3262 }
3263
3264 /* Set to non-null if ARG refers to an unterminated array. */
3265 c_strlen_data data = { };
3266 /* The size of the unterminated array if SRC referes to one. */
3267 tree size;
3268 /* True if the size is exact/constant, false if it's the lower bound
3269 of a range. */
3270 bool exact;
3271 tree len = c_strlen (src, 1, &data, 1);
3272 if (!len
3273 || TREE_CODE (len)((enum tree_code) (len)->base.code) != INTEGER_CST)
3274 {
3275 data.decl = unterminated_array (src, &size, &exact);
3276 if (!data.decl)
3277 return false;
3278 }
3279
3280 if (data.decl)
3281 {
3282 /* Avoid folding calls with unterminated arrays. */
3283 if (!warning_suppressed_p (stmt, OPT_Wstringop_overread))
3284 warn_string_no_nul (loc, stmt, "stpcpy", src, data.decl, size,
3285 exact);
3286 suppress_warning (stmt, OPT_Wstringop_overread);
3287 return false;
3288 }
3289
3290 if (optimize_function_for_size_p (cfun(cfun + 0))
3291 /* If length is zero it's small enough. */
3292 && !integer_zerop (len))
3293 return false;
3294
3295 /* If the source has a known length replace stpcpy with memcpy. */
3296 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3297 if (!fn)
3298 return false;
3299
3300 gimple_seq stmts = NULL__null;
3301 tree tem = gimple_convert (&stmts, loc, size_type_nodeglobal_trees[TI_SIZE_TYPE], len);
3302 lenp1 = gimple_build (&stmts, loc, PLUS_EXPR, size_type_nodeglobal_trees[TI_SIZE_TYPE],
3303 tem, build_int_cst (size_type_nodeglobal_trees[TI_SIZE_TYPE], 1));
3304 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3305 gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
3306 gimple_move_vops (repl, stmt);
3307 gsi_insert_before (gsi, repl, GSI_SAME_STMT);
3308 /* Replace the result with dest + len. */
3309 stmts = NULL__null;
3310 tem = gimple_convert (&stmts, loc, sizetypesizetype_tab[(int) stk_sizetype], len);
3311 gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
3312 gassign *ret = gimple_build_assign (gimple_call_lhs (stmt),
3313 POINTER_PLUS_EXPR, dest, tem);
3314 gsi_replace (gsi, ret, false);
3315 /* Finally fold the memcpy call. */
3316 gimple_stmt_iterator gsi2 = *gsi;
3317 gsi_prev (&gsi2);
3318 fold_stmt (&gsi2);
3319 return true;
3320}
3321
3322/* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS. Return
3323 NULL_TREE if a normal call should be emitted rather than expanding
3324 the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
3325 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
3326 passed as second argument. */
3327
3328static bool
3329gimple_fold_builtin_snprintf_chk (gimple_stmt_iterator *gsi,
3330 enum built_in_function fcode)
3331{
3332 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3333 tree dest, size, len, fn, fmt, flag;
3334 const char *fmt_str;
3335
3336 /* Verify the required arguments in the original call. */
3337 if (gimple_call_num_args (stmt) < 5)
3338 return false;
3339
3340 dest = gimple_call_arg (stmt, 0);
3341 len = gimple_call_arg (stmt, 1);
3342 flag = gimple_call_arg (stmt, 2);
3343 size = gimple_call_arg (stmt, 3);
3344 fmt = gimple_call_arg (stmt, 4);
3345
3346 tree maxlen = get_maxval_strlen (len, SRK_INT_VALUE);
3347 if (! integer_all_onesp (size)
3348 && !known_lower (stmt, len, size) && !known_lower (stmt, maxlen, size))
3349 return false;
3350
3351 if (!init_target_chars ())
3352 return false;
3353
3354 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
3355 or if format doesn't contain % chars or is "%s". */
3356 if (! integer_zerop (flag))
3357 {
3358 fmt_str = c_getstr (fmt);
3359 if (fmt_str == NULL__null)
3360 return false;
3361 if (strchr (fmt_str, target_percent) != NULL__null
3362 && strcmp (fmt_str, target_percent_s))
3363 return false;
3364 }
3365
3366 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
3367 available. */
3368 fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
3369 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
3370 if (!fn)
3371 return false;
3372
3373 /* Replace the called function and the first 5 argument by 3 retaining
3374 trailing varargs. */
3375 gimple_call_set_fndecl (stmt, fn);
3376 gimple_call_set_fntype (stmt, TREE_TYPE (fn)((contains_struct_check ((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3376, __FUNCTION__))->typed.type)
);
3377 gimple_call_set_arg (stmt, 0, dest);
3378 gimple_call_set_arg (stmt, 1, len);
3379 gimple_call_set_arg (stmt, 2, fmt);
3380 for (unsigned i = 3; i < gimple_call_num_args (stmt) - 2; ++i)
3381 gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3382 gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3383 fold_stmt (gsi);
3384 return true;
3385}
3386
3387/* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
3388 Return NULL_TREE if a normal call should be emitted rather than
3389 expanding the function inline. FCODE is either BUILT_IN_SPRINTF_CHK
3390 or BUILT_IN_VSPRINTF_CHK. */
3391
3392static bool
3393gimple_fold_builtin_sprintf_chk (gimple_stmt_iterator *gsi,
3394 enum built_in_function fcode)
3395{
3396 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3397 tree dest, size, len, fn, fmt, flag;
3398 const char *fmt_str;
3399 unsigned nargs = gimple_call_num_args (stmt);
3400
3401 /* Verify the required arguments in the original call. */
3402 if (nargs < 4)
3403 return false;
3404 dest = gimple_call_arg (stmt, 0);
3405 flag = gimple_call_arg (stmt, 1);
3406 size = gimple_call_arg (stmt, 2);
3407 fmt = gimple_call_arg (stmt, 3);
3408
3409 len = NULL_TREE(tree) __null;
3410
3411 if (!init_target_chars ())
3412 return false;
3413
3414 /* Check whether the format is a literal string constant. */
3415 fmt_str = c_getstr (fmt);
3416 if (fmt_str != NULL__null)
3417 {
3418 /* If the format doesn't contain % args or %%, we know the size. */
3419 if (strchr (fmt_str, target_percent) == 0)
3420 {
3421 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
3422 len = build_int_cstu (size_type_nodeglobal_trees[TI_SIZE_TYPE], strlen (fmt_str));
3423 }
3424 /* If the format is "%s" and first ... argument is a string literal,
3425 we know the size too. */
3426 else if (fcode == BUILT_IN_SPRINTF_CHK
3427 && strcmp (fmt_str, target_percent_s) == 0)
3428 {
3429 tree arg;
3430
3431 if (nargs == 5)
3432 {
3433 arg = gimple_call_arg (stmt, 4);
3434 if (POINTER_TYPE_P (TREE_TYPE (arg))(((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3434, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3434, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3435 len = c_strlen (arg, 1);
3436 }
3437 }
3438 }
3439
3440 if (! integer_all_onesp (size) && !known_lower (stmt, len, size, true))
3441 return false;
3442
3443 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
3444 or if format doesn't contain % chars or is "%s". */
3445 if (! integer_zerop (flag))
3446 {
3447 if (fmt_str == NULL__null)
3448 return false;
3449 if (strchr (fmt_str, target_percent) != NULL__null
3450 && strcmp (fmt_str, target_percent_s))
3451 return false;
3452 }
3453
3454 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
3455 fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
3456 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
3457 if (!fn)
3458 return false;
3459
3460 /* Replace the called function and the first 4 argument by 2 retaining
3461 trailing varargs. */
3462 gimple_call_set_fndecl (stmt, fn);
3463 gimple_call_set_fntype (stmt, TREE_TYPE (fn)((contains_struct_check ((fn), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3463, __FUNCTION__))->typed.type)
);
3464 gimple_call_set_arg (stmt, 0, dest);
3465 gimple_call_set_arg (stmt, 1, fmt);
3466 for (unsigned i = 2; i < gimple_call_num_args (stmt) - 2; ++i)
3467 gimple_call_set_arg (stmt, i, gimple_call_arg (stmt, i + 2));
3468 gimple_set_num_ops (stmt, gimple_num_ops (stmt) - 2);
3469 fold_stmt (gsi);
3470 return true;
3471}
3472
3473/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
3474 ORIG may be null if this is a 2-argument call. We don't attempt to
3475 simplify calls with more than 3 arguments.
3476
3477 Return true if simplification was possible, otherwise false. */
3478
3479bool
3480gimple_fold_builtin_sprintf (gimple_stmt_iterator *gsi)
3481{
3482 gimple *stmt = gsi_stmt (*gsi);
3483
3484 /* Verify the required arguments in the original call. We deal with two
3485 types of sprintf() calls: 'sprintf (str, fmt)' and
3486 'sprintf (dest, "%s", orig)'. */
3487 if (gimple_call_num_args (stmt) > 3)
3488 return false;
3489
3490 tree orig = NULL_TREE(tree) __null;
3491 if (gimple_call_num_args (stmt) == 3)
3492 orig = gimple_call_arg (stmt, 2);
3493
3494 /* Check whether the format is a literal string constant. */
3495 tree fmt = gimple_call_arg (stmt, 1);
3496 const char *fmt_str = c_getstr (fmt);
3497 if (fmt_str == NULL__null)
3498 return false;
3499
3500 tree dest = gimple_call_arg (stmt, 0);
3501
3502 if (!init_target_chars ())
3503 return false;
3504
3505 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3506 if (!fn)
3507 return false;
3508
3509 /* If the format doesn't contain % args or %%, use strcpy. */
3510 if (strchr (fmt_str, target_percent) == NULL__null)
3511 {
3512 /* Don't optimize sprintf (buf, "abc", ptr++). */
3513 if (orig)
3514 return false;
3515
3516 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
3517 'format' is known to contain no % formats. */
3518 gimple_seq stmts = NULL__null;
3519 gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3520
3521 /* Propagate the NO_WARNING bit to avoid issuing the same
3522 warning more than once. */
3523 copy_warning (repl, stmt);
3524
3525 gimple_seq_add_stmt_without_update (&stmts, repl);
3526 if (tree lhs = gimple_call_lhs (stmt))
3527 {
3528 repl = gimple_build_assign (lhs, build_int_cst (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3528, __FUNCTION__))->typed.type)
,
3529 strlen (fmt_str)));
3530 gimple_seq_add_stmt_without_update (&stmts, repl);
3531 gsi_replace_with_seq_vops (gsi, stmts);
3532 /* gsi now points at the assignment to the lhs, get a
3533 stmt iterator to the memcpy call.
3534 ??? We can't use gsi_for_stmt as that doesn't work when the
3535 CFG isn't built yet. */
3536 gimple_stmt_iterator gsi2 = *gsi;
3537 gsi_prev (&gsi2);
3538 fold_stmt (&gsi2);
3539 }
3540 else
3541 {
3542 gsi_replace_with_seq_vops (gsi, stmts);
3543 fold_stmt (gsi);
3544 }
3545 return true;
3546 }
3547
3548 /* If the format is "%s", use strcpy if the result isn't used. */
3549 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3550 {
3551 /* Don't crash on sprintf (str1, "%s"). */
3552 if (!orig)
3553 return false;
3554
3555 /* Don't fold calls with source arguments of invalid (nonpointer)
3556 types. */
3557 if (!POINTER_TYPE_P (TREE_TYPE (orig))(((enum tree_code) (((contains_struct_check ((orig), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3557, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((orig), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3557, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3558 return false;
3559
3560 tree orig_len = NULL_TREE(tree) __null;
3561 if (gimple_call_lhs (stmt))
3562 {
3563 orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3564 if (!orig_len)
3565 return false;
3566 }
3567
3568 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
3569 gimple_seq stmts = NULL__null;
3570 gimple *repl = gimple_build_call (fn, 2, dest, orig);
3571
3572 /* Propagate the NO_WARNING bit to avoid issuing the same
3573 warning more than once. */
3574 copy_warning (repl, stmt);
3575
3576 gimple_seq_add_stmt_without_update (&stmts, repl);
3577 if (tree lhs = gimple_call_lhs (stmt))
3578 {
3579 if (!useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3579, __FUNCTION__))->typed.type)
,
3580 TREE_TYPE (orig_len)((contains_struct_check ((orig_len), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3580, __FUNCTION__))->typed.type)
))
3581 orig_len = fold_convert (TREE_TYPE (lhs), orig_len)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3581, __FUNCTION__))->typed.type), orig_len)
;
3582 repl = gimple_build_assign (lhs, orig_len);
3583 gimple_seq_add_stmt_without_update (&stmts, repl);
3584 gsi_replace_with_seq_vops (gsi, stmts);
3585 /* gsi now points at the assignment to the lhs, get a
3586 stmt iterator to the memcpy call.
3587 ??? We can't use gsi_for_stmt as that doesn't work when the
3588 CFG isn't built yet. */
3589 gimple_stmt_iterator gsi2 = *gsi;
3590 gsi_prev (&gsi2);
3591 fold_stmt (&gsi2);
3592 }
3593 else
3594 {
3595 gsi_replace_with_seq_vops (gsi, stmts);
3596 fold_stmt (gsi);
3597 }
3598 return true;
3599 }
3600 return false;
3601}
3602
3603/* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
3604 FMT, and ORIG. ORIG may be null if this is a 3-argument call. We don't
3605 attempt to simplify calls with more than 4 arguments.
3606
3607 Return true if simplification was possible, otherwise false. */
3608
3609bool
3610gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi)
3611{
3612 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3613 tree dest = gimple_call_arg (stmt, 0);
3614 tree destsize = gimple_call_arg (stmt, 1);
3615 tree fmt = gimple_call_arg (stmt, 2);
3616 tree orig = NULL_TREE(tree) __null;
3617 const char *fmt_str = NULL__null;
3618
3619 if (gimple_call_num_args (stmt) > 4)
3620 return false;
3621
3622 if (gimple_call_num_args (stmt) == 4)
3623 orig = gimple_call_arg (stmt, 3);
3624
3625 /* Check whether the format is a literal string constant. */
3626 fmt_str = c_getstr (fmt);
3627 if (fmt_str == NULL__null)
3628 return false;
3629
3630 if (!init_target_chars ())
3631 return false;
3632
3633 /* If the format doesn't contain % args or %%, use strcpy. */
3634 if (strchr (fmt_str, target_percent) == NULL__null)
3635 {
3636 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3637 if (!fn)
3638 return false;
3639
3640 /* Don't optimize snprintf (buf, 4, "abc", ptr++). */
3641 if (orig)
3642 return false;
3643
3644 tree len = build_int_cstu (TREE_TYPE (destsize)((contains_struct_check ((destsize), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3644, __FUNCTION__))->typed.type)
, strlen (fmt_str));
3645
3646 /* We could expand this as
3647 memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
3648 or to
3649 memcpy (str, fmt_with_nul_at_cstm1, cst);
3650 but in the former case that might increase code size
3651 and in the latter case grow .rodata section too much.
3652 So punt for now. */
3653 if (!known_lower (stmt, len, destsize, true))
3654 return false;
3655
3656 gimple_seq stmts = NULL__null;
3657 gimple *repl = gimple_build_call (fn, 2, dest, fmt);
3658 gimple_seq_add_stmt_without_update (&stmts, repl);
3659 if (tree lhs = gimple_call_lhs (stmt))
3660 {
3661 repl = gimple_build_assign (lhs,
3662 fold_convert (TREE_TYPE (lhs), len)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3662, __FUNCTION__))->typed.type), len)
);
3663 gimple_seq_add_stmt_without_update (&stmts, repl);
3664 gsi_replace_with_seq_vops (gsi, stmts);
3665 /* gsi now points at the assignment to the lhs, get a
3666 stmt iterator to the memcpy call.
3667 ??? We can't use gsi_for_stmt as that doesn't work when the
3668 CFG isn't built yet. */
3669 gimple_stmt_iterator gsi2 = *gsi;
3670 gsi_prev (&gsi2);
3671 fold_stmt (&gsi2);
3672 }
3673 else
3674 {
3675 gsi_replace_with_seq_vops (gsi, stmts);
3676 fold_stmt (gsi);
3677 }
3678 return true;
3679 }
3680
3681 /* If the format is "%s", use strcpy if the result isn't used. */
3682 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
3683 {
3684 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3685 if (!fn)
3686 return false;
3687
3688 /* Don't crash on snprintf (str1, cst, "%s"). */
3689 if (!orig)
3690 return false;
3691
3692 tree orig_len = get_maxval_strlen (orig, SRK_STRLEN);
3693
3694 /* We could expand this as
3695 memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
3696 or to
3697 memcpy (str1, str2_with_nul_at_cstm1, cst);
3698 but in the former case that might increase code size
3699 and in the latter case grow .rodata section too much.
3700 So punt for now. */
3701 if (!known_lower (stmt, orig_len, destsize, true))
3702 return false;
3703
3704 /* Convert snprintf (str1, cst, "%s", str2) into
3705 strcpy (str1, str2) if strlen (str2) < cst. */
3706 gimple_seq stmts = NULL__null;
3707 gimple *repl = gimple_build_call (fn, 2, dest, orig);
3708 gimple_seq_add_stmt_without_update (&stmts, repl);
3709 if (tree lhs = gimple_call_lhs (stmt))
3710 {
3711 if (!useless_type_conversion_p (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3711, __FUNCTION__))->typed.type)
,
3712 TREE_TYPE (orig_len)((contains_struct_check ((orig_len), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3712, __FUNCTION__))->typed.type)
))
3713 orig_len = fold_convert (TREE_TYPE (lhs), orig_len)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3713, __FUNCTION__))->typed.type), orig_len)
;
3714 repl = gimple_build_assign (lhs, orig_len);
3715 gimple_seq_add_stmt_without_update (&stmts, repl);
3716 gsi_replace_with_seq_vops (gsi, stmts);
3717 /* gsi now points at the assignment to the lhs, get a
3718 stmt iterator to the memcpy call.
3719 ??? We can't use gsi_for_stmt as that doesn't work when the
3720 CFG isn't built yet. */
3721 gimple_stmt_iterator gsi2 = *gsi;
3722 gsi_prev (&gsi2);
3723 fold_stmt (&gsi2);
3724 }
3725 else
3726 {
3727 gsi_replace_with_seq_vops (gsi, stmts);
3728 fold_stmt (gsi);
3729 }
3730 return true;
3731 }
3732 return false;
3733}
3734
3735/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
3736 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
3737 more than 3 arguments, and ARG may be null in the 2-argument case.
3738
3739 Return NULL_TREE if no simplification was possible, otherwise return the
3740 simplified form of the call as a tree. FCODE is the BUILT_IN_*
3741 code of the function to be simplified. */
3742
3743static bool
3744gimple_fold_builtin_fprintf (gimple_stmt_iterator *gsi,
3745 tree fp, tree fmt, tree arg,
3746 enum built_in_function fcode)
3747{
3748 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3749 tree fn_fputc, fn_fputs;
3750 const char *fmt_str = NULL__null;
3751
3752 /* If the return value is used, don't do the transformation. */
3753 if (gimple_call_lhs (stmt) != NULL_TREE(tree) __null)
3754 return false;
3755
3756 /* Check whether the format is a literal string constant. */
3757 fmt_str = c_getstr (fmt);
3758 if (fmt_str == NULL__null)
3759 return false;
3760
3761 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
3762 {
3763 /* If we're using an unlocked function, assume the other
3764 unlocked functions exist explicitly. */
3765 fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
3766 fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
3767 }
3768 else
3769 {
3770 fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
3771 fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
3772 }
3773
3774 if (!init_target_chars ())
3775 return false;
3776
3777 /* If the format doesn't contain % args or %%, use strcpy. */
3778 if (strchr (fmt_str, target_percent) == NULL__null)
3779 {
3780 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
3781 && arg)
3782 return false;
3783
3784 /* If the format specifier was "", fprintf does nothing. */
3785 if (fmt_str[0] == '\0')
3786 {
3787 replace_call_with_value (gsi, NULL_TREE(tree) __null);
3788 return true;
3789 }
3790
3791 /* When "string" doesn't contain %, replace all cases of
3792 fprintf (fp, string) with fputs (string, fp). The fputs
3793 builtin will take care of special cases like length == 1. */
3794 if (fn_fputs)
3795 {
3796 gcall *repl = gimple_build_call (fn_fputs, 2, fmt, fp);
3797 replace_call_with_call_and_fold (gsi, repl);
3798 return true;
3799 }
3800 }
3801
3802 /* The other optimizations can be done only on the non-va_list variants. */
3803 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
3804 return false;
3805
3806 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
3807 else if (strcmp (fmt_str, target_percent_s) == 0)
3808 {
3809 if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg))(((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3809, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3809, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3810 return false;
3811 if (fn_fputs)
3812 {
3813 gcall *repl = gimple_build_call (fn_fputs, 2, arg, fp);
3814 replace_call_with_call_and_fold (gsi, repl);
3815 return true;
3816 }
3817 }
3818
3819 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
3820 else if (strcmp (fmt_str, target_percent_c) == 0)
3821 {
3822 if (!arg
3823 || ! useless_type_conversion_p (integer_type_nodeinteger_types[itk_int], TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3823, __FUNCTION__))->typed.type)
))
3824 return false;
3825 if (fn_fputc)
3826 {
3827 gcall *repl = gimple_build_call (fn_fputc, 2, arg, fp);
3828 replace_call_with_call_and_fold (gsi, repl);
3829 return true;
3830 }
3831 }
3832
3833 return false;
3834}
3835
3836/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
3837 FMT and ARG are the arguments to the call; we don't fold cases with
3838 more than 2 arguments, and ARG may be null if this is a 1-argument case.
3839
3840 Return NULL_TREE if no simplification was possible, otherwise return the
3841 simplified form of the call as a tree. FCODE is the BUILT_IN_*
3842 code of the function to be simplified. */
3843
3844static bool
3845gimple_fold_builtin_printf (gimple_stmt_iterator *gsi, tree fmt,
3846 tree arg, enum built_in_function fcode)
3847{
3848 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
3849 tree fn_putchar, fn_puts, newarg;
3850 const char *fmt_str = NULL__null;
3851
3852 /* If the return value is used, don't do the transformation. */
3853 if (gimple_call_lhs (stmt) != NULL_TREE(tree) __null)
3854 return false;
3855
3856 /* Check whether the format is a literal string constant. */
3857 fmt_str = c_getstr (fmt);
3858 if (fmt_str == NULL__null)
3859 return false;
3860
3861 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
3862 {
3863 /* If we're using an unlocked function, assume the other
3864 unlocked functions exist explicitly. */
3865 fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
3866 fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
3867 }
3868 else
3869 {
3870 fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
3871 fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
3872 }
3873
3874 if (!init_target_chars ())
3875 return false;
3876
3877 if (strcmp (fmt_str, target_percent_s) == 0
3878 || strchr (fmt_str, target_percent) == NULL__null)
3879 {
3880 const char *str;
3881
3882 if (strcmp (fmt_str, target_percent_s) == 0)
3883 {
3884 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
3885 return false;
3886
3887 if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg))(((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3887, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3887, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3888 return false;
3889
3890 str = c_getstr (arg);
3891 if (str == NULL__null)
3892 return false;
3893 }
3894 else
3895 {
3896 /* The format specifier doesn't contain any '%' characters. */
3897 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
3898 && arg)
3899 return false;
3900 str = fmt_str;
3901 }
3902
3903 /* If the string was "", printf does nothing. */
3904 if (str[0] == '\0')
3905 {
3906 replace_call_with_value (gsi, NULL_TREE(tree) __null);
3907 return true;
3908 }
3909
3910 /* If the string has length of 1, call putchar. */
3911 if (str[1] == '\0')
3912 {
3913 /* Given printf("c"), (where c is any one character,)
3914 convert "c"[0] to an int and pass that to the replacement
3915 function. */
3916 newarg = build_int_cst (integer_type_nodeinteger_types[itk_int], str[0]);
3917 if (fn_putchar)
3918 {
3919 gcall *repl = gimple_build_call (fn_putchar, 1, newarg);
3920 replace_call_with_call_and_fold (gsi, repl);
3921 return true;
3922 }
3923 }
3924 else
3925 {
3926 /* If the string was "string\n", call puts("string"). */
3927 size_t len = strlen (str);
3928 if ((unsigned char)str[len - 1] == target_newline
3929 && (size_t) (int) len == len
3930 && (int) len > 0)
3931 {
3932 char *newstr;
3933
3934 /* Create a NUL-terminated string that's one char shorter
3935 than the original, stripping off the trailing '\n'. */
3936 newstr = xstrdup (str);
3937 newstr[len - 1] = '\0';
3938 newarg = build_string_literal (len, newstr);
3939 free (newstr);
3940 if (fn_puts)
3941 {
3942 gcall *repl = gimple_build_call (fn_puts, 1, newarg);
3943 replace_call_with_call_and_fold (gsi, repl);
3944 return true;
3945 }
3946 }
3947 else
3948 /* We'd like to arrange to call fputs(string,stdout) here,
3949 but we need stdout and don't have a way to get it yet. */
3950 return false;
3951 }
3952 }
3953
3954 /* The other optimizations can be done only on the non-va_list variants. */
3955 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
3956 return false;
3957
3958 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
3959 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
3960 {
3961 if (!arg || ! POINTER_TYPE_P (TREE_TYPE (arg))(((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3961, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE
|| ((enum tree_code) (((contains_struct_check ((arg), (TS_TYPED
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3961, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE
)
)
3962 return false;
3963 if (fn_puts)
3964 {
3965 gcall *repl = gimple_build_call (fn_puts, 1, arg);
3966 replace_call_with_call_and_fold (gsi, repl);
3967 return true;
3968 }
3969 }
3970
3971 /* If the format specifier was "%c", call __builtin_putchar(arg). */
3972 else if (strcmp (fmt_str, target_percent_c) == 0)
3973 {
3974 if (!arg || ! useless_type_conversion_p (integer_type_nodeinteger_types[itk_int],
3975 TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 3975, __FUNCTION__))->typed.type)
))
3976 return false;
3977 if (fn_putchar)
3978 {
3979 gcall *repl = gimple_build_call (fn_putchar, 1, arg);
3980 replace_call_with_call_and_fold (gsi, repl);
3981 return true;
3982 }
3983 }
3984
3985 return false;
3986}
3987
3988
3989
3990/* Fold a call to __builtin_strlen with known length LEN. */
3991
3992static bool
3993gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
3994{
3995 gimple *stmt = gsi_stmt (*gsi);
3996 tree arg = gimple_call_arg (stmt, 0);
3997
3998 wide_int minlen;
3999 wide_int maxlen;
4000
4001 c_strlen_data lendata = { };
4002 if (get_range_strlen (arg, &lendata, /* eltsize = */ 1)
4003 && !lendata.decl
4004 && lendata.minlen && TREE_CODE (lendata.minlen)((enum tree_code) (lendata.minlen)->base.code) == INTEGER_CST
4005 && lendata.maxlen && TREE_CODE (lendata.maxlen)((enum tree_code) (lendata.maxlen)->base.code) == INTEGER_CST)
4006 {
4007 /* The range of lengths refers to either a single constant
4008 string or to the longest and shortest constant string
4009 referenced by the argument of the strlen() call, or to
4010 the strings that can possibly be stored in the arrays
4011 the argument refers to. */
4012 minlen = wi::to_wide (lendata.minlen);
4013 maxlen = wi::to_wide (lendata.maxlen);
4014 }
4015 else
4016 {
4017 unsigned prec = TYPE_PRECISION (sizetype)((tree_class_check ((sizetype_tab[(int) stk_sizetype]), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4017, __FUNCTION__))->type_common.precision)
;
4018
4019 minlen = wi::shwi (0, prec);
4020 maxlen = wi::to_wide (max_object_size (), prec) - 2;
4021 }
4022
4023 if (minlen == maxlen)
4024 {
4025 /* Fold the strlen call to a constant. */
4026 tree type = TREE_TYPE (lendata.minlen)((contains_struct_check ((lendata.minlen), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4026, __FUNCTION__))->typed.type)
;
4027 tree len = force_gimple_operand_gsi (gsi,
4028 wide_int_to_tree (type, minlen),
4029 true, NULL__null, true, GSI_SAME_STMT);
4030 replace_call_with_value (gsi, len);
4031 return true;
4032 }
4033
4034 /* Set the strlen() range to [0, MAXLEN]. */
4035 if (tree lhs = gimple_call_lhs (stmt))
4036 set_strlen_range (lhs, minlen, maxlen);
4037
4038 return false;
4039}
4040
4041/* Fold a call to __builtin_acc_on_device. */
4042
4043static bool
4044gimple_fold_builtin_acc_on_device (gimple_stmt_iterator *gsi, tree arg0)
4045{
4046 /* Defer folding until we know which compiler we're in. */
4047 if (symtab->state != EXPANSION)
4048 return false;
4049
4050 unsigned val_host = GOMP_DEVICE_HOST2;
4051 unsigned val_dev = GOMP_DEVICE_NONE0;
4052
4053#ifdef ACCEL_COMPILER
4054 val_host = GOMP_DEVICE_NOT_HOST4;
4055 val_dev = ACCEL_COMPILER_acc_device;
4056#endif
4057
4058 location_t loc = gimple_location (gsi_stmt (*gsi));
4059
4060 tree host_eq = make_ssa_name (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]);
4061 gimple *host_ass = gimple_build_assign
4062 (host_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0)((contains_struct_check ((arg0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4062, __FUNCTION__))->typed.type)
, val_host));
4063 gimple_set_location (host_ass, loc);
4064 gsi_insert_before (gsi, host_ass, GSI_SAME_STMT);
4065
4066 tree dev_eq = make_ssa_name (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]);
4067 gimple *dev_ass = gimple_build_assign
4068 (dev_eq, EQ_EXPR, arg0, build_int_cst (TREE_TYPE (arg0)((contains_struct_check ((arg0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4068, __FUNCTION__))->typed.type)
, val_dev));
4069 gimple_set_location (dev_ass, loc);
4070 gsi_insert_before (gsi, dev_ass, GSI_SAME_STMT);
4071
4072 tree result = make_ssa_name (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE]);
4073 gimple *result_ass = gimple_build_assign
4074 (result, BIT_IOR_EXPR, host_eq, dev_eq);
4075 gimple_set_location (result_ass, loc);
4076 gsi_insert_before (gsi, result_ass, GSI_SAME_STMT);
4077
4078 replace_call_with_value (gsi, result);
4079
4080 return true;
4081}
4082
4083/* Fold realloc (0, n) -> malloc (n). */
4084
4085static bool
4086gimple_fold_builtin_realloc (gimple_stmt_iterator *gsi)
4087{
4088 gimple *stmt = gsi_stmt (*gsi);
4089 tree arg = gimple_call_arg (stmt, 0);
4090 tree size = gimple_call_arg (stmt, 1);
4091
4092 if (operand_equal_p (arg, null_pointer_nodeglobal_trees[TI_NULL_POINTER], 0))
4093 {
4094 tree fn_malloc = builtin_decl_implicit (BUILT_IN_MALLOC);
4095 if (fn_malloc)
4096 {
4097 gcall *repl = gimple_build_call (fn_malloc, 1, size);
4098 replace_call_with_call_and_fold (gsi, repl);
4099 return true;
4100 }
4101 }
4102 return false;
4103}
4104
4105/* Number of bytes into which any type but aggregate or vector types
4106 should fit. */
4107static constexpr size_t clear_padding_unit
4108 = MAX_BITSIZE_MODE_ANY_MODE(256*(8)) / BITS_PER_UNIT(8);
4109/* Buffer size on which __builtin_clear_padding folding code works. */
4110static const size_t clear_padding_buf_size = 32 * clear_padding_unit;
4111
4112/* Data passed through __builtin_clear_padding folding. */
4113struct clear_padding_struct {
4114 location_t loc;
4115 /* 0 during __builtin_clear_padding folding, nonzero during
4116 clear_type_padding_in_mask. In that case, instead of clearing the
4117 non-padding bits in union_ptr array clear the padding bits in there. */
4118 bool clear_in_mask;
4119 tree base;
4120 tree alias_type;
4121 gimple_stmt_iterator *gsi;
4122 /* Alignment of buf->base + 0. */
4123 unsigned align;
4124 /* Offset from buf->base. Should be always a multiple of UNITS_PER_WORD. */
4125 HOST_WIDE_INTlong off;
4126 /* Number of padding bytes before buf->off that don't have padding clear
4127 code emitted yet. */
4128 HOST_WIDE_INTlong padding_bytes;
4129 /* The size of the whole object. Never emit code to touch
4130 buf->base + buf->sz or following bytes. */
4131 HOST_WIDE_INTlong sz;
4132 /* Number of bytes recorded in buf->buf. */
4133 size_t size;
4134 /* When inside union, instead of emitting code we and bits inside of
4135 the union_ptr array. */
4136 unsigned char *union_ptr;
4137 /* Set bits mean padding bits that need to be cleared by the builtin. */
4138 unsigned char buf[clear_padding_buf_size + clear_padding_unit];
4139};
4140
4141/* Emit code to clear padding requested in BUF->buf - set bits
4142 in there stand for padding that should be cleared. FULL is true
4143 if everything from the buffer should be flushed, otherwise
4144 it can leave up to 2 * clear_padding_unit bytes for further
4145 processing. */
4146
4147static void
4148clear_padding_flush (clear_padding_struct *buf, bool full)
4149{
4150 gcc_assert ((clear_padding_unit % UNITS_PER_WORD) == 0)((void)(!((clear_padding_unit % (((global_options.x_ix86_isa_flags
& (1UL << 1)) != 0) ? 8 : 4)) == 0) ? fancy_abort (
"/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4150, __FUNCTION__), 0 : 0))
;
4151 if (!full && buf->size < 2 * clear_padding_unit)
4152 return;
4153 gcc_assert ((buf->off % UNITS_PER_WORD) == 0)((void)(!((buf->off % (((global_options.x_ix86_isa_flags &
(1UL << 1)) != 0) ? 8 : 4)) == 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4153, __FUNCTION__), 0 : 0))
;
4154 size_t end = buf->size;
4155 if (!full)
4156 end = ((end - clear_padding_unit - 1) / clear_padding_unit
4157 * clear_padding_unit);
4158 size_t padding_bytes = buf->padding_bytes;
4159 if (buf->union_ptr)
4160 {
4161 if (buf->clear_in_mask)
4162 {
4163 /* During clear_type_padding_in_mask, clear the padding
4164 bits set in buf->buf in the buf->union_ptr mask. */
4165 for (size_t i = 0; i < end; i++)
4166 {
4167 if (buf->buf[i] == (unsigned char) ~0)
4168 padding_bytes++;
4169 else
4170 {
4171 memset (&buf->union_ptr[buf->off + i - padding_bytes],
4172 0, padding_bytes);
4173 padding_bytes = 0;
4174 buf->union_ptr[buf->off + i] &= ~buf->buf[i];
4175 }
4176 }
4177 if (full)
4178 {
4179 memset (&buf->union_ptr[buf->off + end - padding_bytes],
4180 0, padding_bytes);
4181 buf->off = 0;
4182 buf->size = 0;
4183 buf->padding_bytes = 0;
4184 }
4185 else
4186 {
4187 memmove (buf->buf, buf->buf + end, buf->size - end);
4188 buf->off += end;
4189 buf->size -= end;
4190 buf->padding_bytes = padding_bytes;
4191 }
4192 return;
4193 }
4194 /* Inside of a union, instead of emitting any code, instead
4195 clear all bits in the union_ptr buffer that are clear
4196 in buf. Whole padding bytes don't clear anything. */
4197 for (size_t i = 0; i < end; i++)
4198 {
4199 if (buf->buf[i] == (unsigned char) ~0)
4200 padding_bytes++;
4201 else
4202 {
4203 padding_bytes = 0;
4204 buf->union_ptr[buf->off + i] &= buf->buf[i];
4205 }
4206 }
4207 if (full)
4208 {
4209 buf->off = 0;
4210 buf->size = 0;
4211 buf->padding_bytes = 0;
4212 }
4213 else
4214 {
4215 memmove (buf->buf, buf->buf + end, buf->size - end);
4216 buf->off += end;
4217 buf->size -= end;
4218 buf->padding_bytes = padding_bytes;
4219 }
4220 return;
4221 }
4222 size_t wordsize = UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4223 for (size_t i = 0; i < end; i += wordsize)
4224 {
4225 size_t nonzero_first = wordsize;
4226 size_t nonzero_last = 0;
4227 size_t zero_first = wordsize;
4228 size_t zero_last = 0;
4229 bool all_ones = true, bytes_only = true;
4230 if ((unsigned HOST_WIDE_INTlong) (buf->off + i + wordsize)
4231 > (unsigned HOST_WIDE_INTlong) buf->sz)
4232 {
4233 gcc_assert (wordsize > 1)((void)(!(wordsize > 1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4233, __FUNCTION__), 0 : 0))
;
4234 wordsize /= 2;
4235 i -= wordsize;
4236 continue;
4237 }
4238 for (size_t j = i; j < i + wordsize && j < end; j++)
4239 {
4240 if (buf->buf[j])
4241 {
4242 if (nonzero_first == wordsize)
4243 {
4244 nonzero_first = j - i;
4245 nonzero_last = j - i;
4246 }
4247 if (nonzero_last != j - i)
4248 all_ones = false;
4249 nonzero_last = j + 1 - i;
4250 }
4251 else
4252 {
4253 if (zero_first == wordsize)
4254 zero_first = j - i;
4255 zero_last = j + 1 - i;
4256 }
4257 if (buf->buf[j] != 0 && buf->buf[j] != (unsigned char) ~0)
4258 {
4259 all_ones = false;
4260 bytes_only = false;
4261 }
4262 }
4263 size_t padding_end = i;
4264 if (padding_bytes)
4265 {
4266 if (nonzero_first == 0
4267 && nonzero_last == wordsize
4268 && all_ones)
4269 {
4270 /* All bits are padding and we had some padding
4271 before too. Just extend it. */
4272 padding_bytes += wordsize;
4273 continue;
4274 }
4275 if (all_ones && nonzero_first == 0)
4276 {
4277 padding_bytes += nonzero_last;
4278 padding_end += nonzero_last;
4279 nonzero_first = wordsize;
4280 nonzero_last = 0;
4281 }
4282 else if (bytes_only && nonzero_first == 0)
4283 {
4284 gcc_assert (zero_first && zero_first != wordsize)((void)(!(zero_first && zero_first != wordsize) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4284, __FUNCTION__), 0 : 0))
;
4285 padding_bytes += zero_first;
4286 padding_end += zero_first;
4287 }
4288 tree atype, src;
4289 if (padding_bytes == 1)
4290 {
4291 atype = char_type_nodeinteger_types[itk_char];
4292 src = build_zero_cst (char_type_nodeinteger_types[itk_char]);
4293 }
4294 else
4295 {
4296 atype = build_array_type_nelts (char_type_nodeinteger_types[itk_char], padding_bytes);
4297 src = build_constructor (atype, NULL__null);
4298 }
4299 tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4300 build_int_cst (buf->alias_type,
4301 buf->off + padding_end
4302 - padding_bytes));
4303 gimple *g = gimple_build_assign (dst, src);
4304 gimple_set_location (g, buf->loc);
4305 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4306 padding_bytes = 0;
4307 buf->padding_bytes = 0;
4308 }
4309 if (nonzero_first == wordsize)
4310 /* All bits in a word are 0, there are no padding bits. */
4311 continue;
4312 if (all_ones && nonzero_last == wordsize)
4313 {
4314 /* All bits between nonzero_first and end of word are padding
4315 bits, start counting padding_bytes. */
4316 padding_bytes = nonzero_last - nonzero_first;
4317 continue;
4318 }
4319 if (bytes_only)
4320 {
4321 /* If bitfields aren't involved in this word, prefer storing
4322 individual bytes or groups of them over performing a RMW
4323 operation on the whole word. */
4324 gcc_assert (i + zero_last <= end)((void)(!(i + zero_last <= end) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4324, __FUNCTION__), 0 : 0))
;
4325 for (size_t j = padding_end; j < i + zero_last; j++)
4326 {
4327 if (buf->buf[j])
4328 {
4329 size_t k;
4330 for (k = j; k < i + zero_last; k++)
4331 if (buf->buf[k] == 0)
4332 break;
4333 HOST_WIDE_INTlong off = buf->off + j;
4334 tree atype, src;
4335 if (k - j == 1)
4336 {
4337 atype = char_type_nodeinteger_types[itk_char];
4338 src = build_zero_cst (char_type_nodeinteger_types[itk_char]);
4339 }
4340 else
4341 {
4342 atype = build_array_type_nelts (char_type_nodeinteger_types[itk_char], k - j);
4343 src = build_constructor (atype, NULL__null);
4344 }
4345 tree dst = build2_loc (buf->loc, MEM_REF, atype,
4346 buf->base,
4347 build_int_cst (buf->alias_type, off));
4348 gimple *g = gimple_build_assign (dst, src);
4349 gimple_set_location (g, buf->loc);
4350 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4351 j = k;
4352 }
4353 }
4354 if (nonzero_last == wordsize)
4355 padding_bytes = nonzero_last - zero_last;
4356 continue;
4357 }
4358 for (size_t eltsz = 1; eltsz <= wordsize; eltsz <<= 1)
4359 {
4360 if (nonzero_last - nonzero_first <= eltsz
4361 && ((nonzero_first & ~(eltsz - 1))
4362 == ((nonzero_last - 1) & ~(eltsz - 1))))
4363 {
4364 tree type;
4365 if (eltsz == 1)
4366 type = char_type_nodeinteger_types[itk_char];
4367 else
4368 type = lang_hooks.types.type_for_size (eltsz * BITS_PER_UNIT(8),
4369 0);
4370 size_t start = nonzero_first & ~(eltsz - 1);
4371 HOST_WIDE_INTlong off = buf->off + i + start;
4372 tree atype = type;
4373 if (eltsz > 1 && buf->align < TYPE_ALIGN (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4373, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4373, __FUNCTION__))->type_common.align) - 1) : 0)
)
4374 atype = build_aligned_type (type, buf->align);
4375 tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4376 build_int_cst (buf->alias_type, off));
4377 tree src;
4378 gimple *g;
4379 if (all_ones
4380 && nonzero_first == start
4381 && nonzero_last == start + eltsz)
4382 src = build_zero_cst (type);
4383 else
4384 {
4385 src = make_ssa_name (type);
4386 tree tmp_dst = unshare_expr (dst);
4387 /* The folding introduces a read from the tmp_dst, we should
4388 prevent uninitialized warning analysis from issuing warning
4389 for such fake read. In order to suppress warning only for
4390 this expr, we should set the location of tmp_dst to
4391 UNKNOWN_LOCATION first, then suppress_warning will call
4392 set_no_warning_bit to set the no_warning flag only for
4393 tmp_dst. */
4394 SET_EXPR_LOCATION (tmp_dst, UNKNOWN_LOCATION)(expr_check (((tmp_dst)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4394, __FUNCTION__))->exp.locus = (((location_t) 0))
;
4395 suppress_warning (tmp_dst, OPT_Wuninitialized);
4396 g = gimple_build_assign (src, tmp_dst);
4397 gimple_set_location (g, buf->loc);
4398 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4399 tree mask = native_interpret_expr (type,
4400 buf->buf + i + start,
4401 eltsz);
4402 gcc_assert (mask && TREE_CODE (mask) == INTEGER_CST)((void)(!(mask && ((enum tree_code) (mask)->base.code
) == INTEGER_CST) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4402, __FUNCTION__), 0 : 0))
;
4403 mask = fold_build1 (BIT_NOT_EXPR, type, mask)fold_build1_loc (((location_t) 0), BIT_NOT_EXPR, type, mask );
4404 tree src_masked = make_ssa_name (type);
4405 g = gimple_build_assign (src_masked, BIT_AND_EXPR,
4406 src, mask);
4407 gimple_set_location (g, buf->loc);
4408 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4409 src = src_masked;
4410 }
4411 g = gimple_build_assign (dst, src);
4412 gimple_set_location (g, buf->loc);
4413 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4414 break;
4415 }
4416 }
4417 }
4418 if (full)
4419 {
4420 if (padding_bytes)
4421 {
4422 tree atype, src;
4423 if (padding_bytes == 1)
4424 {
4425 atype = char_type_nodeinteger_types[itk_char];
4426 src = build_zero_cst (char_type_nodeinteger_types[itk_char]);
4427 }
4428 else
4429 {
4430 atype = build_array_type_nelts (char_type_nodeinteger_types[itk_char], padding_bytes);
4431 src = build_constructor (atype, NULL__null);
4432 }
4433 tree dst = build2_loc (buf->loc, MEM_REF, atype, buf->base,
4434 build_int_cst (buf->alias_type,
4435 buf->off + end
4436 - padding_bytes));
4437 gimple *g = gimple_build_assign (dst, src);
4438 gimple_set_location (g, buf->loc);
4439 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4440 }
4441 size_t end_rem = end % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4442 buf->off += end - end_rem;
4443 buf->size = end_rem;
4444 memset (buf->buf, 0, buf->size);
4445 buf->padding_bytes = 0;
4446 }
4447 else
4448 {
4449 memmove (buf->buf, buf->buf + end, buf->size - end);
4450 buf->off += end;
4451 buf->size -= end;
4452 buf->padding_bytes = padding_bytes;
4453 }
4454}
4455
4456/* Append PADDING_BYTES padding bytes. */
4457
4458static void
4459clear_padding_add_padding (clear_padding_struct *buf,
4460 HOST_WIDE_INTlong padding_bytes)
4461{
4462 if (padding_bytes == 0)
4463 return;
4464 if ((unsigned HOST_WIDE_INTlong) padding_bytes + buf->size
4465 > (unsigned HOST_WIDE_INTlong) clear_padding_buf_size)
4466 clear_padding_flush (buf, false);
4467 if ((unsigned HOST_WIDE_INTlong) padding_bytes + buf->size
4468 > (unsigned HOST_WIDE_INTlong) clear_padding_buf_size)
4469 {
4470 memset (buf->buf + buf->size, ~0, clear_padding_buf_size - buf->size);
4471 padding_bytes -= clear_padding_buf_size - buf->size;
4472 buf->size = clear_padding_buf_size;
4473 clear_padding_flush (buf, false);
4474 gcc_assert (buf->padding_bytes)((void)(!(buf->padding_bytes) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4474, __FUNCTION__), 0 : 0))
;
4475 /* At this point buf->buf[0] through buf->buf[buf->size - 1]
4476 is guaranteed to be all ones. */
4477 padding_bytes += buf->size;
4478 buf->size = padding_bytes % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4479 memset (buf->buf, ~0, buf->size);
4480 buf->off += padding_bytes - buf->size;
4481 buf->padding_bytes += padding_bytes - buf->size;
4482 }
4483 else
4484 {
4485 memset (buf->buf + buf->size, ~0, padding_bytes);
4486 buf->size += padding_bytes;
4487 }
4488}
4489
4490static void clear_padding_type (clear_padding_struct *, tree,
4491 HOST_WIDE_INTlong, bool);
4492
4493/* Clear padding bits of union type TYPE. */
4494
4495static void
4496clear_padding_union (clear_padding_struct *buf, tree type,
4497 HOST_WIDE_INTlong sz, bool for_auto_init)
4498{
4499 clear_padding_struct *union_buf;
4500 HOST_WIDE_INTlong start_off = 0, next_off = 0;
4501 size_t start_size = 0;
4502 if (buf->union_ptr)
4503 {
4504 start_off = buf->off + buf->size;
4505 next_off = start_off + sz;
4506 start_size = start_off % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4507 start_off -= start_size;
4508 clear_padding_flush (buf, true);
4509 union_buf = buf;
4510 }
4511 else
4512 {
4513 if (sz + buf->size > clear_padding_buf_size)
4514 clear_padding_flush (buf, false);
4515 union_buf = XALLOCA (clear_padding_struct)((clear_padding_struct *) __builtin_alloca(sizeof (clear_padding_struct
)))
;
4516 union_buf->loc = buf->loc;
4517 union_buf->clear_in_mask = buf->clear_in_mask;
4518 union_buf->base = NULL_TREE(tree) __null;
4519 union_buf->alias_type = NULL_TREE(tree) __null;
4520 union_buf->gsi = NULL__null;
4521 union_buf->align = 0;
4522 union_buf->off = 0;
4523 union_buf->padding_bytes = 0;
4524 union_buf->sz = sz;
4525 union_buf->size = 0;
4526 if (sz + buf->size <= clear_padding_buf_size)
4527 union_buf->union_ptr = buf->buf + buf->size;
4528 else
4529 union_buf->union_ptr = XNEWVEC (unsigned char, sz)((unsigned char *) xmalloc (sizeof (unsigned char) * (sz)));
4530 memset (union_buf->union_ptr, ~0, sz);
4531 }
4532
4533 for (tree field = TYPE_FIELDS (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4533, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))->type_non_common.values)
; field; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), (
TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4533, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4533, __FUNCTION__))->common.chain))
)
4534 if (TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL && !DECL_PADDING_P (field)((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4534, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_3
)
)
4535 {
4536 if (DECL_SIZE_UNIT (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4536, __FUNCTION__))->decl_common.size_unit)
== NULL_TREE(tree) __null)
4537 {
4538 if (TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4538, __FUNCTION__))->typed.type)
== error_mark_nodeglobal_trees[TI_ERROR_MARK])
4539 continue;
4540 gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE((void)(!(((enum tree_code) (((contains_struct_check ((field)
, (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4540, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE
&& !(((tree_class_check ((((contains_struct_check ((
field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__))->type_common.size) != (tree) __null
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__), 0 : 0))
4541 && !COMPLETE_TYPE_P (TREE_TYPE (field)))((void)(!(((enum tree_code) (((contains_struct_check ((field)
, (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4540, __FUNCTION__))->typed.type))->base.code) == ARRAY_TYPE
&& !(((tree_class_check ((((contains_struct_check ((
field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__))->type_common.size) != (tree) __null
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4541, __FUNCTION__), 0 : 0))
;
4542 if (!buf->clear_in_mask && !for_auto_init)
4543 error_at (buf->loc, "flexible array member %qD does not have "
4544 "well defined padding bits for %qs",
4545 field, "__builtin_clear_padding");
4546 continue;
4547 }
4548 HOST_WIDE_INTlong fldsz = tree_to_shwi (DECL_SIZE_UNIT (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4548, __FUNCTION__))->decl_common.size_unit)
);
4549 gcc_assert (union_buf->size == 0)((void)(!(union_buf->size == 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4549, __FUNCTION__), 0 : 0))
;
4550 union_buf->off = start_off;
4551 union_buf->size = start_size;
4552 memset (union_buf->buf, ~0, start_size);
4553 clear_padding_type (union_buf, TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4553, __FUNCTION__))->typed.type)
, fldsz, for_auto_init);
4554 clear_padding_add_padding (union_buf, sz - fldsz);
4555 clear_padding_flush (union_buf, true);
4556 }
4557
4558 if (buf == union_buf)
4559 {
4560 buf->off = next_off;
4561 buf->size = next_off % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4562 buf->off -= buf->size;
4563 memset (buf->buf, ~0, buf->size);
4564 }
4565 else if (sz + buf->size <= clear_padding_buf_size)
4566 buf->size += sz;
4567 else
4568 {
4569 unsigned char *union_ptr = union_buf->union_ptr;
4570 while (sz)
4571 {
4572 clear_padding_flush (buf, false);
4573 HOST_WIDE_INTlong this_sz
4574 = MIN ((unsigned HOST_WIDE_INT) sz,(((unsigned long) sz) < (clear_padding_buf_size - buf->
size) ? ((unsigned long) sz) : (clear_padding_buf_size - buf->
size))
4575 clear_padding_buf_size - buf->size)(((unsigned long) sz) < (clear_padding_buf_size - buf->
size) ? ((unsigned long) sz) : (clear_padding_buf_size - buf->
size))
;
4576 memcpy (buf->buf + buf->size, union_ptr, this_sz);
4577 buf->size += this_sz;
4578 union_ptr += this_sz;
4579 sz -= this_sz;
4580 }
4581 XDELETE (union_buf->union_ptr)free ((void*) (union_buf->union_ptr));
4582 }
4583}
4584
4585/* The only known floating point formats with padding bits are the
4586 IEEE extended ones. */
4587
4588static bool
4589clear_padding_real_needs_padding_p (tree type)
4590{
4591 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type))(real_format_for_mode[(((enum mode_class) mode_class[((((enum
tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4591, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_DECIMAL_FLOAT
) ? (((((((enum tree_code) ((tree_class_check ((type), (tcc_type
), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4591, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)) - MIN_MODE_DECIMAL_FLOAT
) + (MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1)) : ((enum mode_class
) mode_class[((((enum tree_code) ((tree_class_check ((type), (
tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4591, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)]) == MODE_FLOAT ? ((((
((enum tree_code) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4591, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(type) : (type)->type_common.mode)) - MIN_MODE_FLOAT) : (
(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4591, __FUNCTION__)), 0)])
;
4592 return (fmt->b == 2
4593 && fmt->signbit_ro == fmt->signbit_rw
4594 && (fmt->signbit_ro == 79 || fmt->signbit_ro == 95));
4595}
4596
4597/* Return true if TYPE might contain any padding bits. */
4598
4599bool
4600clear_padding_type_may_have_padding_p (tree type)
4601{
4602 switch (TREE_CODE (type)((enum tree_code) (type)->base.code))
4603 {
4604 case RECORD_TYPE:
4605 case UNION_TYPE:
4606 return true;
4607 case ARRAY_TYPE:
4608 case COMPLEX_TYPE:
4609 case VECTOR_TYPE:
4610 return clear_padding_type_may_have_padding_p (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4610, __FUNCTION__))->typed.type)
);
4611 case REAL_TYPE:
4612 return clear_padding_real_needs_padding_p (type);
4613 default:
4614 return false;
4615 }
4616}
4617
4618/* Emit a runtime loop:
4619 for (; buf.base != end; buf.base += sz)
4620 __builtin_clear_padding (buf.base); */
4621
4622static void
4623clear_padding_emit_loop (clear_padding_struct *buf, tree type,
4624 tree end, bool for_auto_init)
4625{
4626 tree l1 = create_artificial_label (buf->loc);
4627 tree l2 = create_artificial_label (buf->loc);
4628 tree l3 = create_artificial_label (buf->loc);
4629 gimple *g = gimple_build_goto (l2);
4630 gimple_set_location (g, buf->loc);
4631 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4632 g = gimple_build_label (l1);
4633 gimple_set_location (g, buf->loc);
4634 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4635 clear_padding_type (buf, type, buf->sz, for_auto_init);
4636 clear_padding_flush (buf, true);
4637 g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR, buf->base,
4638 size_int (buf->sz)size_int_kind (buf->sz, stk_sizetype));
4639 gimple_set_location (g, buf->loc);
4640 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4641 g = gimple_build_label (l2);
4642 gimple_set_location (g, buf->loc);
4643 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4644 g = gimple_build_cond (NE_EXPR, buf->base, end, l1, l3);
4645 gimple_set_location (g, buf->loc);
4646 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4647 g = gimple_build_label (l3);
4648 gimple_set_location (g, buf->loc);
4649 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4650}
4651
4652/* Clear padding bits for TYPE. Called recursively from
4653 gimple_fold_builtin_clear_padding. If FOR_AUTO_INIT is true,
4654 the __builtin_clear_padding is not called by the end user,
4655 instead, it's inserted by the compiler to initialize the
4656 paddings of automatic variable. Therefore, we should not
4657 emit the error messages for flexible array members to confuse
4658 the end user. */
4659
4660static void
4661clear_padding_type (clear_padding_struct *buf, tree type,
4662 HOST_WIDE_INTlong sz, bool for_auto_init)
4663{
4664 switch (TREE_CODE (type)((enum tree_code) (type)->base.code))
4665 {
4666 case RECORD_TYPE:
4667 HOST_WIDE_INTlong cur_pos;
4668 cur_pos = 0;
4669 for (tree field = TYPE_FIELDS (type)((tree_check3 ((type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4669, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))->type_non_common.values)
; field; field = DECL_CHAIN (field)(((contains_struct_check (((contains_struct_check ((field), (
TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4669, __FUNCTION__))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4669, __FUNCTION__))->common.chain))
)
4670 if (TREE_CODE (field)((enum tree_code) (field)->base.code) == FIELD_DECL && !DECL_PADDING_P (field)((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4670, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_3
)
)
4671 {
4672 tree ftype = TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4672, __FUNCTION__))->typed.type)
;
4673 if (DECL_BIT_FIELD (field)((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4673, __FUNCTION__, (FIELD_DECL)))->decl_common.decl_flag_1
)
)
4674 {
4675 HOST_WIDE_INTlong fldsz = TYPE_PRECISION (ftype)((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4675, __FUNCTION__))->type_common.precision)
;
4676 if (fldsz == 0)
4677 continue;
4678 HOST_WIDE_INTlong pos = int_byte_position (field);
4679 if (pos >= sz)
4680 continue;
4681 HOST_WIDE_INTlong bpos
4682 = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field)((tree_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4682, __FUNCTION__, (FIELD_DECL)))->field_decl.bit_offset
)
);
4683 bpos %= BITS_PER_UNIT(8);
4684 HOST_WIDE_INTlong end
4685 = ROUND_UP (bpos + fldsz, BITS_PER_UNIT)(((bpos + fldsz) + ((8)) - 1) & ~(((8)) - 1)) / BITS_PER_UNIT(8);
4686 if (pos + end > cur_pos)
4687 {
4688 clear_padding_add_padding (buf, pos + end - cur_pos);
4689 cur_pos = pos + end;
4690 }
4691 gcc_assert (cur_pos > pos((void)(!(cur_pos > pos && ((unsigned long) buf->
size >= (unsigned long) cur_pos - pos)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4693, __FUNCTION__), 0 : 0))
4692 && ((unsigned HOST_WIDE_INT) buf->size((void)(!(cur_pos > pos && ((unsigned long) buf->
size >= (unsigned long) cur_pos - pos)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4693, __FUNCTION__), 0 : 0))
4693 >= (unsigned HOST_WIDE_INT) cur_pos - pos))((void)(!(cur_pos > pos && ((unsigned long) buf->
size >= (unsigned long) cur_pos - pos)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4693, __FUNCTION__), 0 : 0))
;
4694 unsigned char *p = buf->buf + buf->size - (cur_pos - pos);
4695 if (BYTES_BIG_ENDIAN0 != WORDS_BIG_ENDIAN0)
4696 sorry_at (buf->loc, "PDP11 bit-field handling unsupported"
4697 " in %qs", "__builtin_clear_padding");
4698 else if (BYTES_BIG_ENDIAN0)
4699 {
4700 /* Big endian. */
4701 if (bpos + fldsz <= BITS_PER_UNIT(8))
4702 *p &= ~(((1 << fldsz) - 1)
4703 << (BITS_PER_UNIT(8) - bpos - fldsz));
4704 else
4705 {
4706 if (bpos)
4707 {
4708 *p &= ~(((1U << BITS_PER_UNIT(8)) - 1) >> bpos);
4709 p++;
4710 fldsz -= BITS_PER_UNIT(8) - bpos;
4711 }
4712 memset (p, 0, fldsz / BITS_PER_UNIT(8));
4713 p += fldsz / BITS_PER_UNIT(8);
4714 fldsz %= BITS_PER_UNIT(8);
4715 if (fldsz)
4716 *p &= ((1U << BITS_PER_UNIT(8)) - 1) >> fldsz;
4717 }
4718 }
4719 else
4720 {
4721 /* Little endian. */
4722 if (bpos + fldsz <= BITS_PER_UNIT(8))
4723 *p &= ~(((1 << fldsz) - 1) << bpos);
4724 else
4725 {
4726 if (bpos)
4727 {
4728 *p &= ~(((1 << BITS_PER_UNIT(8)) - 1) << bpos);
4729 p++;
4730 fldsz -= BITS_PER_UNIT(8) - bpos;
4731 }
4732 memset (p, 0, fldsz / BITS_PER_UNIT(8));
4733 p += fldsz / BITS_PER_UNIT(8);
4734 fldsz %= BITS_PER_UNIT(8);
4735 if (fldsz)
4736 *p &= ~((1 << fldsz) - 1);
4737 }
4738 }
4739 }
4740 else if (DECL_SIZE_UNIT (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4740, __FUNCTION__))->decl_common.size_unit)
== NULL_TREE(tree) __null)
4741 {
4742 if (ftype == error_mark_nodeglobal_trees[TI_ERROR_MARK])
4743 continue;
4744 gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE((void)(!(((enum tree_code) (ftype)->base.code) == ARRAY_TYPE
&& !(((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4745, __FUNCTION__))->type_common.size) != (tree) __null
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4745, __FUNCTION__), 0 : 0))
4745 && !COMPLETE_TYPE_P (ftype))((void)(!(((enum tree_code) (ftype)->base.code) == ARRAY_TYPE
&& !(((tree_class_check ((ftype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4745, __FUNCTION__))->type_common.size) != (tree) __null
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4745, __FUNCTION__), 0 : 0))
;
4746 if (!buf->clear_in_mask && !for_auto_init)
4747 error_at (buf->loc, "flexible array member %qD does not "
4748 "have well defined padding bits for %qs",
4749 field, "__builtin_clear_padding");
4750 }
4751 else if (is_empty_type (ftype))
4752 continue;
4753 else
4754 {
4755 HOST_WIDE_INTlong pos = int_byte_position (field);
4756 if (pos >= sz)
4757 continue;
4758 HOST_WIDE_INTlong fldsz = tree_to_shwi (DECL_SIZE_UNIT (field)((contains_struct_check ((field), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4758, __FUNCTION__))->decl_common.size_unit)
);
4759 gcc_assert (pos >= 0 && fldsz >= 0 && pos >= cur_pos)((void)(!(pos >= 0 && fldsz >= 0 && pos
>= cur_pos) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4759, __FUNCTION__), 0 : 0))
;
4760 clear_padding_add_padding (buf, pos - cur_pos);
4761 cur_pos = pos;
4762 if (tree asbase = lang_hooks.types.classtype_as_base (field))
4763 ftype = asbase;
4764 clear_padding_type (buf, ftype, fldsz, for_auto_init);
4765 cur_pos += fldsz;
4766 }
4767 }
4768 gcc_assert (sz >= cur_pos)((void)(!(sz >= cur_pos) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4768, __FUNCTION__), 0 : 0))
;
4769 clear_padding_add_padding (buf, sz - cur_pos);
4770 break;
4771 case ARRAY_TYPE:
4772 HOST_WIDE_INTlong nelts, fldsz;
4773 fldsz = int_size_in_bytes (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4773, __FUNCTION__))->typed.type)
);
4774 if (fldsz == 0)
4775 break;
4776 nelts = sz / fldsz;
4777 if (nelts > 1
4778 && sz > 8 * UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
4779 && buf->union_ptr == NULL__null
4780 && clear_padding_type_may_have_padding_p (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4780, __FUNCTION__))->typed.type)
))
4781 {
4782 /* For sufficiently large array of more than one elements,
4783 emit a runtime loop to keep code size manageable. */
4784 tree base = buf->base;
4785 unsigned int prev_align = buf->align;
4786 HOST_WIDE_INTlong off = buf->off + buf->size;
4787 HOST_WIDE_INTlong prev_sz = buf->sz;
4788 clear_padding_flush (buf, true);
4789 tree elttype = TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4789, __FUNCTION__))->typed.type)
;
4790 buf->base = create_tmp_var (build_pointer_type (elttype));
4791 tree end = make_ssa_name (TREE_TYPE (buf->base)((contains_struct_check ((buf->base), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4791, __FUNCTION__))->typed.type)
);
4792 gimple *g = gimple_build_assign (buf->base, POINTER_PLUS_EXPR,
4793 base, size_int (off)size_int_kind (off, stk_sizetype));
4794 gimple_set_location (g, buf->loc);
4795 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4796 g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf->base,
4797 size_int (sz)size_int_kind (sz, stk_sizetype));
4798 gimple_set_location (g, buf->loc);
4799 gsi_insert_before (buf->gsi, g, GSI_SAME_STMT);
4800 buf->sz = fldsz;
4801 buf->align = TYPE_ALIGN (elttype)(((tree_class_check ((elttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4801, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((elttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4801, __FUNCTION__))->type_common.align) - 1) : 0)
;
4802 buf->off = 0;
4803 buf->size = 0;
4804 clear_padding_emit_loop (buf, elttype, end, for_auto_init);
4805 buf->base = base;
4806 buf->sz = prev_sz;
4807 buf->align = prev_align;
4808 buf->size = off % UNITS_PER_WORD(((global_options.x_ix86_isa_flags & (1UL << 1)) !=
0) ? 8 : 4)
;
4809 buf->off = off - buf->size;
4810 memset (buf->buf, 0, buf->size);
4811 break;
4812 }
4813 for (HOST_WIDE_INTlong i = 0; i < nelts; i++)
4814 clear_padding_type (buf, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4814, __FUNCTION__))->typed.type)
, fldsz, for_auto_init);
4815 break;
4816 case UNION_TYPE:
4817 clear_padding_union (buf, type, sz, for_auto_init);
4818 break;
4819 case REAL_TYPE:
4820 gcc_assert ((size_t) sz <= clear_padding_unit)((void)(!((size_t) sz <= clear_padding_unit) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4820, __FUNCTION__), 0 : 0))
;
4821 if ((unsigned HOST_WIDE_INTlong) sz + buf->size > clear_padding_buf_size)
4822 clear_padding_flush (buf, false);
4823 if (clear_padding_real_needs_padding_p (type))
4824 {
4825 /* Use native_interpret_real + native_encode_expr to figure out
4826 which bits are padding. */
4827 memset (buf->buf + buf->size, ~0, sz);
4828 tree cst = native_interpret_real (type, buf->buf + buf->size, sz);
4829 gcc_assert (cst && TREE_CODE (cst) == REAL_CST)((void)(!(cst && ((enum tree_code) (cst)->base.code
) == REAL_CST) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4829, __FUNCTION__), 0 : 0))
;
4830 int len = native_encode_expr (cst, buf->buf + buf->size, sz);
4831 gcc_assert (len > 0 && (size_t) len == (size_t) sz)((void)(!(len > 0 && (size_t) len == (size_t) sz) ?
fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4831, __FUNCTION__), 0 : 0))
;
4832 for (size_t i = 0; i < (size_t) sz; i++)
4833 buf->buf[buf->size + i] ^= ~0;
4834 }
4835 else
4836 memset (buf->buf + buf->size, 0, sz);
4837 buf->size += sz;
4838 break;
4839 case COMPLEX_TYPE:
4840 fldsz = int_size_in_bytes (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4840, __FUNCTION__))->typed.type)
);
4841 clear_padding_type (buf, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4841, __FUNCTION__))->typed.type)
, fldsz, for_auto_init);
4842 clear_padding_type (buf, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4842, __FUNCTION__))->typed.type)
, fldsz, for_auto_init);
4843 break;
4844 case VECTOR_TYPE:
4845 nelts = TYPE_VECTOR_SUBPARTS (type).to_constant ();
4846 fldsz = int_size_in_bytes (TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4846, __FUNCTION__))->typed.type)
);
4847 for (HOST_WIDE_INTlong i = 0; i < nelts; i++)
4848 clear_padding_type (buf, TREE_TYPE (type)((contains_struct_check ((type), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4848, __FUNCTION__))->typed.type)
, fldsz, for_auto_init);
4849 break;
4850 case NULLPTR_TYPE:
4851 gcc_assert ((size_t) sz <= clear_padding_unit)((void)(!((size_t) sz <= clear_padding_unit) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4851, __FUNCTION__), 0 : 0))
;
4852 if ((unsigned HOST_WIDE_INTlong) sz + buf->size > clear_padding_buf_size)
4853 clear_padding_flush (buf, false);
4854 memset (buf->buf + buf->size, ~0, sz);
4855 buf->size += sz;
4856 break;
4857 default:
4858 gcc_assert ((size_t) sz <= clear_padding_unit)((void)(!((size_t) sz <= clear_padding_unit) ? fancy_abort
("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4858, __FUNCTION__), 0 : 0))
;
4859 if ((unsigned HOST_WIDE_INTlong) sz + buf->size > clear_padding_buf_size)
4860 clear_padding_flush (buf, false);
4861 memset (buf->buf + buf->size, 0, sz);
4862 buf->size += sz;
4863 break;
4864 }
4865}
4866
4867/* Clear padding bits of TYPE in MASK. */
4868
4869void
4870clear_type_padding_in_mask (tree type, unsigned char *mask)
4871{
4872 clear_padding_struct buf;
4873 buf.loc = UNKNOWN_LOCATION((location_t) 0);
4874 buf.clear_in_mask = true;
4875 buf.base = NULL_TREE(tree) __null;
4876 buf.alias_type = NULL_TREE(tree) __null;
4877 buf.gsi = NULL__null;
4878 buf.align = 0;
4879 buf.off = 0;
4880 buf.padding_bytes = 0;
4881 buf.sz = int_size_in_bytes (type);
4882 buf.size = 0;
4883 buf.union_ptr = mask;
4884 clear_padding_type (&buf, type, buf.sz, false);
4885 clear_padding_flush (&buf, true);
4886}
4887
4888/* Fold __builtin_clear_padding builtin. */
4889
4890static bool
4891gimple_fold_builtin_clear_padding (gimple_stmt_iterator *gsi)
4892{
4893 gimple *stmt = gsi_stmt (*gsi);
4894 gcc_assert (gimple_call_num_args (stmt) == 2)((void)(!(gimple_call_num_args (stmt) == 2) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4894, __FUNCTION__), 0 : 0))
;
4895 tree ptr = gimple_call_arg (stmt, 0);
4896 tree typearg = gimple_call_arg (stmt, 1);
4897 /* The 2nd argument of __builtin_clear_padding's value is used to
4898 distinguish whether this call is made by the user or by the compiler
4899 for automatic variable initialization. */
4900 bool for_auto_init = (bool) TREE_INT_CST_LOW (typearg)((unsigned long) (*tree_int_cst_elt_check ((typearg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4900, __FUNCTION__)))
;
4901 tree type = TREE_TYPE (TREE_TYPE (typearg))((contains_struct_check ((((contains_struct_check ((typearg),
(TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4901, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4901, __FUNCTION__))->typed.type)
;
4902 location_t loc = gimple_location (stmt);
4903 clear_padding_struct buf;
4904 gimple_stmt_iterator gsiprev = *gsi;
4905 /* This should be folded during the lower pass. */
4906 gcc_assert (!gimple_in_ssa_p (cfun) && cfun->cfg == NULL)((void)(!(!gimple_in_ssa_p ((cfun + 0)) && (cfun + 0)
->cfg == __null) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4906, __FUNCTION__), 0 : 0))
;
4907 gcc_assert (COMPLETE_TYPE_P (type))((void)(!((((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4907, __FUNCTION__))->type_common.size) != (tree) __null
)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4907, __FUNCTION__), 0 : 0))
;
4908 gsi_prev (&gsiprev);
4909
4910 buf.loc = loc;
4911 buf.clear_in_mask = false;
4912 buf.base = ptr;
4913 buf.alias_type = NULL_TREE(tree) __null;
4914 buf.gsi = gsi;
4915 buf.align = get_pointer_alignment (ptr);
4916 unsigned int talign = min_align_of_type (type) * BITS_PER_UNIT(8);
4917 buf.align = MAX (buf.align, talign)((buf.align) > (talign) ? (buf.align) : (talign));
4918 buf.off = 0;
4919 buf.padding_bytes = 0;
4920 buf.size = 0;
4921 buf.sz = int_size_in_bytes (type);
4922 buf.union_ptr = NULL__null;
4923 if (buf.sz < 0 && int_size_in_bytes (strip_array_types (type)) < 0)
4924 sorry_at (loc, "%s not supported for variable length aggregates",
4925 "__builtin_clear_padding");
4926 /* The implementation currently assumes 8-bit host and target
4927 chars which is the case for all currently supported targets
4928 and hosts and is required e.g. for native_{encode,interpret}* APIs. */
4929 else if (CHAR_BIT8 != 8 || BITS_PER_UNIT(8) != 8)
4930 sorry_at (loc, "%s not supported on this target",
4931 "__builtin_clear_padding");
4932 else if (!clear_padding_type_may_have_padding_p (type))
4933 ;
4934 else if (TREE_CODE (type)((enum tree_code) (type)->base.code) == ARRAY_TYPE && buf.sz < 0)
4935 {
4936 tree sz = TYPE_SIZE_UNIT (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4936, __FUNCTION__))->type_common.size_unit)
;
4937 tree elttype = type;
4938 /* Only supports C/C++ VLAs and flattens all the VLA levels. */
4939 while (TREE_CODE (elttype)((enum tree_code) (elttype)->base.code) == ARRAY_TYPE
4940 && int_size_in_bytes (elttype) < 0)
4941 elttype = TREE_TYPE (elttype)((contains_struct_check ((elttype), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4941, __FUNCTION__))->typed.type)
;
4942 HOST_WIDE_INTlong eltsz = int_size_in_bytes (elttype);
4943 gcc_assert (eltsz >= 0)((void)(!(eltsz >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4943, __FUNCTION__), 0 : 0))
;
4944 if (eltsz)
4945 {
4946 buf.base = create_tmp_var (build_pointer_type (elttype));
4947 tree end = make_ssa_name (TREE_TYPE (buf.base)((contains_struct_check ((buf.base), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4947, __FUNCTION__))->typed.type)
);
4948 gimple *g = gimple_build_assign (buf.base, ptr);
4949 gimple_set_location (g, loc);
4950 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4951 g = gimple_build_assign (end, POINTER_PLUS_EXPR, buf.base, sz);
4952 gimple_set_location (g, loc);
4953 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4954 buf.sz = eltsz;
4955 buf.align = TYPE_ALIGN (elttype)(((tree_class_check ((elttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4955, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((elttype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4955, __FUNCTION__))->type_common.align) - 1) : 0)
;
4956 buf.alias_type = build_pointer_type (elttype);
4957 clear_padding_emit_loop (&buf, elttype, end, for_auto_init);
4958 }
4959 }
4960 else
4961 {
4962 if (!is_gimple_mem_ref_addr (buf.base))
4963 {
4964 buf.base = make_ssa_name (TREE_TYPE (ptr)((contains_struct_check ((ptr), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 4964, __FUNCTION__))->typed.type)
);
4965 gimple *g = gimple_build_assign (buf.base, ptr);
4966 gimple_set_location (g, loc);
4967 gsi_insert_before (gsi, g, GSI_SAME_STMT);
4968 }
4969 buf.alias_type = build_pointer_type (type);
4970 clear_padding_type (&buf, type, buf.sz, for_auto_init);
4971 clear_padding_flush (&buf, true);
4972 }
4973
4974 gimple_stmt_iterator gsiprev2 = *gsi;
4975 gsi_prev (&gsiprev2);
4976 if (gsi_stmt (gsiprev) == gsi_stmt (gsiprev2))
4977 gsi_replace (gsi, gimple_build_nop (), true);
4978 else
4979 {
4980 gsi_remove (gsi, true);
4981 *gsi = gsiprev2;
4982 }
4983 return true;
4984}
4985
4986/* Fold the non-target builtin at *GSI and return whether any simplification
4987 was made. */
4988
4989static bool
4990gimple_fold_builtin (gimple_stmt_iterator *gsi)
4991{
4992 gcall *stmt = as_a <gcall *>(gsi_stmt (*gsi));
4993 tree callee = gimple_call_fndecl (stmt);
4994
4995 /* Give up for always_inline inline builtins until they are
4996 inlined. */
4997 if (avoid_folding_inline_builtin (callee))
4998 return false;
4999
5000 unsigned n = gimple_call_num_args (stmt);
5001 enum built_in_function fcode = DECL_FUNCTION_CODE (callee);
5002 switch (fcode)
5003 {
5004 case BUILT_IN_BCMP:
5005 return gimple_fold_builtin_bcmp (gsi);
5006 case BUILT_IN_BCOPY:
5007 return gimple_fold_builtin_bcopy (gsi);
5008 case BUILT_IN_BZERO:
5009 return gimple_fold_builtin_bzero (gsi);
5010
5011 case BUILT_IN_MEMSET:
5012 return gimple_fold_builtin_memset (gsi,
5013 gimple_call_arg (stmt, 1),
5014 gimple_call_arg (stmt, 2));
5015 case BUILT_IN_MEMCPY:
5016 case BUILT_IN_MEMPCPY:
5017 case BUILT_IN_MEMMOVE:
5018 return gimple_fold_builtin_memory_op (gsi, gimple_call_arg (stmt, 0),
5019 gimple_call_arg (stmt, 1), fcode);
5020 case BUILT_IN_SPRINTF_CHK:
5021 case BUILT_IN_VSPRINTF_CHK:
5022 return gimple_fold_builtin_sprintf_chk (gsi, fcode);
5023 case BUILT_IN_STRCAT_CHK:
5024 return gimple_fold_builtin_strcat_chk (gsi);
5025 case BUILT_IN_STRNCAT_CHK:
5026 return gimple_fold_builtin_strncat_chk (gsi);
5027 case BUILT_IN_STRLEN:
5028 return gimple_fold_builtin_strlen (gsi);
5029 case BUILT_IN_STRCPY:
5030 return gimple_fold_builtin_strcpy (gsi,
5031 gimple_call_arg (stmt, 0),
5032 gimple_call_arg (stmt, 1));
5033 case BUILT_IN_STRNCPY:
5034 return gimple_fold_builtin_strncpy (gsi,
5035 gimple_call_arg (stmt, 0),
5036 gimple_call_arg (stmt, 1),
5037 gimple_call_arg (stmt, 2));
5038 case BUILT_IN_STRCAT:
5039 return gimple_fold_builtin_strcat (gsi, gimple_call_arg (stmt, 0),
5040 gimple_call_arg (stmt, 1));
5041 case BUILT_IN_STRNCAT:
5042 return gimple_fold_builtin_strncat (gsi);
5043 case BUILT_IN_INDEX:
5044 case BUILT_IN_STRCHR:
5045 return gimple_fold_builtin_strchr (gsi, false);
5046 case BUILT_IN_RINDEX:
5047 case BUILT_IN_STRRCHR:
5048 return gimple_fold_builtin_strchr (gsi, true);
5049 case BUILT_IN_STRSTR:
5050 return gimple_fold_builtin_strstr (gsi);
5051 case BUILT_IN_STRCMP:
5052 case BUILT_IN_STRCMP_EQ:
5053 case BUILT_IN_STRCASECMP:
5054 case BUILT_IN_STRNCMP:
5055 case BUILT_IN_STRNCMP_EQ:
5056 case BUILT_IN_STRNCASECMP:
5057 return gimple_fold_builtin_string_compare (gsi);
5058 case BUILT_IN_MEMCHR:
5059 return gimple_fold_builtin_memchr (gsi);
5060 case BUILT_IN_FPUTS:
5061 return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5062 gimple_call_arg (stmt, 1), false);
5063 case BUILT_IN_FPUTS_UNLOCKED:
5064 return gimple_fold_builtin_fputs (gsi, gimple_call_arg (stmt, 0),
5065 gimple_call_arg (stmt, 1), true);
5066 case BUILT_IN_MEMCPY_CHK:
5067 case BUILT_IN_MEMPCPY_CHK:
5068 case BUILT_IN_MEMMOVE_CHK:
5069 case BUILT_IN_MEMSET_CHK:
5070 return gimple_fold_builtin_memory_chk (gsi,
5071 gimple_call_arg (stmt, 0),
5072 gimple_call_arg (stmt, 1),
5073 gimple_call_arg (stmt, 2),
5074 gimple_call_arg (stmt, 3),
5075 fcode);
5076 case BUILT_IN_STPCPY:
5077 return gimple_fold_builtin_stpcpy (gsi);
5078 case BUILT_IN_STRCPY_CHK:
5079 case BUILT_IN_STPCPY_CHK:
5080 return gimple_fold_builtin_stxcpy_chk (gsi,
5081 gimple_call_arg (stmt, 0),
5082 gimple_call_arg (stmt, 1),
5083 gimple_call_arg (stmt, 2),
5084 fcode);
5085 case BUILT_IN_STRNCPY_CHK:
5086 case BUILT_IN_STPNCPY_CHK:
5087 return gimple_fold_builtin_stxncpy_chk (gsi,
5088 gimple_call_arg (stmt, 0),
5089 gimple_call_arg (stmt, 1),
5090 gimple_call_arg (stmt, 2),
5091 gimple_call_arg (stmt, 3),
5092 fcode);
5093 case BUILT_IN_SNPRINTF_CHK:
5094 case BUILT_IN_VSNPRINTF_CHK:
5095 return gimple_fold_builtin_snprintf_chk (gsi, fcode);
5096
5097 case BUILT_IN_FPRINTF:
5098 case BUILT_IN_FPRINTF_UNLOCKED:
5099 case BUILT_IN_VFPRINTF:
5100 if (n == 2 || n == 3)
5101 return gimple_fold_builtin_fprintf (gsi,
5102 gimple_call_arg (stmt, 0),
5103 gimple_call_arg (stmt, 1),
5104 n == 3
5105 ? gimple_call_arg (stmt, 2)
5106 : NULL_TREE(tree) __null,
5107 fcode);
5108 break;
5109 case BUILT_IN_FPRINTF_CHK:
5110 case BUILT_IN_VFPRINTF_CHK:
5111 if (n == 3 || n == 4)
5112 return gimple_fold_builtin_fprintf (gsi,
5113 gimple_call_arg (stmt, 0),
5114 gimple_call_arg (stmt, 2),
5115 n == 4
5116 ? gimple_call_arg (stmt, 3)
5117 : NULL_TREE(tree) __null,
5118 fcode);
5119 break;
5120 case BUILT_IN_PRINTF:
5121 case BUILT_IN_PRINTF_UNLOCKED:
5122 case BUILT_IN_VPRINTF:
5123 if (n == 1 || n == 2)
5124 return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 0),
5125 n == 2
5126 ? gimple_call_arg (stmt, 1)
5127 : NULL_TREE(tree) __null, fcode);
5128 break;
5129 case BUILT_IN_PRINTF_CHK:
5130 case BUILT_IN_VPRINTF_CHK:
5131 if (n == 2 || n == 3)
5132 return gimple_fold_builtin_printf (gsi, gimple_call_arg (stmt, 1),
5133 n == 3
5134 ? gimple_call_arg (stmt, 2)
5135 : NULL_TREE(tree) __null, fcode);
5136 break;
5137 case BUILT_IN_ACC_ON_DEVICE:
5138 return gimple_fold_builtin_acc_on_device (gsi,
5139 gimple_call_arg (stmt, 0));
5140 case BUILT_IN_REALLOC:
5141 return gimple_fold_builtin_realloc (gsi);
5142
5143 case BUILT_IN_CLEAR_PADDING:
5144 return gimple_fold_builtin_clear_padding (gsi);
5145
5146 default:;
5147 }
5148
5149 /* Try the generic builtin folder. */
5150 bool ignore = (gimple_call_lhs (stmt) == NULL__null);
5151 tree result = fold_call_stmt (stmt, ignore);
5152 if (result)
5153 {
5154 if (ignore)
5155 STRIP_NOPS (result)(result) = tree_strip_nop_conversions ((const_cast<union tree_node
*> (((result)))))
;
5156 else
5157 result = fold_convert (gimple_call_return_type (stmt), result)fold_convert_loc (((location_t) 0), gimple_call_return_type (
stmt), result)
;
5158 gimplify_and_update_call_from_tree (gsi, result);
5159 return true;
5160 }
5161
5162 return false;
5163}
5164
5165/* Transform IFN_GOACC_DIM_SIZE and IFN_GOACC_DIM_POS internal
5166 function calls to constants, where possible. */
5167
5168static tree
5169fold_internal_goacc_dim (const gimple *call)
5170{
5171 int axis = oacc_get_ifn_dim_arg (call);
5172 int size = oacc_get_fn_dim_size (current_function_decl, axis);
5173 tree result = NULL_TREE(tree) __null;
5174 tree type = TREE_TYPE (gimple_call_lhs (call))((contains_struct_check ((gimple_call_lhs (call)), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5174, __FUNCTION__))->typed.type)
;
5175
5176 switch (gimple_call_internal_fn (call))
5177 {
5178 case IFN_GOACC_DIM_POS:
5179 /* If the size is 1, we know the answer. */
5180 if (size == 1)
5181 result = build_int_cst (type, 0);
5182 break;
5183 case IFN_GOACC_DIM_SIZE:
5184 /* If the size is not dynamic, we know the answer. */
5185 if (size)
5186 result = build_int_cst (type, size);
5187 break;
5188 default:
5189 break;
5190 }
5191
5192 return result;
5193}
5194
5195/* Return true if stmt is __atomic_compare_exchange_N call which is suitable
5196 for conversion into ATOMIC_COMPARE_EXCHANGE if the second argument is
5197 &var where var is only addressable because of such calls. */
5198
5199bool
5200optimize_atomic_compare_exchange_p (gimple *stmt)
5201{
5202 if (gimple_call_num_args (stmt) != 6
5203 || !flag_inline_atomicsglobal_options.x_flag_inline_atomics
5204 || !optimizeglobal_options.x_optimize
5205 || sanitize_flags_p (SANITIZE_THREAD | SANITIZE_ADDRESS)
5206 || !gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
5207 || !gimple_vdef (stmt)
5208 || !gimple_vuse (stmt))
5209 return false;
5210
5211 tree fndecl = gimple_call_fndecl (stmt);
5212 switch (DECL_FUNCTION_CODE (fndecl))
5213 {
5214 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
5215 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
5216 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
5217 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
5218 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
5219 break;
5220 default:
5221 return false;
5222 }
5223
5224 tree expected = gimple_call_arg (stmt, 1);
5225 if (TREE_CODE (expected)((enum tree_code) (expected)->base.code) != ADDR_EXPR
5226 || !SSA_VAR_P (TREE_OPERAND (expected, 0))(((enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((expected), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5226, __FUNCTION__))))))->base.code) == VAR_DECL || ((enum
tree_code) ((*((const_cast<tree*> (tree_operand_check (
(expected), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5226, __FUNCTION__))))))->base.code) == PARM_DECL || ((enum
tree_code) ((*((const_cast<tree*> (tree_operand_check (
(expected), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5226, __FUNCTION__))))))->base.code) == RESULT_DECL || (
(enum tree_code) ((*((const_cast<tree*> (tree_operand_check
((expected), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5226, __FUNCTION__))))))->base.code) == SSA_NAME)
)
5227 return false;
5228
5229 tree etype = TREE_TYPE (TREE_OPERAND (expected, 0))((contains_struct_check (((*((const_cast<tree*> (tree_operand_check
((expected), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5229, __FUNCTION__)))))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5229, __FUNCTION__))->typed.type)
;
5230 if (!is_gimple_reg_type (etype)
5231 || !auto_var_in_fn_p (TREE_OPERAND (expected, 0)(*((const_cast<tree*> (tree_operand_check ((expected), (
0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5231, __FUNCTION__)))))
, current_function_decl)
5232 || TREE_THIS_VOLATILE (etype)((etype)->base.volatile_flag)
5233 || VECTOR_TYPE_P (etype)(((enum tree_code) (etype)->base.code) == VECTOR_TYPE)
5234 || TREE_CODE (etype)((enum tree_code) (etype)->base.code) == COMPLEX_TYPE
5235 /* Don't optimize floating point expected vars, VIEW_CONVERT_EXPRs
5236 might not preserve all the bits. See PR71716. */
5237 || SCALAR_FLOAT_TYPE_P (etype)(((enum tree_code) (etype)->base.code) == REAL_TYPE)
5238 || maybe_ne (TYPE_PRECISION (etype)((tree_class_check ((etype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5238, __FUNCTION__))->type_common.precision)
,
5239 GET_MODE_BITSIZE (TYPE_MODE (etype)((((enum tree_code) ((tree_class_check ((etype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5239, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(etype) : (etype)->type_common.mode)
)))
5240 return false;
5241
5242 tree weak = gimple_call_arg (stmt, 3);
5243 if (!integer_zerop (weak) && !integer_onep (weak))
5244 return false;
5245
5246 tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl))((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5246, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5246, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common
.values)
;
5247 tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)))((tree_check ((((contains_struct_check ((((contains_struct_check
((parmt), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5247, __FUNCTION__))->common.chain)), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5247, __FUNCTION__))->common.chain)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5247, __FUNCTION__, (TREE_LIST)))->list.value)
;
5248 machine_mode mode = TYPE_MODE (itype)((((enum tree_code) ((tree_class_check ((itype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5248, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(itype) : (itype)->type_common.mode)
;
5249
5250 if (direct_optab_handler (atomic_compare_and_swap_optab, mode)
5251 == CODE_FOR_nothing
5252 && optab_handler (sync_compare_and_swap_optab, mode) == CODE_FOR_nothing)
5253 return false;
5254
5255 if (maybe_ne (int_size_in_bytes (etype), GET_MODE_SIZE (mode)))
5256 return false;
5257
5258 return true;
5259}
5260
5261/* Fold
5262 r = __atomic_compare_exchange_N (p, &e, d, w, s, f);
5263 into
5264 _Complex uintN_t t = ATOMIC_COMPARE_EXCHANGE (p, e, d, w * 256 + N, s, f);
5265 i = IMAGPART_EXPR <t>;
5266 r = (_Bool) i;
5267 e = REALPART_EXPR <t>; */
5268
5269void
5270fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
5271{
5272 gimple *stmt = gsi_stmt (*gsi);
5273 tree fndecl = gimple_call_fndecl (stmt);
5274 tree parmt = TYPE_ARG_TYPES (TREE_TYPE (fndecl))((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5274, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5274, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common
.values)
;
5275 tree itype = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (parmt)))((tree_check ((((contains_struct_check ((((contains_struct_check
((parmt), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5275, __FUNCTION__))->common.chain)), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5275, __FUNCTION__))->common.chain)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5275, __FUNCTION__, (TREE_LIST)))->list.value)
;
5276 tree ctype = build_complex_type (itype);
5277 tree expected = TREE_OPERAND (gimple_call_arg (stmt, 1), 0)(*((const_cast<tree*> (tree_operand_check ((gimple_call_arg
(stmt, 1)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5277, __FUNCTION__)))))
;
5278 bool throws = false;
5279 edge e = NULL__null;
5280 gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)((contains_struct_check ((expected), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5280, __FUNCTION__))->typed.type)
),
5281 expected);
5282 gsi_insert_before (gsi, g, GSI_SAME_STMT);
5283 gimple_stmt_iterator gsiret = gsi_for_stmt (g);
5284 if (!useless_type_conversion_p (itype, TREE_TYPE (expected)((contains_struct_check ((expected), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5284, __FUNCTION__))->typed.type)
))
5285 {
5286 g = gimple_build_assign (make_ssa_name (itype), VIEW_CONVERT_EXPR,
5287 build1 (VIEW_CONVERT_EXPR, itype,
5288 gimple_assign_lhs (g)));
5289 gsi_insert_before (gsi, g, GSI_SAME_STMT);
5290 }
5291 int flag = (integer_onep (gimple_call_arg (stmt, 3)) ? 256 : 0)
5292 + int_size_in_bytes (itype);
5293 g = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE, 6,
5294 gimple_call_arg (stmt, 0),
5295 gimple_assign_lhs (g),
5296 gimple_call_arg (stmt, 2),
5297 build_int_cst (integer_type_nodeinteger_types[itk_int], flag),
5298 gimple_call_arg (stmt, 4),
5299 gimple_call_arg (stmt, 5));
5300 tree lhs = make_ssa_name (ctype);
5301 gimple_call_set_lhs (g, lhs);
5302 gimple_move_vops (g, stmt);
5303 tree oldlhs = gimple_call_lhs (stmt);
5304 if (stmt_can_throw_internal (cfun(cfun + 0), stmt))
5305 {
5306 throws = true;
5307 e = find_fallthru_edge (gsi_bb (*gsi)->succs);
5308 }
5309 gimple_call_set_nothrow (as_a <gcall *> (g),
5310 gimple_call_nothrow_p (as_a <gcall *> (stmt)));
5311 gimple_call_set_lhs (stmt, NULL_TREE(tree) __null);
5312 gsi_replace (gsi, g, true);
5313 if (oldlhs)
5314 {
5315 g = gimple_build_assign (make_ssa_name (itype), IMAGPART_EXPR,
5316 build1 (IMAGPART_EXPR, itype, lhs));
5317 if (throws)
5318 {
5319 gsi_insert_on_edge_immediate (e, g);
5320 *gsi = gsi_for_stmt (g);
5321 }
5322 else
5323 gsi_insert_after (gsi, g, GSI_NEW_STMT);
5324 g = gimple_build_assign (oldlhs, NOP_EXPR, gimple_assign_lhs (g));
5325 gsi_insert_after (gsi, g, GSI_NEW_STMT);
5326 }
5327 g = gimple_build_assign (make_ssa_name (itype), REALPART_EXPR,
5328 build1 (REALPART_EXPR, itype, lhs));
5329 if (throws && oldlhs == NULL_TREE(tree) __null)
5330 {
5331 gsi_insert_on_edge_immediate (e, g);
5332 *gsi = gsi_for_stmt (g);
5333 }
5334 else
5335 gsi_insert_after (gsi, g, GSI_NEW_STMT);
5336 if (!useless_type_conversion_p (TREE_TYPE (expected)((contains_struct_check ((expected), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5336, __FUNCTION__))->typed.type)
, itype))
5337 {
5338 g = gimple_build_assign (make_ssa_name (TREE_TYPE (expected)((contains_struct_check ((expected), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5338, __FUNCTION__))->typed.type)
),
5339 VIEW_CONVERT_EXPR,
5340 build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expected)((contains_struct_check ((expected), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5340, __FUNCTION__))->typed.type)
,
5341 gimple_assign_lhs (g)));
5342 gsi_insert_after (gsi, g, GSI_NEW_STMT);
5343 }
5344 g = gimple_build_assign (expected, SSA_NAME, gimple_assign_lhs (g));
5345 gsi_insert_after (gsi, g, GSI_NEW_STMT);
5346 *gsi = gsiret;
5347}
5348
5349/* Return true if ARG0 CODE ARG1 in infinite signed precision operation
5350 doesn't fit into TYPE. The test for overflow should be regardless of
5351 -fwrapv, and even for unsigned types. */
5352
5353bool
5354arith_overflowed_p (enum tree_code code, const_tree type,
5355 const_tree arg0, const_tree arg1)
5356{
5357 widest2_int warg0 = widest2_int_cst (arg0);
5358 widest2_int warg1 = widest2_int_cst (arg1);
5359 widest2_int wres;
5360 switch (code)
5361 {
5362 case PLUS_EXPR: wres = wi::add (warg0, warg1); break;
5363 case MINUS_EXPR: wres = wi::sub (warg0, warg1); break;
5364 case MULT_EXPR: wres = wi::mul (warg0, warg1); break;
5365 default: gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5365, __FUNCTION__))
;
5366 }
5367 signop sign = TYPE_SIGN (type)((signop) ((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5367, __FUNCTION__))->base.u.bits.unsigned_flag))
;
5368 if (sign == UNSIGNED && wi::neg_p (wres))
5369 return true;
5370 return wi::min_precision (wres, sign) > TYPE_PRECISION (type)((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5370, __FUNCTION__))->type_common.precision)
;
5371}
5372
5373/* If IFN_{MASK,LEN}_LOAD/STORE call CALL is unconditional, return a MEM_REF
5374 for the memory it references, otherwise return null. VECTYPE is the
5375 type of the memory vector. MASK_P indicates it's for MASK if true,
5376 otherwise it's for LEN. */
5377
5378static tree
5379gimple_fold_partial_load_store_mem_ref (gcall *call, tree vectype, bool mask_p)
5380{
5381 tree ptr = gimple_call_arg (call, 0);
5382 tree alias_align = gimple_call_arg (call, 1);
5383 if (!tree_fits_uhwi_p (alias_align))
5384 return NULL_TREE(tree) __null;
5385
5386 if (mask_p)
5387 {
5388 tree mask = gimple_call_arg (call, 2);
5389 if (!integer_all_onesp (mask))
5390 return NULL_TREE(tree) __null;
5391 }
5392 else
5393 {
5394 tree basic_len = gimple_call_arg (call, 2);
5395 if (!poly_int_tree_p (basic_len))
5396 return NULL_TREE(tree) __null;
5397 unsigned int nargs = gimple_call_num_args (call);
5398 tree bias = gimple_call_arg (call, nargs - 1);
5399 gcc_assert (TREE_CODE (bias) == INTEGER_CST)((void)(!(((enum tree_code) (bias)->base.code) == INTEGER_CST
) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5399, __FUNCTION__), 0 : 0))
;
5400 if (maybe_ne (wi::to_poly_widest (basic_len) - wi::to_widest (bias),
5401 GET_MODE_SIZE (TYPE_MODE (vectype)((((enum tree_code) ((tree_class_check ((vectype), (tcc_type)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5401, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(vectype) : (vectype)->type_common.mode)
)))
5402 return NULL_TREE(tree) __null;
5403 }
5404
5405 unsigned HOST_WIDE_INTlong align = tree_to_uhwi (alias_align);
5406 if (TYPE_ALIGN (vectype)(((tree_class_check ((vectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5406, __FUNCTION__))->type_common.align) ? ((unsigned)1)
<< (((tree_class_check ((vectype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5406, __FUNCTION__))->type_common.align) - 1) : 0)
!= align)
5407 vectype = build_aligned_type (vectype, align);
5408 tree offset = build_zero_cst (TREE_TYPE (alias_align)((contains_struct_check ((alias_align), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5408, __FUNCTION__))->typed.type)
);
5409 return fold_build2 (MEM_REF, vectype, ptr, offset)fold_build2_loc (((location_t) 0), MEM_REF, vectype, ptr, offset
)
;
5410}
5411
5412/* Try to fold IFN_{MASK,LEN}_LOAD call CALL. Return true on success.
5413 MASK_P indicates it's for MASK if true, otherwise it's for LEN. */
5414
5415static bool
5416gimple_fold_partial_load (gimple_stmt_iterator *gsi, gcall *call, bool mask_p)
5417{
5418 tree lhs = gimple_call_lhs (call);
5419 if (!lhs)
5420 return false;
5421
5422 if (tree rhs
5423 = gimple_fold_partial_load_store_mem_ref (call, TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5423, __FUNCTION__))->typed.type)
, mask_p))
5424 {
5425 gassign *new_stmt = gimple_build_assign (lhs, rhs);
5426 gimple_set_location (new_stmt, gimple_location (call));
5427 gimple_move_vops (new_stmt, call);
5428 gsi_replace (gsi, new_stmt, false);
5429 return true;
5430 }
5431 return false;
5432}
5433
5434/* Try to fold IFN_{MASK,LEN}_STORE call CALL. Return true on success.
5435 MASK_P indicates it's for MASK if true, otherwise it's for LEN. */
5436
5437static bool
5438gimple_fold_partial_store (gimple_stmt_iterator *gsi, gcall *call,
5439 bool mask_p)
5440{
5441 tree rhs = gimple_call_arg (call, 3);
5442 if (tree lhs
5443 = gimple_fold_partial_load_store_mem_ref (call, TREE_TYPE (rhs)((contains_struct_check ((rhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5443, __FUNCTION__))->typed.type)
, mask_p))
5444 {
5445 gassign *new_stmt = gimple_build_assign (lhs, rhs);
5446 gimple_set_location (new_stmt, gimple_location (call));
5447 gimple_move_vops (new_stmt, call);
5448 gsi_replace (gsi, new_stmt, false);
5449 return true;
5450 }
5451 return false;
5452}
5453
5454/* Attempt to fold a call statement referenced by the statement iterator GSI.
5455 The statement may be replaced by another statement, e.g., if the call
5456 simplifies to a constant value. Return true if any changes were made.
5457 It is assumed that the operands have been previously folded. */
5458
5459static bool
5460gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
5461{
5462 gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
5463 tree callee;
5464 bool changed = false;
5465
5466 /* Check for virtual calls that became direct calls. */
5467 callee = gimple_call_fn (stmt);
5468 if (callee && TREE_CODE (callee)((enum tree_code) (callee)->base.code) == OBJ_TYPE_REF)
5469 {
5470 if (gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)(*((const_cast<tree*> (tree_operand_check (((tree_check
((callee), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5470, __FUNCTION__, (OBJ_TYPE_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5470, __FUNCTION__)))))
) != NULL_TREE(tree) __null)
5471 {
5472 if (dump_file && virtual_method_call_p (callee)
5473 && !possible_polymorphic_call_target_p
5474 (callee, stmt, cgraph_node::get (gimple_call_addr_fndecl
5475 (OBJ_TYPE_REF_EXPR (callee)(*((const_cast<tree*> (tree_operand_check (((tree_check
((callee), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5475, __FUNCTION__, (OBJ_TYPE_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5475, __FUNCTION__)))))
))))
5476 {
5477 fprintf (dump_file,
5478 "Type inheritance inconsistent devirtualization of ");
5479 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
5480 fprintf (dump_file, " to ");
5481 print_generic_expr (dump_file, callee, TDF_SLIM);
5482 fprintf (dump_file, "\n");
5483 }
5484
5485 gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee)(*((const_cast<tree*> (tree_operand_check (((tree_check
((callee), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5485, __FUNCTION__, (OBJ_TYPE_REF)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5485, __FUNCTION__)))))
);
5486 changed = true;
5487 }
5488 else if (flag_devirtualizeglobal_options.x_flag_devirtualize && !inplace && virtual_method_call_p (callee))
5489 {
5490 bool final;
5491 vec <cgraph_node *>targets
5492 = possible_polymorphic_call_targets (callee, stmt, &final);
5493 if (final && targets.length () <= 1 && dbg_cnt (devirt))
5494 {
5495 tree lhs = gimple_call_lhs (stmt);
5496 if (dump_enabled_p ())
5497 {
5498 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
5499 "folding virtual function call to %s\n",
5500 targets.length () == 1
5501 ? targets[0]->name ()
5502 : "__builtin_unreachable");
5503 }
5504 if (targets.length () == 1)
5505 {
5506 tree fndecl = targets[0]->decl;
5507 gimple_call_set_fndecl (stmt, fndecl);
5508 changed = true;
5509 /* If changing the call to __cxa_pure_virtual
5510 or similar noreturn function, adjust gimple_call_fntype
5511 too. */
5512 if (gimple_call_noreturn_p (stmt)
5513 && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))(((enum tree_code) (((contains_struct_check ((((contains_struct_check
((fndecl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5513, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5513, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE
)
5514 && TYPE_ARG_TYPES (TREE_TYPE (fndecl))((tree_check2 ((((contains_struct_check ((fndecl), (TS_TYPED)
, "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5514, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5514, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common
.values)
5515 && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))((tree_check ((((tree_check2 ((((contains_struct_check ((fndecl
), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5515, __FUNCTION__))->typed.type)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5515, __FUNCTION__, (FUNCTION_TYPE), (METHOD_TYPE)))->type_non_common
.values)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5515, __FUNCTION__, (TREE_LIST)))->list.value)
5516 == void_type_nodeglobal_trees[TI_VOID_TYPE]))
5517 gimple_call_set_fntype (stmt, TREE_TYPE (fndecl)((contains_struct_check ((fndecl), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5517, __FUNCTION__))->typed.type)
);
5518 /* If the call becomes noreturn, remove the lhs. */
5519 if (lhs
5520 && gimple_call_noreturn_p (stmt)
5521 && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))(((enum tree_code) (((contains_struct_check ((gimple_call_fntype
(stmt)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5521, __FUNCTION__))->typed.type))->base.code) == VOID_TYPE
)
5522 || should_remove_lhs_p (lhs)))
5523 {
5524 if (TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME)
5525 {
5526 tree var = create_tmp_var (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5526, __FUNCTION__))->typed.type)
);
5527 tree def = get_or_create_ssa_default_def (cfun(cfun + 0), var);
5528 gimple *new_stmt = gimple_build_assign (lhs, def);
5529 gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
5530 }
5531 gimple_call_set_lhs (stmt, NULL_TREE(tree) __null);
5532 }
5533 maybe_remove_unused_call_args (cfun(cfun + 0), stmt);
5534 }
5535 else
5536 {
5537 location_t loc = gimple_location (stmt);
5538 gimple *new_stmt = gimple_build_builtin_unreachable (loc);
5539 gimple_call_set_ctrl_altering (new_stmt, false);
5540 /* If the call had a SSA name as lhs morph that into
5541 an uninitialized value. */
5542 if (lhs && TREE_CODE (lhs)((enum tree_code) (lhs)->base.code) == SSA_NAME)
5543 {
5544 tree var = create_tmp_var (TREE_TYPE (lhs)((contains_struct_check ((lhs), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5544, __FUNCTION__))->typed.type)
);
5545 SET_SSA_NAME_VAR_OR_IDENTIFIER (lhs, var)do { tree var_ = (var); (tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5545, __FUNCTION__, (SSA_NAME)))->ssa_name.var = var_; (
tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5545, __FUNCTION__, (SSA_NAME)))->base.public_flag = (var_
&& ((enum tree_code) (var_)->base.code) == VAR_DECL
&& ((tree_check ((var_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5545, __FUNCTION__, (VAR_DECL)))->base.u.bits.saturating_flag
)); } while (0)
;
5546 SSA_NAME_DEF_STMT (lhs)(tree_check ((lhs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5546, __FUNCTION__, (SSA_NAME)))->ssa_name.def_stmt
= gimple_build_nop ();
5547 set_ssa_default_def (cfun(cfun + 0), var, lhs);
5548 }
5549 gimple_move_vops (new_stmt, stmt);
5550 gsi_replace (gsi, new_stmt, false);
5551 return true;
5552 }
5553 }
5554 }
5555 }
5556
5557 /* Check for indirect calls that became direct calls, and then
5558 no longer require a static chain. */
5559 if (gimple_call_chain (stmt))
5560 {
5561 tree fn = gimple_call_fndecl (stmt);
5562 if (fn && !DECL_STATIC_CHAIN (fn)((tree_check ((fn), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5562, __FUNCTION__, (FUNCTION_DECL)))->decl_with_vis.regdecl_flag
)
)
5563 {
5564 gimple_call_set_chain (stmt, NULL__null);
5565 changed = true;
5566 }
5567 }
5568
5569 if (inplace)
5570 return changed;
5571
5572 /* Check for builtins that CCP can handle using information not
5573 available in the generic fold routines. */
5574 if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
5575 {
5576 if (gimple_fold_builtin (gsi))
5577 changed = true;
5578 }
5579 else if (gimple_call_builtin_p (stmt, BUILT_IN_MD))
5580 {
5581 changed |= targetm.gimple_fold_builtin (gsi);
5582 }
5583 else if (gimple_call_internal_p (stmt))
5584 {
5585 enum tree_code subcode = ERROR_MARK;
5586 tree result = NULL_TREE(tree) __null;
5587 bool cplx_result = false;
5588 tree overflow = NULL_TREE(tree) __null;
5589 switch (gimple_call_internal_fn (stmt))
5590 {
5591 case IFN_BUILTIN_EXPECT:
5592 result = fold_builtin_expect (gimple_location (stmt),
5593 gimple_call_arg (stmt, 0),
5594 gimple_call_arg (stmt, 1),
5595 gimple_call_arg (stmt, 2),
5596 NULL_TREE(tree) __null);
5597 break;
5598 case IFN_UBSAN_OBJECT_SIZE:
5599 {
5600 tree offset = gimple_call_arg (stmt, 1);
5601 tree objsize = gimple_call_arg (stmt, 2);
5602 if (integer_all_onesp (objsize)
5603 || (TREE_CODE (offset)((enum tree_code) (offset)->base.code) == INTEGER_CST
5604 && TREE_CODE (objsize)((enum tree_code) (objsize)->base.code) == INTEGER_CST
5605 && tree_int_cst_le (offset, objsize)))
5606 {
5607 replace_call_with_value (gsi, NULL_TREE(tree) __null);
5608 return true;
5609 }
5610 }
5611 break;
5612 case IFN_UBSAN_PTR:
5613 if (integer_zerop (gimple_call_arg (stmt, 1)))
5614 {
5615 replace_call_with_value (gsi, NULL_TREE(tree) __null);
5616 return true;
5617 }
5618 break;
5619 case IFN_UBSAN_BOUNDS:
5620 {
5621 tree index = gimple_call_arg (stmt, 1);
5622 tree bound = gimple_call_arg (stmt, 2);
5623 if (TREE_CODE (index)((enum tree_code) (index)->base.code) == INTEGER_CST
5624 && TREE_CODE (bound)((enum tree_code) (bound)->base.code) == INTEGER_CST)
5625 {
5626 index = fold_convert (TREE_TYPE (bound), index)fold_convert_loc (((location_t) 0), ((contains_struct_check (
(bound), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5626, __FUNCTION__))->typed.type), index)
;
5627 if (TREE_CODE (index)((enum tree_code) (index)->base.code) == INTEGER_CST
5628 && tree_int_cst_lt (index, bound))
5629 {
5630 replace_call_with_value (gsi, NULL_TREE(tree) __null);
5631 return true;
5632 }
5633 }
5634 }
5635 break;
5636 case IFN_GOACC_DIM_SIZE:
5637 case IFN_GOACC_DIM_POS:
5638 result = fold_internal_goacc_dim (stmt);
5639 break;
5640 case IFN_UBSAN_CHECK_ADD:
5641 subcode = PLUS_EXPR;
5642 break;
5643 case IFN_UBSAN_CHECK_SUB:
5644 subcode = MINUS_EXPR;
5645 break;
5646 case IFN_UBSAN_CHECK_MUL:
5647 subcode = MULT_EXPR;
5648 break;
5649 case IFN_ADD_OVERFLOW:
5650 subcode = PLUS_EXPR;
5651 cplx_result = true;
5652 break;
5653 case IFN_SUB_OVERFLOW:
5654 subcode = MINUS_EXPR;
5655 cplx_result = true;
5656 break;
5657 case IFN_MUL_OVERFLOW:
5658 subcode = MULT_EXPR;
5659 cplx_result = true;
5660 break;
5661 case IFN_MASK_LOAD:
5662 changed |= gimple_fold_partial_load (gsi, stmt, true);
5663 break;
5664 case IFN_MASK_STORE:
5665 changed |= gimple_fold_partial_store (gsi, stmt, true);
5666 break;
5667 case IFN_LEN_LOAD:
5668 changed |= gimple_fold_partial_load (gsi, stmt, false);
5669 break;
5670 case IFN_LEN_STORE:
5671 changed |= gimple_fold_partial_store (gsi, stmt, false);
5672 break;
5673 default:
5674 break;
5675 }
5676 if (subcode != ERROR_MARK)
5677 {
5678 tree arg0 = gimple_call_arg (stmt, 0);
5679 tree arg1 = gimple_call_arg (stmt, 1);
5680 tree type = TREE_TYPE (arg0)((contains_struct_check ((arg0), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.cc"
, 5680, __FUNCTION__))->typed.type)
;
5681 if (cplx_result)
5682 {
5683 tree lhs = gimple_call_lhs (stmt);
5684 if (lhs == NULL_TREE(tree) __null