Bug Summary

File:build/gcc/vec.h
Warning:line 814, column 10
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name gimple-fold.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/13.0.0 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/backward -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-error=format-diag -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2021-11-20-133755-20252-1/report-s0K6K_.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.c

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/gimple-fold.c

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