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 constraint.cc -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/13.0.0 -D IN_GCC_FRONTEND -D IN_GCC -D HAVE_CONFIG_H -I . -I cp -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/cp -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-_YqtzZ.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc

/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc

1/* Processing rules for constraints.
2 Copyright (C) 2013-2021 Free Software Foundation, Inc.
3 Contributed by Andrew Sutton (andrew.n.sutton@gmail.com)
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for 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 "tm.h"
25#include "timevar.h"
26#include "hash-set.h"
27#include "machmode.h"
28#include "vec.h"
29#include "double-int.h"
30#include "input.h"
31#include "alias.h"
32#include "symtab.h"
33#include "wide-int.h"
34#include "inchash.h"
35#include "tree.h"
36#include "stringpool.h"
37#include "attribs.h"
38#include "intl.h"
39#include "flags.h"
40#include "cp-tree.h"
41#include "c-family/c-common.h"
42#include "c-family/c-objc.h"
43#include "cp-objcp-common.h"
44#include "tree-inline.h"
45#include "decl.h"
46#include "toplev.h"
47#include "type-utils.h"
48
49static tree satisfaction_value (tree t);
50
51/* When we're parsing or substuting a constraint expression, we have slightly
52 different expression semantics. In particular, we don't want to reduce a
53 concept-id to a satisfaction value. */
54
55processing_constraint_expression_sentinel::
56processing_constraint_expression_sentinel ()
57{
58 ++scope_chain->x_processing_constraint;
59}
60
61processing_constraint_expression_sentinel::
62~processing_constraint_expression_sentinel ()
63{
64 --scope_chain->x_processing_constraint;
65}
66
67bool
68processing_constraint_expression_p ()
69{
70 return scope_chain->x_processing_constraint != 0;
71}
72
73/*---------------------------------------------------------------------------
74 Constraint expressions
75---------------------------------------------------------------------------*/
76
77/* Information provided to substitution. */
78
79struct subst_info
80{
81 subst_info (tsubst_flags_t cmp, tree in)
82 : complain (cmp), in_decl (in)
83 { }
84
85 /* True if we should not diagnose errors. */
86 bool quiet() const
87 {
88 return complain == tf_none;
89 }
90
91 /* True if we should diagnose errors. */
92 bool noisy() const
93 {
94 return !quiet ();
95 }
96
97 tsubst_flags_t complain;
98 tree in_decl;
99};
100
101/* Provides additional context for satisfaction.
102
103 During satisfaction:
104 - The flag noisy() controls whether to diagnose ill-formed satisfaction,
105 such as the satisfaction value of an atom being non-bool or non-constant.
106 - The flag diagnose_unsatisfaction_p() controls whether to additionally
107 explain why a constraint is not satisfied.
108 - We enter satisfaction with noisy+unsat from diagnose_constraints.
109 - We enter satisfaction with noisy-unsat from the replay inside
110 constraint_satisfaction_value.
111 - We enter satisfaction quietly (both flags cleared) from
112 constraints_satisfied_p.
113
114 During evaluation of a requires-expression:
115 - The flag noisy() controls whether to diagnose ill-formed types and
116 expressions inside its requirements.
117 - The flag diagnose_unsatisfaction_p() controls whether to additionally
118 explain why the requires-expression evaluates to false.
119 - We enter tsubst_requires_expr with noisy+unsat from
120 diagnose_atomic_constraint and potentially from
121 satisfy_nondeclaration_constraints.
122 - We enter tsubst_requires_expr with noisy-unsat from
123 cp_parser_requires_expression when processing a requires-expression that
124 appears outside a template.
125 - We enter tsubst_requires_expr quietly (both flags cleared) when
126 substituting through a requires-expression as part of template
127 instantiation. */
128
129struct sat_info : subst_info
130{
131 sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
132 : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
133 {
134 if (diagnose_unsatisfaction_p ())
135 gcc_checking_assert (noisy ())((void)(!(noisy ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 135, __FUNCTION__), 0 : 0))
;
136 }
137
138 /* True if we should diagnose the cause of satisfaction failure.
139 Implies noisy(). */
140 bool
141 diagnose_unsatisfaction_p () const
142 {
143 return diagnose_unsatisfaction;
144 }
145
146 bool diagnose_unsatisfaction;
147};
148
149static tree constraint_satisfaction_value (tree, tree, sat_info);
150
151/* True if T is known to be some type other than bool. Note that this
152 is false for dependent types and errors. */
153
154static inline bool
155known_non_bool_p (tree t)
156{
157 return (t && !WILDCARD_TYPE_P (t)(((enum tree_code) (t)->base.code) == TEMPLATE_TYPE_PARM ||
((enum tree_code) (t)->base.code) == TYPENAME_TYPE || ((enum
tree_code) (t)->base.code) == TYPEOF_TYPE || ((enum tree_code
) (t)->base.code) == BOUND_TEMPLATE_TEMPLATE_PARM || ((enum
tree_code) (t)->base.code) == DECLTYPE_TYPE)
&& TREE_CODE (t)((enum tree_code) (t)->base.code) != BOOLEAN_TYPE);
158}
159
160static bool
161check_constraint_atom (cp_expr expr)
162{
163 if (known_non_bool_p (TREE_TYPE (expr)((contains_struct_check ((expr), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 163, __FUNCTION__))->typed.type)
))
164 {
165 error_at (expr.get_location (),
166 "constraint expression does not have type %<bool%>");
167 return false;
168 }
169
170 /* Check that we're using function concepts correctly. */
171 if (concept_check_p (expr))
172 {
173 tree id = unpack_concept_check (expr);
174 tree tmpl = TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 174, __FUNCTION__)))))
;
175 if (OVL_P (tmpl)(((enum tree_code) (tmpl)->base.code) == FUNCTION_DECL || (
(enum tree_code) (tmpl)->base.code) == OVERLOAD)
&& TREE_CODE (expr)((enum tree_code) (expr)->base.code) == TEMPLATE_ID_EXPR)
176 {
177 error_at (EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((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)))) ? get_location_from_adhoc_loc (line_table
, ((((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))) : (((((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)))) != ((location_t) 0)) ? (expr)->exp.locus : (input_location
))
,
178 "function concept must be called");
179 return false;
180 }
181 }
182
183 return true;
184}
185
186static bool
187check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
188{
189 return check_constraint_atom (lhs) && check_constraint_atom (rhs);
190}
191
192/* Validate the semantic properties of the constraint expression. */
193
194static cp_expr
195finish_constraint_binary_op (location_t loc,
196 tree_code code,
197 cp_expr lhs,
198 cp_expr rhs)
199{
200 gcc_assert (processing_constraint_expression_p ())((void)(!(processing_constraint_expression_p ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 200, __FUNCTION__), 0 : 0))
;
201 if (lhs == error_mark_nodeglobal_trees[TI_ERROR_MARK] || rhs == error_mark_nodeglobal_trees[TI_ERROR_MARK])
202 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
203 if (!check_constraint_operands (loc, lhs, rhs))
204 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
205 tree overload;
206 cp_expr expr = build_x_binary_op (loc, code,
207 lhs, TREE_CODE (lhs)((enum tree_code) (lhs)->base.code),
208 rhs, TREE_CODE (rhs)((enum tree_code) (rhs)->base.code),
209 &overload, tf_none);
210 /* When either operand is dependent, the overload set may be non-empty. */
211 if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
212 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
213 expr.set_location (loc);
214 expr.set_range (lhs.get_start (), rhs.get_finish ());
215 return expr;
216}
217
218cp_expr
219finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
220{
221 return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
222}
223
224cp_expr
225finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
226{
227 return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
228}
229
230cp_expr
231finish_constraint_primary_expr (cp_expr expr)
232{
233 if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
234 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
235 if (!check_constraint_atom (expr))
236 return cp_expr (error_mark_nodeglobal_trees[TI_ERROR_MARK], expr.get_location ());
237 return expr;
238}
239
240/* Combine two constraint-expressions with a logical-and. */
241
242tree
243combine_constraint_expressions (tree lhs, tree rhs)
244{
245 processing_constraint_expression_sentinel pce;
246 if (!lhs)
247 return rhs;
248 if (!rhs)
249 return lhs;
250 return finish_constraint_and_expr (input_location, lhs, rhs);
251}
252
253/* Extract the template-id from a concept check. For standard and variable
254 checks, this is simply T. For function concept checks, this is the
255 called function. */
256
257tree
258unpack_concept_check (tree t)
259{
260 gcc_assert (concept_check_p (t))((void)(!(concept_check_p (t)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 260, __FUNCTION__), 0 : 0))
;
261
262 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == CALL_EXPR)
263 t = CALL_EXPR_FN (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 263, __FUNCTION__, (CALL_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 263, __FUNCTION__)))))
;
264
265 gcc_assert (TREE_CODE (t) == TEMPLATE_ID_EXPR)((void)(!(((enum tree_code) (t)->base.code) == TEMPLATE_ID_EXPR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 265, __FUNCTION__), 0 : 0))
;
266 return t;
267}
268
269/* Extract the TEMPLATE_DECL from a concept check. */
270
271tree
272get_concept_check_template (tree t)
273{
274 tree id = unpack_concept_check (t);
275 tree tmpl = TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 275, __FUNCTION__)))))
;
276 if (OVL_P (tmpl)(((enum tree_code) (tmpl)->base.code) == FUNCTION_DECL || (
(enum tree_code) (tmpl)->base.code) == OVERLOAD)
)
277 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
278 return tmpl;
279}
280
281/*---------------------------------------------------------------------------
282 Resolution of qualified concept names
283---------------------------------------------------------------------------*/
284
285/* This facility is used to resolve constraint checks from requirement
286 expressions. A constraint check is a call to a function template declared
287 with the keyword 'concept'.
288
289 The result of resolution is a pair (a TREE_LIST) whose value is the
290 matched declaration, and whose purpose contains the coerced template
291 arguments that can be substituted into the call. */
292
293/* Given an overload set OVL, try to find a unique definition that can be
294 instantiated by the template arguments ARGS.
295
296 This function is not called for arbitrary call expressions. In particular,
297 the call expression must be written with explicit template arguments
298 and no function arguments. For example:
299
300 f<T, U>()
301
302 If a single match is found, this returns a TREE_LIST whose VALUE
303 is the constraint function (not the template), and its PURPOSE is
304 the complete set of arguments substituted into the parameter list. */
305
306static tree
307resolve_function_concept_overload (tree ovl, tree args)
308{
309 int nerrs = 0;
310 tree cands = NULL_TREE(tree) __null;
311 for (lkp_iterator iter (ovl); iter; ++iter)
312 {
313 tree tmpl = *iter;
314 if (TREE_CODE (tmpl)((enum tree_code) (tmpl)->base.code) != TEMPLATE_DECL)
315 continue;
316
317 /* Don't try to deduce checks for non-concepts. We often end up trying
318 to resolve constraints in functional casts as part of a
319 postfix-expression. We can save time and headaches by not
320 instantiating those declarations.
321
322 NOTE: This masks a potential error, caused by instantiating
323 non-deduced contexts using placeholder arguments. */
324 tree fn = DECL_TEMPLATE_RESULT (tmpl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 324, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
325 if (DECL_ARGUMENTS (fn)((tree_check ((fn), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 325, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments
)
)
326 continue;
327 if (!DECL_DECLARED_CONCEPT_P (fn)(((contains_struct_check ((fn), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 327, __FUNCTION__))->decl_common.lang_specific)->u.base
.concept_p)
)
328 continue;
329
330 /* Remember the candidate if we can deduce a substitution. */
331 ++processing_template_declscope_chain->x_processing_template_decl;
332 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl))((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 332, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 332, __FUNCTION__, (TREE_LIST)))->list.value)
;
333 if (tree subst = coerce_template_parms (parms, args, tmpl))
334 {
335 if (subst == error_mark_nodeglobal_trees[TI_ERROR_MARK])
336 ++nerrs;
337 else
338 cands = tree_cons (subst, fn, cands);
339 }
340 --processing_template_declscope_chain->x_processing_template_decl;
341 }
342
343 if (!cands)
344 /* We either had no candidates or failed deductions. */
345 return nerrs ? error_mark_nodeglobal_trees[TI_ERROR_MARK] : NULL_TREE(tree) __null;
346 else if (TREE_CHAIN (cands)((contains_struct_check ((cands), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 346, __FUNCTION__))->common.chain)
)
347 /* There are multiple candidates. */
348 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
349
350 return cands;
351}
352
353/* Determine if the call expression CALL is a constraint check, and
354 return the concept declaration and arguments being checked. If CALL
355 does not denote a constraint check, return NULL. */
356
357tree
358resolve_function_concept_check (tree call)
359{
360 gcc_assert (TREE_CODE (call) == CALL_EXPR)((void)(!(((enum tree_code) (call)->base.code) == CALL_EXPR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 360, __FUNCTION__), 0 : 0))
;
361
362 /* A constraint check must be only a template-id expression.
363 If it's a call to a base-link, its function(s) should be a
364 template-id expression. If this is not a template-id, then
365 it cannot be a concept-check. */
366 tree target = CALL_EXPR_FN (call)(*((const_cast<tree*> (tree_operand_check (((tree_check
((call), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 366, __FUNCTION__, (CALL_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 366, __FUNCTION__)))))
;
367 if (BASELINK_P (target)(((enum tree_code) (target)->base.code) == BASELINK))
368 target = BASELINK_FUNCTIONS (target)(((struct tree_baselink*) (tree_check ((target), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 368, __FUNCTION__, (BASELINK))))->functions)
;
369 if (TREE_CODE (target)((enum tree_code) (target)->base.code) != TEMPLATE_ID_EXPR)
370 return NULL_TREE(tree) __null;
371
372 /* Get the overload set and template arguments and try to
373 resolve the target. */
374 tree ovl = TREE_OPERAND (target, 0)(*((const_cast<tree*> (tree_operand_check ((target), (0
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 374, __FUNCTION__)))))
;
375
376 /* This is a function call of a variable concept... ill-formed. */
377 if (TREE_CODE (ovl)((enum tree_code) (ovl)->base.code) == TEMPLATE_DECL)
378 {
379 error_at (location_of (call),
380 "function call of variable concept %qE", call);
381 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
382 }
383
384 tree args = TREE_OPERAND (target, 1)(*((const_cast<tree*> (tree_operand_check ((target), (1
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 384, __FUNCTION__)))))
;
385 return resolve_function_concept_overload (ovl, args);
386}
387
388/* Returns a pair containing the checked concept and its associated
389 prototype parameter. The result is a TREE_LIST whose TREE_VALUE
390 is the concept (non-template) and whose TREE_PURPOSE contains
391 the converted template arguments, including the deduced prototype
392 parameter (in position 0). */
393
394tree
395resolve_concept_check (tree check)
396{
397 gcc_assert (concept_check_p (check))((void)(!(concept_check_p (check)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 397, __FUNCTION__), 0 : 0))
;
398 tree id = unpack_concept_check (check);
399 tree tmpl = TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 399, __FUNCTION__)))))
;
400
401 /* If this is an overloaded function concept, perform overload
402 resolution (this only happens when deducing prototype parameters
403 and template introductions). */
404 if (TREE_CODE (tmpl)((enum tree_code) (tmpl)->base.code) == OVERLOAD)
405 {
406 if (OVL_CHAIN (tmpl)(((struct tree_overload*)(tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 406, __FUNCTION__, (OVERLOAD))))->common.chain)
)
407 return resolve_function_concept_check (check);
408 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
409 }
410
411 tree args = TREE_OPERAND (id, 1)(*((const_cast<tree*> (tree_operand_check ((id), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 411, __FUNCTION__)))))
;
412 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl))((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 412, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 412, __FUNCTION__, (TREE_LIST)))->list.value)
;
413 ++processing_template_declscope_chain->x_processing_template_decl;
414 tree result = coerce_template_parms (parms, args, tmpl);
415 --processing_template_declscope_chain->x_processing_template_decl;
416 if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK])
417 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
418 return build_tree_list (result, DECL_TEMPLATE_RESULT (tmpl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 418, __FUNCTION__, (TEMPLATE_DECL))))))))->result
);
419}
420
421/* Given a call expression or template-id expression to a concept EXPR
422 possibly including a wildcard, deduce the concept being checked and
423 the prototype parameter. Returns true if the constraint and prototype
424 can be deduced and false otherwise. Note that the CHECK and PROTO
425 arguments are set to NULL_TREE if this returns false. */
426
427bool
428deduce_constrained_parameter (tree expr, tree& check, tree& proto)
429{
430 tree info = resolve_concept_check (expr);
431 if (info && info != error_mark_nodeglobal_trees[TI_ERROR_MARK])
432 {
433 check = TREE_VALUE (info)((tree_check ((info), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 433, __FUNCTION__, (TREE_LIST)))->list.value)
;
434 tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0)(*((const_cast<tree *> (tree_vec_elt_check ((((tree_check
((info), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 434, __FUNCTION__, (TREE_LIST)))->list.purpose)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 434, __FUNCTION__)))))
;
435 if (ARGUMENT_PACK_P (arg)(((enum tree_code) (arg)->base.code) == TYPE_ARGUMENT_PACK
|| ((enum tree_code) (arg)->base.code) == NONTYPE_ARGUMENT_PACK
)
)
436 arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0)(*((const_cast<tree *> (tree_vec_elt_check (((((enum tree_code
) (arg)->base.code) == TYPE_ARGUMENT_PACK? ((contains_struct_check
((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 436, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 436, __FUNCTION__))))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 436, __FUNCTION__)))))
;
437 proto = TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 437, __FUNCTION__))->typed.type)
;
438 return true;
439 }
440
441 check = proto = NULL_TREE(tree) __null;
442 return false;
443}
444
445/* Given a call expression or template-id expression to a concept, EXPR,
446 deduce the concept being checked and return the template arguments.
447 Returns NULL_TREE if deduction fails. */
448static tree
449deduce_concept_introduction (tree check)
450{
451 tree info = resolve_concept_check (check);
452 if (info && info != error_mark_nodeglobal_trees[TI_ERROR_MARK])
453 return TREE_PURPOSE (info)((tree_check ((info), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 453, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
454 return NULL_TREE(tree) __null;
455}
456
457/* Build a constrained placeholder type where SPEC is a type-constraint.
458 SPEC can be anything were concept_definition_p is true.
459
460 If DECLTYPE_P is true, then the placeholder is decltype(auto).
461
462 Returns a pair whose FIRST is the concept being checked and whose
463 SECOND is the prototype parameter. */
464
465tree_pair
466finish_type_constraints (tree spec, tree args, tsubst_flags_t complain)
467{
468 gcc_assert (concept_definition_p (spec))((void)(!(concept_definition_p (spec)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 468, __FUNCTION__), 0 : 0))
;
469
470 /* Build an initial concept check. */
471 tree check = build_type_constraint (spec, args, complain);
472 if (check == error_mark_nodeglobal_trees[TI_ERROR_MARK])
473 return std::make_pair (error_mark_nodeglobal_trees[TI_ERROR_MARK], NULL_TREE(tree) __null);
474
475 /* Extract the concept and prototype parameter from the check. */
476 tree con;
477 tree proto;
478 if (!deduce_constrained_parameter (check, con, proto))
479 return std::make_pair (error_mark_nodeglobal_trees[TI_ERROR_MARK], NULL_TREE(tree) __null);
480
481 return std::make_pair (con, proto);
482}
483
484/*---------------------------------------------------------------------------
485 Expansion of concept definitions
486---------------------------------------------------------------------------*/
487
488/* Returns the expression of a function concept. */
489
490static tree
491get_returned_expression (tree fn)
492{
493 /* Extract the body of the function minus the return expression. */
494 tree body = DECL_SAVED_TREE (fn)((tree_check ((fn), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 494, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree
)
;
495 if (!body)
496 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
497 if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR)
498 body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check
((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 498, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 498, __FUNCTION__))))))
;
499 if (TREE_CODE (body)((enum tree_code) (body)->base.code) != RETURN_EXPR)
500 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
501
502 return TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 502, __FUNCTION__)))))
;
503}
504
505/* Returns the initializer of a variable concept. */
506
507static tree
508get_variable_initializer (tree var)
509{
510 tree init = DECL_INITIAL (var)((contains_struct_check ((var), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 510, __FUNCTION__))->decl_common.initial)
;
511 if (!init)
512 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
513 if (BRACE_ENCLOSED_INITIALIZER_P (init)(((enum tree_code) (init)->base.code) == CONSTRUCTOR &&
((contains_struct_check ((init), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 513, __FUNCTION__))->typed.type) == cp_global_trees[CPTI_INIT_LIST_TYPE
])
514 && CONSTRUCTOR_NELTS (init)(vec_safe_length (((tree_check ((init), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 514, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts)))
== 1)
515 init = CONSTRUCTOR_ELT (init, 0)(&(*((tree_check ((init), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 515, __FUNCTION__, (CONSTRUCTOR)))->constructor.elts))[0
])
->value;
516 return init;
517}
518
519/* Returns the definition of a variable or function concept. */
520
521static tree
522get_concept_definition (tree decl)
523{
524 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == OVERLOAD)
525 decl = OVL_FIRST (decl)ovl_first (decl);
526
527 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == TEMPLATE_DECL)
528 decl = DECL_TEMPLATE_RESULT (decl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 528, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
529
530 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == CONCEPT_DECL)
531 return DECL_INITIAL (decl)((contains_struct_check ((decl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 531, __FUNCTION__))->decl_common.initial)
;
532 if (VAR_P (decl)(((enum tree_code) (decl)->base.code) == VAR_DECL))
533 return get_variable_initializer (decl);
534 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) == FUNCTION_DECL)
535 return get_returned_expression (decl);
536 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 536, __FUNCTION__))
;
537}
538
539/*---------------------------------------------------------------------------
540 Normalization of expressions
541
542This set of functions will transform an expression into a constraint
543in a sequence of steps.
544---------------------------------------------------------------------------*/
545
546void
547debug_parameter_mapping (tree map)
548{
549 for (tree p = map; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 549, __FUNCTION__))->common.chain)
)
550 {
551 tree parm = TREE_VALUE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 551, __FUNCTION__, (TREE_LIST)))->list.value)
;
552 tree arg = TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 552, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
553 if (TYPE_P (parm)(tree_code_type[(int) (((enum tree_code) (parm)->base.code
))] == tcc_type)
)
554 verbatim ("MAP %qD TO %qT", TEMPLATE_TYPE_DECL (parm)((((template_parm_index*)(tree_check (((((tree_class_check ((
(tree_check3 (((parm)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 554, __FUNCTION__, (TEMPLATE_TYPE_PARM), (TEMPLATE_TEMPLATE_PARM
), (BOUND_TEMPLATE_TEMPLATE_PARM)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 554, __FUNCTION__))->type_non_common.values))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 554, __FUNCTION__, (TEMPLATE_PARM_INDEX))))->decl))
, arg);
555 else
556 verbatim ("MAP %qD TO %qE", TEMPLATE_PARM_DECL (parm)(((template_parm_index*)(tree_check ((parm), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 556, __FUNCTION__, (TEMPLATE_PARM_INDEX))))->decl)
, arg);
557 // debug_tree (parm);
558 // debug_tree (arg);
559 }
560}
561
562void
563debug_argument_list (tree args)
564{
565 for (int i = 0; i < TREE_VEC_LENGTH (args)((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 565, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++i)
566 {
567 tree arg = TREE_VEC_ELT (args, i)(*((const_cast<tree *> (tree_vec_elt_check ((args), (i)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 567, __FUNCTION__)))))
;
568 if (TYPE_P (arg)(tree_code_type[(int) (((enum tree_code) (arg)->base.code)
)] == tcc_type)
)
569 verbatim ("argument %qT", arg);
570 else
571 verbatim ("argument %qE", arg);
572 }
573}
574
575/* Associate each parameter in PARMS with its corresponding template
576 argument in ARGS. */
577
578static tree
579map_arguments (tree parms, tree args)
580{
581 for (tree p = parms; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 581, __FUNCTION__))->common.chain)
)
582 if (args)
583 {
584 int level;
585 int index;
586 template_parm_level_and_index (TREE_VALUE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 586, __FUNCTION__, (TREE_LIST)))->list.value)
, &level, &index);
587 TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__, (TREE_LIST)))->list.purpose)
= TMPL_ARG (args, level, index)((*((const_cast<tree *> (tree_vec_elt_check ((((args &&
((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((args), (0
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__))))))->base.code) == TREE_VEC) ? (*((const_cast
<tree *> (tree_vec_elt_check ((args), ((level) - 1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__))))) : (args))), (index), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 587, __FUNCTION__))))))
;
588 }
589 else
590 TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 590, __FUNCTION__, (TREE_LIST)))->list.purpose)
= template_parm_to_arg (p);
591
592 return parms;
593}
594
595/* Build the parameter mapping for EXPR using ARGS, where CTX_PARMS
596 are the template parameters in scope for EXPR. */
597
598static tree
599build_parameter_mapping (tree expr, tree args, tree ctx_parms)
600{
601 tree parms = find_template_parameters (expr, ctx_parms);
602 tree map = map_arguments (parms, args);
603 return map;
604}
605
606/* True if the parameter mappings of two atomic constraints formed
607 from the same expression are equivalent. */
608
609static bool
610parameter_mapping_equivalent_p (tree t1, tree t2)
611{
612 tree map1 = ATOMIC_CONSTR_MAP (t1)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 612, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 612, __FUNCTION__)))))
;
613 tree map2 = ATOMIC_CONSTR_MAP (t2)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 613, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 613, __FUNCTION__)))))
;
614 while (map1 && map2)
615 {
616 gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2))((void)(!(((tree_check ((map1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 616, __FUNCTION__, (TREE_LIST)))->list.value) == ((tree_check
((map2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 616, __FUNCTION__, (TREE_LIST)))->list.value)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 616, __FUNCTION__), 0 : 0))
;
617 tree arg1 = TREE_PURPOSE (map1)((tree_check ((map1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 617, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
618 tree arg2 = TREE_PURPOSE (map2)((tree_check ((map2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 618, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
619 if (!template_args_equal (arg1, arg2))
620 return false;
621 map1 = TREE_CHAIN (map1)((contains_struct_check ((map1), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 621, __FUNCTION__))->common.chain)
;
622 map2 = TREE_CHAIN (map2)((contains_struct_check ((map2), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 622, __FUNCTION__))->common.chain)
;
623 }
624 gcc_checking_assert (!map1 && !map2)((void)(!(!map1 && !map2) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 624, __FUNCTION__), 0 : 0))
;
625 return true;
626}
627
628/* Provides additional context for normalization. */
629
630struct norm_info : subst_info
631{
632 explicit norm_info (tsubst_flags_t cmp)
633 : norm_info (NULL_TREE(tree) __null, cmp)
634 {}
635
636 /* Construct a top-level context for DECL. */
637
638 norm_info (tree in_decl, tsubst_flags_t complain)
639 : subst_info (tf_warning_or_error | complain, in_decl)
640 {
641 if (in_decl)
642 {
643 initial_parms = DECL_TEMPLATE_PARMS (in_decl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((in_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 643, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments
;
644 if (generate_diagnostics ())
645 context = build_tree_list (NULL_TREE(tree) __null, in_decl);
646 }
647 else
648 initial_parms = current_template_parmsscope_chain->template_parms;
649 }
650
651 bool generate_diagnostics() const
652 {
653 return complain & tf_norm;
654 }
655
656 void update_context(tree expr, tree args)
657 {
658 if (generate_diagnostics ())
659 {
660 tree map = build_parameter_mapping (expr, args, ctx_parms ());
661 context = tree_cons (map, expr, context);
662 }
663 in_decl = get_concept_check_template (expr);
664 }
665
666 /* Returns the template parameters that are in scope for the current
667 normalization context. */
668
669 tree ctx_parms()
670 {
671 if (in_decl)
672 return DECL_TEMPLATE_PARMS (in_decl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((in_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 672, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments
;
673 else
674 return initial_parms;
675 }
676
677 /* Provides information about the source of a constraint. This is a
678 TREE_LIST whose VALUE is either a concept check or a constrained
679 declaration. The PURPOSE, for concept checks is a parameter mapping
680 for that check. */
681
682 tree context = NULL_TREE(tree) __null;
683
684 /* The declaration whose constraints we're normalizing. The targets
685 of the parameter mapping of each atom will be in terms of the
686 template parameters of ORIG_DECL. */
687
688 tree initial_parms = NULL_TREE(tree) __null;
689};
690
691static tree normalize_expression (tree, tree, norm_info);
692
693/* Transform a logical-or or logical-and expression into either
694 a conjunction or disjunction. */
695
696static tree
697normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
698{
699 tree t0 = normalize_expression (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 699, __FUNCTION__)))))
, args, info);
700 tree t1 = normalize_expression (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 700, __FUNCTION__)))))
, args, info);
701
702 /* Build a new info object for the constraint. */
703 tree ci = info.generate_diagnostics()
704 ? build_tree_list (t, info.context)
705 : NULL_TREE(tree) __null;
706
707 return build2 (c, ci, t0, t1);
708}
709
710static tree
711normalize_concept_check (tree check, tree args, norm_info info)
712{
713 tree id = unpack_concept_check (check);
714 tree tmpl = TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 714, __FUNCTION__)))))
;
715 tree targs = TREE_OPERAND (id, 1)(*((const_cast<tree*> (tree_operand_check ((id), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 715, __FUNCTION__)))))
;
716
717 /* A function concept is wrapped in an overload. */
718 if (TREE_CODE (tmpl)((enum tree_code) (tmpl)->base.code) == OVERLOAD)
719 {
720 /* TODO: Can we diagnose this error during parsing? */
721 if (TREE_CODE (check)((enum tree_code) (check)->base.code) == TEMPLATE_ID_EXPR)
722 error_at (EXPR_LOC_OR_LOC (check, input_location)((((IS_ADHOC_LOC (((((check)) && ((tree_code_type[(int
) (((enum tree_code) ((check))->base.code))]) >= tcc_reference
&& (tree_code_type[(int) (((enum tree_code) ((check)
)->base.code))]) <= tcc_expression)) ? (check)->exp.
locus : ((location_t) 0)))) ? get_location_from_adhoc_loc (line_table
, ((((check)) && ((tree_code_type[(int) (((enum tree_code
) ((check))->base.code))]) >= tcc_reference && (
tree_code_type[(int) (((enum tree_code) ((check))->base.code
))]) <= tcc_expression)) ? (check)->exp.locus : ((location_t
) 0))) : (((((check)) && ((tree_code_type[(int) (((enum
tree_code) ((check))->base.code))]) >= tcc_reference &&
(tree_code_type[(int) (((enum tree_code) ((check))->base.
code))]) <= tcc_expression)) ? (check)->exp.locus : ((location_t
) 0)))) != ((location_t) 0)) ? (check)->exp.locus : (input_location
))
,
723 "function concept must be called");
724 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
725 }
726
727 /* Substitute through the arguments of the concept check. */
728 if (args)
729 targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
730 if (targs == error_mark_nodeglobal_trees[TI_ERROR_MARK])
731 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
732
733 /* Build the substitution for the concept definition. */
734 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl))((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 734, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 734, __FUNCTION__, (TREE_LIST)))->list.value)
;
735 /* Turn on template processing; coercing non-type template arguments
736 will automatically assume they're non-dependent. */
737 ++processing_template_declscope_chain->x_processing_template_decl;
738 tree subst = coerce_template_parms (parms, targs, tmpl);
739 --processing_template_declscope_chain->x_processing_template_decl;
740 if (subst == error_mark_nodeglobal_trees[TI_ERROR_MARK])
741 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
742
743 /* The concept may have been ill-formed. */
744 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 744, __FUNCTION__, (TEMPLATE_DECL))))))))->result
);
745 if (def == error_mark_nodeglobal_trees[TI_ERROR_MARK])
746 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
747
748 info.update_context (check, args);
749 return normalize_expression (def, subst, info);
750}
751
752/* Used by normalize_atom to cache ATOMIC_CONSTRs. */
753
754static GTY((deletable)) hash_table<atom_hasher> *atom_cache;
755
756/* The normal form of an atom depends on the expression. The normal
757 form of a function call to a function concept is a check constraint
758 for that concept. The normal form of a reference to a variable
759 concept is a check constraint for that concept. Otherwise, the
760 constraint is a predicate constraint. */
761
762static tree
763normalize_atom (tree t, tree args, norm_info info)
764{
765 /* Concept checks are not atomic. */
766 if (concept_check_p (t))
767 return normalize_concept_check (t, args, info);
768
769 /* Build the parameter mapping for the atom. */
770 tree map = build_parameter_mapping (t, args, info.ctx_parms ());
771
772 /* Build a new info object for the atom. */
773 tree ci = build_tree_list (t, info.context);
774
775 tree atom = build1 (ATOMIC_CONSTR, ci, map);
776 if (!info.generate_diagnostics ())
777 {
778 /* Cache the ATOMIC_CONSTRs that we return, so that sat_hasher::equal
779 later can cheaply compare two atoms using just pointer equality. */
780 if (!atom_cache)
781 atom_cache = hash_table<atom_hasher>::create_ggc (31);
782 tree *slot = atom_cache->find_slot (atom, INSERT);
783 if (*slot)
784 return *slot;
785
786 /* Find all template parameters used in the targets of the parameter
787 mapping, and store a list of them in the TREE_TYPE of the mapping.
788 This list will be used by sat_hasher to determine the subset of
789 supplied template arguments that the satisfaction value of the atom
790 depends on. */
791 if (map)
792 {
793 tree targets = make_tree_vec (list_length (map));
794 int i = 0;
795 for (tree node = map; node; node = TREE_CHAIN (node)((contains_struct_check ((node), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 795, __FUNCTION__))->common.chain)
)
796 {
797 tree target = TREE_PURPOSE (node)((tree_check ((node), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 797, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
798 TREE_VEC_ELT (targets, i++)(*((const_cast<tree *> (tree_vec_elt_check ((targets), (
i++), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 798, __FUNCTION__)))))
= target;
799 }
800 tree target_parms = find_template_parameters (targets,
801 info.initial_parms);
802 TREE_TYPE (map)((contains_struct_check ((map), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 802, __FUNCTION__))->typed.type)
= target_parms;
803 }
804
805 *slot = atom;
806 }
807 return atom;
808}
809
810/* Returns the normal form of an expression. */
811
812static tree
813normalize_expression (tree t, tree args, norm_info info)
814{
815 if (!t)
816 return NULL_TREE(tree) __null;
817
818 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
819 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
820
821 switch (TREE_CODE (t)((enum tree_code) (t)->base.code))
822 {
823 case TRUTH_ANDIF_EXPR:
824 return normalize_logical_operation (t, args, CONJ_CONSTR, info);
825 case TRUTH_ORIF_EXPR:
826 return normalize_logical_operation (t, args, DISJ_CONSTR, info);
827 default:
828 return normalize_atom (t, args, info);
829 }
830}
831
832/* Cache of the normalized form of constraints. Marked as deletable because it
833 can all be recalculated. */
834static GTY((deletable)) hash_map<tree,tree> *normalized_map;
835
836static tree
837get_normalized_constraints (tree t, norm_info info)
838{
839 auto_timevar time (TV_CONSTRAINT_NORM);
840 return normalize_expression (t, NULL_TREE(tree) __null, info);
841}
842
843/* Returns the normalized constraints from a constraint-info object
844 or NULL_TREE if the constraints are null. IN_DECL provides the
845 declaration to which the constraints belong. */
846
847static tree
848get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
849{
850 if (ci == NULL_TREE(tree) __null)
851 return NULL_TREE(tree) __null;
852
853 /* Substitution errors during normalization are fatal. */
854 ++processing_template_declscope_chain->x_processing_template_decl;
855 norm_info info (in_decl, diag ? tf_norm : tf_none);
856 tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci)check_constraint_info (check_nonnull (ci))->associated_constr, info);
857 --processing_template_declscope_chain->x_processing_template_decl;
858
859 return t;
860}
861
862/* Returns the normalized constraints for the declaration D. */
863
864static tree
865get_normalized_constraints_from_decl (tree d, bool diag = false)
866{
867 tree tmpl;
868 tree decl;
869
870 /* For inherited constructors, consider the original declaration;
871 it has the correct template information attached. */
872 d = strip_inheriting_ctors (d);
873
874 if (regenerated_lambda_fn_p (d))
875 {
876 /* If this lambda was regenerated, DECL_TEMPLATE_PARMS doesn't contain
877 all in-scope template parameters, but the lambda from which it was
878 ultimately regenerated does, so use that instead. */
879 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d))((((tree_class_check ((((contains_struct_check ((d), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 879, __FUNCTION__))->decl_minimal.context)), (tcc_type),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 879, __FUNCTION__))->type_with_lang_specific.lang_specific
))->lambda_expr)
;
880 lambda = most_general_lambda (lambda);
881 d = lambda_function (lambda);
882 }
883
884 if (TREE_CODE (d)((enum tree_code) (d)->base.code) == TEMPLATE_DECL)
885 {
886 tmpl = d;
887 decl = DECL_TEMPLATE_RESULT (tmpl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 887, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
888 }
889 else
890 {
891 if (tree ti = DECL_TEMPLATE_INFO (d)(((contains_struct_check ((template_info_decl_check ((d), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 891, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 891, __FUNCTION__))->decl_common.lang_specific) ->u.min
.template_info)
)
892 tmpl = TI_TEMPLATE (ti)((struct tree_template_info*)(tree_check ((ti), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 892, __FUNCTION__, (TEMPLATE_INFO))))->tmpl
;
893 else
894 tmpl = NULL_TREE(tree) __null;
895 decl = d;
896 }
897
898 /* Get the most general template for the declaration, and compute
899 arguments from that. This ensures that the arguments used for
900 normalization are always template parameters and not arguments
901 used for outer specializations. For example:
902
903 template<typename T>
904 struct S {
905 template<typename U> requires C<T, U> void f(U);
906 };
907
908 S<int>::f(0);
909
910 When we normalize the requirements for S<int>::f, we want the
911 arguments to be {T, U}, not {int, U}. One reason for this is that
912 accepting the latter causes the template parameter level of U
913 to be reduced in a way that makes it overly difficult substitute
914 concrete arguments (i.e., eventually {int, int} during satisfaction. */
915 if (tmpl)
916 {
917 if (DECL_LANG_SPECIFIC(tmpl)((contains_struct_check ((tmpl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 917, __FUNCTION__))->decl_common.lang_specific)
&& !DECL_TEMPLATE_SPECIALIZATION (tmpl)((((contains_struct_check ((tmpl), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 917, __FUNCTION__))->decl_common.lang_specific)->u.base
.use_template) == 2)
)
918 tmpl = most_general_template (tmpl);
919 }
920
921 d = tmpl ? tmpl : decl;
922
923 /* If we're not diagnosing errors, use cached constraints, if any. */
924 if (!diag)
925 if (tree *p = hash_map_safe_get (normalized_map, d))
926 return *p;
927
928 tree norm = NULL_TREE(tree) __null;
929 if (tree ci = get_constraints (d))
930 {
931 push_access_scope_guard pas (decl);
932 norm = get_normalized_constraints_from_info (ci, tmpl, diag);
933 }
934
935 if (!diag)
936 hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
937
938 return norm;
939}
940
941/* Returns the normal form of TMPL's definition. */
942
943static tree
944normalize_concept_definition (tree tmpl, bool diag = false)
945{
946 if (!diag)
947 if (tree *p = hash_map_safe_get (normalized_map, tmpl))
948 return *p;
949
950 gcc_assert (concept_definition_p (tmpl))((void)(!(concept_definition_p (tmpl)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 950, __FUNCTION__), 0 : 0))
;
951 if (OVL_P (tmpl)(((enum tree_code) (tmpl)->base.code) == FUNCTION_DECL || (
(enum tree_code) (tmpl)->base.code) == OVERLOAD)
)
952 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
953 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL)((void)(!(((enum tree_code) (tmpl)->base.code) == TEMPLATE_DECL
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 953, __FUNCTION__), 0 : 0))
;
954 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 954, __FUNCTION__, (TEMPLATE_DECL))))))))->result
);
955 ++processing_template_declscope_chain->x_processing_template_decl;
956 norm_info info (tmpl, diag ? tf_norm : tf_none);
957 tree norm = get_normalized_constraints (def, info);
958 --processing_template_declscope_chain->x_processing_template_decl;
959
960 if (!diag)
961 hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
962
963 return norm;
964}
965
966/* Normalize an EXPR as a constraint. */
967
968static tree
969normalize_constraint_expression (tree expr, norm_info info)
970{
971 if (!expr || expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
972 return expr;
973
974 if (!info.generate_diagnostics ())
975 if (tree *p = hash_map_safe_get (normalized_map, expr))
976 return *p;
977
978 ++processing_template_declscope_chain->x_processing_template_decl;
979 tree norm = get_normalized_constraints (expr, info);
980 --processing_template_declscope_chain->x_processing_template_decl;
981
982 if (!info.generate_diagnostics ())
983 hash_map_safe_put<hm_ggc> (normalized_map, expr, norm);
984
985 return norm;
986}
987
988/* 17.4.1.2p2. Two constraints are identical if they are formed
989 from the same expression and the targets of the parameter mapping
990 are equivalent. */
991
992bool
993atomic_constraints_identical_p (tree t1, tree t2)
994{
995 gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR)((void)(!(((enum tree_code) (t1)->base.code) == ATOMIC_CONSTR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 995, __FUNCTION__), 0 : 0))
;
996 gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR)((void)(!(((enum tree_code) (t2)->base.code) == ATOMIC_CONSTR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 996, __FUNCTION__), 0 : 0))
;
997
998 if (ATOMIC_CONSTR_EXPR (t1)((tree_check ((((contains_struct_check (((tree_check3 (((tree_check
((t1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (TREE_LIST)))->list.purpose)
!= ATOMIC_CONSTR_EXPR (t2)((tree_check ((((contains_struct_check (((tree_check3 (((tree_check
((t2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 998, __FUNCTION__, (TREE_LIST)))->list.purpose)
)
999 return false;
1000
1001 if (!parameter_mapping_equivalent_p (t1, t2))
1002 return false;
1003
1004 return true;
1005}
1006
1007/* True if T1 and T2 are equivalent, meaning they have the same syntactic
1008 structure and all corresponding constraints are identical. */
1009
1010bool
1011constraints_equivalent_p (tree t1, tree t2)
1012{
1013 gcc_assert (CONSTR_P (t1))((void)(!((((enum tree_code) (t1)->base.code) == ATOMIC_CONSTR
|| ((enum tree_code) (t1)->base.code) == CONJ_CONSTR || (
(enum tree_code) (t1)->base.code) == DISJ_CONSTR)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1013, __FUNCTION__), 0 : 0))
;
1014 gcc_assert (CONSTR_P (t2))((void)(!((((enum tree_code) (t2)->base.code) == ATOMIC_CONSTR
|| ((enum tree_code) (t2)->base.code) == CONJ_CONSTR || (
(enum tree_code) (t2)->base.code) == DISJ_CONSTR)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1014, __FUNCTION__), 0 : 0))
;
1015
1016 if (TREE_CODE (t1)((enum tree_code) (t1)->base.code) != TREE_CODE (t2)((enum tree_code) (t2)->base.code))
1017 return false;
1018
1019 switch (TREE_CODE (t1)((enum tree_code) (t1)->base.code))
1020 {
1021 case CONJ_CONSTR:
1022 case DISJ_CONSTR:
1023 if (!constraints_equivalent_p (TREE_OPERAND (t1, 0)(*((const_cast<tree*> (tree_operand_check ((t1), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1023, __FUNCTION__)))))
, TREE_OPERAND (t2, 0)(*((const_cast<tree*> (tree_operand_check ((t2), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1023, __FUNCTION__)))))
))
1024 return false;
1025 if (!constraints_equivalent_p (TREE_OPERAND (t1, 1)(*((const_cast<tree*> (tree_operand_check ((t1), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1025, __FUNCTION__)))))
, TREE_OPERAND (t2, 1)(*((const_cast<tree*> (tree_operand_check ((t2), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1025, __FUNCTION__)))))
))
1026 return false;
1027 break;
1028 case ATOMIC_CONSTR:
1029 if (!atomic_constraints_identical_p(t1, t2))
1030 return false;
1031 break;
1032 default:
1033 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1033, __FUNCTION__))
;
1034 }
1035 return true;
1036}
1037
1038/* Compute the hash value for T. */
1039
1040hashval_t
1041hash_atomic_constraint (tree t)
1042{
1043 gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR)((void)(!(((enum tree_code) (t)->base.code) == ATOMIC_CONSTR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1043, __FUNCTION__), 0 : 0))
;
1044
1045 /* Hash the identity of the expression. */
1046 hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1046, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1046, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1046, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1046, __FUNCTION__, (TREE_LIST)))->list.purpose)
);
1047
1048 /* Hash the targets of the parameter map. */
1049 tree p = ATOMIC_CONSTR_MAP (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1049, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1049, __FUNCTION__)))))
;
1050 while (p)
1051 {
1052 val = iterative_hash_template_arg (TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1052, __FUNCTION__, (TREE_LIST)))->list.purpose)
, val);
1053 p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1053, __FUNCTION__))->common.chain)
;
1054 }
1055
1056 return val;
1057}
1058
1059namespace inchash
1060{
1061
1062static void
1063add_constraint (tree t, hash& h)
1064{
1065 h.add_int(TREE_CODE (t)((enum tree_code) (t)->base.code));
1066 switch (TREE_CODE (t)((enum tree_code) (t)->base.code))
1067 {
1068 case CONJ_CONSTR:
1069 case DISJ_CONSTR:
1070 add_constraint (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1070, __FUNCTION__)))))
, h);
1071 add_constraint (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1071, __FUNCTION__)))))
, h);
1072 break;
1073 case ATOMIC_CONSTR:
1074 h.merge_hash (hash_atomic_constraint (t));
1075 break;
1076 default:
1077 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1077, __FUNCTION__))
;
1078 }
1079}
1080
1081}
1082
1083/* Computes a hash code for the constraint T. */
1084
1085hashval_t
1086iterative_hash_constraint (tree t, hashval_t val)
1087{
1088 gcc_assert (CONSTR_P (t))((void)(!((((enum tree_code) (t)->base.code) == ATOMIC_CONSTR
|| ((enum tree_code) (t)->base.code) == CONJ_CONSTR || ((
enum tree_code) (t)->base.code) == DISJ_CONSTR)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1088, __FUNCTION__), 0 : 0))
;
1089 inchash::hash h (val);
1090 inchash::add_constraint (t, h);
1091 return h.end ();
1092}
1093
1094// -------------------------------------------------------------------------- //
1095// Constraint Semantic Processing
1096//
1097// The following functions are called by the parser and substitution rules
1098// to create and evaluate constraint-related nodes.
1099
1100// The constraints associated with the current template parameters.
1101tree
1102current_template_constraints (void)
1103{
1104 if (!current_template_parmsscope_chain->template_parms)
1105 return NULL_TREE(tree) __null;
1106 tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms)((contains_struct_check (((tree_check ((scope_chain->template_parms
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1106, __FUNCTION__, (TREE_LIST)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1106, __FUNCTION__))->typed.type)
;
1107 return build_constraints (tmpl_constr, NULL_TREE(tree) __null);
1108}
1109
1110/* If the recently parsed TYPE declares or defines a template or
1111 template specialization, get its corresponding constraints from the
1112 current template parameters and bind them to TYPE's declaration. */
1113
1114tree
1115associate_classtype_constraints (tree type)
1116{
1117 if (!type || type == error_mark_nodeglobal_trees[TI_ERROR_MARK] || !CLASS_TYPE_P (type)(((((enum tree_code) (type)->base.code)) == RECORD_TYPE ||
(((enum tree_code) (type)->base.code)) == UNION_TYPE) &&
((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1117, __FUNCTION__))->type_common.lang_flag_5))
)
1118 return type;
1119
1120 /* An explicit class template specialization has no template parameters. */
1121 if (!current_template_parmsscope_chain->template_parms)
1122 return type;
1123
1124 if (CLASSTYPE_IS_TEMPLATE (type)((((tree_class_check (((tree_check3 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->type_non_common.lang_1)) &&
!((((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->type_with_lang_specific.lang_specific
))->use_template) && (((((contains_struct_check ((
((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((((struct tree_template_info
*)(tree_check (((((tree_class_check (((tree_check3 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->type_non_common.lang_1))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (TEMPLATE_INFO))))->tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (TREE_LIST)))->list.value)), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->typed.type))) == (((struct tree_template_info
*)(tree_check (((((tree_class_check (((tree_check3 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->type_non_common.lang_1))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__, (TEMPLATE_INFO))))->tmpl)))
|| CLASSTYPE_TEMPLATE_SPECIALIZATION (type)(((((tree_class_check ((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1124, __FUNCTION__))->type_with_lang_specific.lang_specific
))->use_template) == 2)
)
1125 {
1126 tree decl = TYPE_STUB_DECL (type)(((contains_struct_check (((tree_class_check ((type), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1126, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1126, __FUNCTION__))->common.chain))
;
1127 tree ci = current_template_constraints ();
1128
1129 /* An implicitly instantiated member template declaration already
1130 has associated constraints. If it is defined outside of its
1131 class, then we need match these constraints against those of
1132 original declaration. */
1133 if (tree orig_ci = get_constraints (decl))
1134 {
1135 if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)((long) ((unsigned long) (*tree_int_cst_elt_check ((((tree_check
((scope_chain->template_parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1135, __FUNCTION__, (TREE_LIST)))->list.purpose)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1135, __FUNCTION__))))
1136 - TMPL_ARGS_DEPTH (TYPE_TI_ARGS (type))(((((struct tree_template_info*)(tree_check (((((enum tree_code
) (type)->base.code) == ENUMERAL_TYPE || ((enum tree_code)
(type)->base.code) == BOUND_TEMPLATE_TEMPLATE_PARM || (((
enum tree_code) (type)->base.code) == RECORD_TYPE || ((enum
tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code
) (type)->base.code) == QUAL_UNION_TYPE) ? ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))->type_non_common.lang_1) : (tree) __null
)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TEMPLATE_INFO))))->args) &&
((tree_check (((((struct tree_template_info*)(tree_check (((
((enum tree_code) (type)->base.code) == ENUMERAL_TYPE || (
(enum tree_code) (type)->base.code) == BOUND_TEMPLATE_TEMPLATE_PARM
|| (((enum tree_code) (type)->base.code) == RECORD_TYPE ||
((enum tree_code) (type)->base.code) == UNION_TYPE || ((enum
tree_code) (type)->base.code) == QUAL_UNION_TYPE) ? ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))->type_non_common.lang_1) : (tree) __null
)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TEMPLATE_INFO))))->args)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check (((((struct
tree_template_info*)(tree_check (((((enum tree_code) (type)->
base.code) == ENUMERAL_TYPE || ((enum tree_code) (type)->base
.code) == BOUND_TEMPLATE_TEMPLATE_PARM || (((enum tree_code) (
type)->base.code) == RECORD_TYPE || ((enum tree_code) (type
)->base.code) == UNION_TYPE || ((enum tree_code) (type)->
base.code) == QUAL_UNION_TYPE) ? ((tree_class_check ((type), (
tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))->type_non_common.lang_1) : (tree) __null
)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TEMPLATE_INFO))))->args)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check (((((struct tree_template_info
*)(tree_check (((((enum tree_code) (type)->base.code) == ENUMERAL_TYPE
|| ((enum tree_code) (type)->base.code) == BOUND_TEMPLATE_TEMPLATE_PARM
|| (((enum tree_code) (type)->base.code) == RECORD_TYPE ||
((enum tree_code) (type)->base.code) == UNION_TYPE || ((enum
tree_code) (type)->base.code) == QUAL_UNION_TYPE) ? ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))->type_non_common.lang_1) : (tree) __null
)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TEMPLATE_INFO))))->args)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))))))->base.code) == TREE_VEC) ? ((tree_check
(((((struct tree_template_info*)(tree_check (((((enum tree_code
) (type)->base.code) == ENUMERAL_TYPE || ((enum tree_code)
(type)->base.code) == BOUND_TEMPLATE_TEMPLATE_PARM || (((
enum tree_code) (type)->base.code) == RECORD_TYPE || ((enum
tree_code) (type)->base.code) == UNION_TYPE || ((enum tree_code
) (type)->base.code) == QUAL_UNION_TYPE) ? ((tree_class_check
((type), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__))->type_non_common.lang_1) : (tree) __null
)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TEMPLATE_INFO))))->args)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1136, __FUNCTION__, (TREE_VEC)))->base.u.length) : 1)
))
1137 {
1138 /* If there is a discrepancy between the current template depth
1139 and the template depth of the original declaration, then we
1140 must be redeclaring a class template as part of a friend
1141 declaration within another class template. Before matching
1142 constraints, we need to reduce the template parameter level
1143 within the current constraints via substitution. */
1144 tree outer_gtargs = template_parms_to_args (current_template_parmsscope_chain->template_parms);
1145 TREE_VEC_LENGTH (outer_gtargs)((tree_check ((outer_gtargs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1145, __FUNCTION__, (TREE_VEC)))->base.u.length)
= extra_levels;
1146 ci = tsubst_constraint_info (ci, outer_gtargs, tf_none, NULL_TREE(tree) __null);
1147 }
1148 if (!equivalent_constraints (ci, orig_ci))
1149 {
1150 error ("%qT does not match original declaration", type);
1151 tree tmpl = CLASSTYPE_TI_TEMPLATE (type)((struct tree_template_info*)(tree_check (((((tree_class_check
(((tree_check3 ((type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1151, __FUNCTION__, (RECORD_TYPE), (UNION_TYPE), (QUAL_UNION_TYPE
)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1151, __FUNCTION__))->type_non_common.lang_1))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1151, __FUNCTION__, (TEMPLATE_INFO))))->tmpl
;
1152 location_t loc = DECL_SOURCE_LOCATION (tmpl)((contains_struct_check ((tmpl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1152, __FUNCTION__))->decl_minimal.locus)
;
1153 inform (loc, "original template declaration here");
1154 /* Fall through, so that we define the type anyway. */
1155 }
1156 return type;
1157 }
1158 set_constraints (decl, ci);
1159 }
1160 return type;
1161}
1162
1163/* Create an empty constraint info block. */
1164
1165static inline tree_constraint_info*
1166build_constraint_info ()
1167{
1168 return (tree_constraint_info *)make_node (CONSTRAINT_INFO);
1169}
1170
1171/* Build a constraint-info object that contains the associated constraints
1172 of a declaration. This also includes the declaration's template
1173 requirements (TREQS) and any trailing requirements for a function
1174 declarator (DREQS). Note that both TREQS and DREQS must be constraints.
1175
1176 If the declaration has neither template nor declaration requirements
1177 this returns NULL_TREE, indicating an unconstrained declaration. */
1178
1179tree
1180build_constraints (tree tr, tree dr)
1181{
1182 if (!tr && !dr)
1183 return NULL_TREE(tree) __null;
1184
1185 tree_constraint_info* ci = build_constraint_info ();
1186 ci->template_reqs = tr;
1187 ci->declarator_reqs = dr;
1188 ci->associated_constr = combine_constraint_expressions (tr, dr);
1189
1190 return (tree)ci;
1191}
1192
1193/* Add constraint RHS to the end of CONSTRAINT_INFO ci. */
1194
1195tree
1196append_constraint (tree ci, tree rhs)
1197{
1198 tree tr = ci ? CI_TEMPLATE_REQS (ci)check_constraint_info (check_nonnull (ci))->template_reqs : NULL_TREE(tree) __null;
1199 tree dr = ci ? CI_DECLARATOR_REQS (ci)check_constraint_info (check_nonnull (ci))->declarator_reqs : NULL_TREE(tree) __null;
1200 dr = combine_constraint_expressions (dr, rhs);
1201 if (ci)
1202 {
1203 CI_DECLARATOR_REQS (ci)check_constraint_info (check_nonnull (ci))->declarator_reqs = dr;
1204 tree ac = combine_constraint_expressions (tr, dr);
1205 CI_ASSOCIATED_CONSTRAINTS (ci)check_constraint_info (check_nonnull (ci))->associated_constr = ac;
1206 }
1207 else
1208 ci = build_constraints (tr, dr);
1209 return ci;
1210}
1211
1212/* A mapping from declarations to constraint information. */
1213
1214static GTY ((cache)) decl_tree_cache_map *decl_constraints;
1215
1216/* Returns the template constraints of declaration T. If T is not
1217 constrained, return NULL_TREE. Note that T must be non-null. */
1218
1219tree
1220get_constraints (const_tree t)
1221{
1222 if (!flag_conceptsglobal_options.x_flag_concepts)
1223 return NULL_TREE(tree) __null;
1224 if (!decl_constraints)
1225 return NULL_TREE(tree) __null;
1226
1227 gcc_assert (DECL_P (t))((void)(!((tree_code_type[(int) (((enum tree_code) (t)->base
.code))] == tcc_declaration)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1227, __FUNCTION__), 0 : 0))
;
1228 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == TEMPLATE_DECL)
1229 t = DECL_TEMPLATE_RESULT (t)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1229, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
1230 tree* found = decl_constraints->get (CONST_CAST_TREE (t)(const_cast<union tree_node *> (((t)))));
1231 if (found)
1232 return *found;
1233 else
1234 return NULL_TREE(tree) __null;
1235}
1236
1237/* Associate the given constraint information CI with the declaration
1238 T. If T is a template, then the constraints are associated with
1239 its underlying declaration. Don't build associations if CI is
1240 NULL_TREE. */
1241
1242void
1243set_constraints (tree t, tree ci)
1244{
1245 if (!ci)
1246 return;
1247 gcc_assert (t && flag_concepts)((void)(!(t && global_options.x_flag_concepts) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1247, __FUNCTION__), 0 : 0))
;
1248 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == TEMPLATE_DECL)
1249 t = DECL_TEMPLATE_RESULT (t)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1249, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
1250 bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
1251 gcc_assert (!found)((void)(!(!found) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1251, __FUNCTION__), 0 : 0))
;
1252}
1253
1254/* Remove the associated constraints of the declaration T. */
1255
1256void
1257remove_constraints (tree t)
1258{
1259 gcc_checking_assert (DECL_P (t))((void)(!((tree_code_type[(int) (((enum tree_code) (t)->base
.code))] == tcc_declaration)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1259, __FUNCTION__), 0 : 0))
;
1260 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == TEMPLATE_DECL)
1261 t = DECL_TEMPLATE_RESULT (t)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1261, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
1262
1263 if (decl_constraints)
1264 decl_constraints->remove (t);
1265}
1266
1267/* If DECL is a friend, substitute into REQS to produce requirements suitable
1268 for declaration matching. */
1269
1270tree
1271maybe_substitute_reqs_for (tree reqs, const_tree decl_)
1272{
1273 if (reqs == NULL_TREE(tree) __null)
1274 return NULL_TREE(tree) __null;
1275
1276 tree decl = CONST_CAST_TREE (decl_)(const_cast<union tree_node *> (((decl_))));
1277 tree result = STRIP_TEMPLATE (decl)(((enum tree_code) (decl)->base.code) == TEMPLATE_DECL ? (
(struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1277, __FUNCTION__, (TEMPLATE_DECL))))))))->result : decl
)
;
1278
1279 if (DECL_UNIQUE_FRIEND_P (result)(((contains_struct_check (((tree_check ((result), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1279, __FUNCTION__, (FUNCTION_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1279, __FUNCTION__))->decl_common.lang_specific) ->u.
base.friend_or_tls)
)
1280 {
1281 tree tmpl = decl;
1282 if (TREE_CODE (decl)((enum tree_code) (decl)->base.code) != TEMPLATE_DECL)
1283 tmpl = DECL_TI_TEMPLATE (result)((struct tree_template_info*)(tree_check (((((contains_struct_check
((template_info_decl_check ((result), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1283, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1283, __FUNCTION__))->decl_common.lang_specific) ->u.
min.template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1283, __FUNCTION__, (TEMPLATE_INFO))))->tmpl
;
1284
1285 tree gargs = generic_targs_for (tmpl);
1286 processing_template_decl_sentinel s;
1287 if (uses_template_parms (gargs))
1288 ++processing_template_declscope_chain->x_processing_template_decl;
1289 reqs = tsubst_constraint (reqs, gargs,
1290 tf_warning_or_error, NULL_TREE(tree) __null);
1291 }
1292 return reqs;
1293}
1294
1295/* Returns the trailing requires clause of the declarator of
1296 a template declaration T or NULL_TREE if none. */
1297
1298tree
1299get_trailing_function_requirements (tree t)
1300{
1301 tree ci = get_constraints (t);
1302 if (!ci)
1303 return NULL_TREE(tree) __null;
1304 return CI_DECLARATOR_REQS (ci)check_constraint_info (check_nonnull (ci))->declarator_reqs;
1305}
1306
1307/* Construct a sequence of template arguments by prepending
1308 ARG to REST. Either ARG or REST may be null. */
1309static tree
1310build_concept_check_arguments (tree arg, tree rest)
1311{
1312 gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true)((void)(!(rest ? ((enum tree_code) (rest)->base.code) == TREE_VEC
: true) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1312, __FUNCTION__), 0 : 0))
;
1313 tree args;
1314 if (arg)
1315 {
1316 int n = rest ? TREE_VEC_LENGTH (rest)((tree_check ((rest), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1316, __FUNCTION__, (TREE_VEC)))->base.u.length)
: 0;
1317 args = make_tree_vec (n + 1);
1318 TREE_VEC_ELT (args, 0)(*((const_cast<tree *> (tree_vec_elt_check ((args), (0)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1318, __FUNCTION__)))))
= arg;
1319 if (rest)
1320 for (int i = 0; i < n; ++i)
1321 TREE_VEC_ELT (args, i + 1)(*((const_cast<tree *> (tree_vec_elt_check ((args), (i +
1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1321, __FUNCTION__)))))
= TREE_VEC_ELT (rest, i)(*((const_cast<tree *> (tree_vec_elt_check ((rest), (i)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1321, __FUNCTION__)))))
;
1322 int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest)int_cst_value (((contains_struct_check (((tree_check ((rest),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1322, __FUNCTION__, (TREE_VEC)))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1322, __FUNCTION__))->common.chain))
: 0;
1323 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1)((contains_struct_check (((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1323, __FUNCTION__, (TREE_VEC)))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1323, __FUNCTION__))->common.chain) = build_int_cst ((tree
) __null, def + 1)
;
1324 }
1325 else
1326 {
1327 args = rest;
1328 }
1329 return args;
1330}
1331
1332/* Builds an id-expression of the form `C<Args...>()` where C is a function
1333 concept. */
1334
1335static tree
1336build_function_check (tree tmpl, tree args, tsubst_flags_t /*complain*/)
1337{
1338 if (TREE_CODE (tmpl)((enum tree_code) (tmpl)->base.code) == TEMPLATE_DECL)
1339 {
1340 /* If we just got a template, wrap it in an overload so it looks like any
1341 other template-id. */
1342 tmpl = ovl_make (tmpl);
1343 TREE_TYPE (tmpl)((contains_struct_check ((tmpl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1343, __FUNCTION__))->typed.type)
= boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE];
1344 }
1345
1346 /* Perform function concept resolution now so we always have a single
1347 function of the overload set (even if we started with only one; the
1348 resolution function converts template arguments). Note that we still
1349 wrap this in an overload set so we don't upset other parts of the
1350 compiler that expect template-ids referring to function concepts
1351 to have an overload set. */
1352 tree info = resolve_function_concept_overload (tmpl, args);
1353 if (info == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1354 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1355 if (!info)
1356 {
1357 error ("no matching concepts for %qE", tmpl);
1358 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1359 }
1360 args = TREE_PURPOSE (info)((tree_check ((info), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1360, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
1361 tmpl = DECL_TI_TEMPLATE (TREE_VALUE (info))((struct tree_template_info*)(tree_check (((((contains_struct_check
((template_info_decl_check ((((tree_check ((info), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1361, __FUNCTION__, (TREE_LIST)))->list.value)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1361, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1361, __FUNCTION__))->decl_common.lang_specific) ->u.
min.template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1361, __FUNCTION__, (TEMPLATE_INFO))))->tmpl
;
1362
1363 /* Rebuild the singleton overload set; mark the type bool. */
1364 tmpl = ovl_make (tmpl, NULL_TREE(tree) __null);
1365 TREE_TYPE (tmpl)((contains_struct_check ((tmpl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1365, __FUNCTION__))->typed.type)
= boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE];
1366
1367 /* Build the id-expression around the overload set. */
1368 tree id = build2 (TEMPLATE_ID_EXPR, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], tmpl, args);
1369
1370 /* Finally, build the call expression around the overload. */
1371 ++processing_template_declscope_chain->x_processing_template_decl;
1372 vec<tree, va_gc> *fargs = make_tree_vector ();
1373 tree call = build_min_nt_call_vec (id, fargs);
1374 TREE_TYPE (call)((contains_struct_check ((call), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1374, __FUNCTION__))->typed.type)
= boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE];
1375 release_tree_vector (fargs);
1376 --processing_template_declscope_chain->x_processing_template_decl;
1377
1378 return call;
1379}
1380
1381/* Builds an id-expression of the form `C<Args...>` where C is a variable
1382 concept. */
1383
1384static tree
1385build_variable_check (tree tmpl, tree args, tsubst_flags_t complain)
1386{
1387 gcc_assert (variable_concept_p (tmpl))((void)(!(variable_concept_p (tmpl)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1387, __FUNCTION__), 0 : 0))
;
1388 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL)((void)(!(((enum tree_code) (tmpl)->base.code) == TEMPLATE_DECL
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1388, __FUNCTION__), 0 : 0))
;
1389 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl))((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1389, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1389, __FUNCTION__, (TREE_LIST)))->list.value)
;
1390 args = coerce_template_parms (parms, args, tmpl, complain);
1391 if (args == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1392 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1393 return build2 (TEMPLATE_ID_EXPR, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], tmpl, args);
1394}
1395
1396/* Builds an id-expression of the form `C<Args...>` where C is a standard
1397 concept. */
1398
1399static tree
1400build_standard_check (tree tmpl, tree args, tsubst_flags_t complain)
1401{
1402 gcc_assert (standard_concept_p (tmpl))((void)(!(standard_concept_p (tmpl)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1402, __FUNCTION__), 0 : 0))
;
1403 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL)((void)(!(((enum tree_code) (tmpl)->base.code) == TEMPLATE_DECL
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1403, __FUNCTION__), 0 : 0))
;
1404 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl))((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1404, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1404, __FUNCTION__, (TREE_LIST)))->list.value)
;
1405 args = coerce_template_parms (parms, args, tmpl, complain);
1406 if (args == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1407 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1408 return build2 (TEMPLATE_ID_EXPR, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], tmpl, args);
1409}
1410
1411/* Construct an expression that checks TARGET using ARGS. */
1412
1413tree
1414build_concept_check (tree target, tree args, tsubst_flags_t complain)
1415{
1416 return build_concept_check (target, NULL_TREE(tree) __null, args, complain);
1417}
1418
1419/* Construct an expression that checks the concept given by DECL. If
1420 concept_definition_p (DECL) is false, this returns null. */
1421
1422tree
1423build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain)
1424{
1425 tree args = build_concept_check_arguments (arg, rest);
1426
1427 if (standard_concept_p (decl))
1428 return build_standard_check (decl, args, complain);
1429 if (variable_concept_p (decl))
1430 return build_variable_check (decl, args, complain);
1431 if (function_concept_p (decl))
1432 return build_function_check (decl, args, complain);
1433
1434 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1435}
1436
1437/* Build a template-id that can participate in a concept check. */
1438
1439static tree
1440build_concept_id (tree decl, tree args)
1441{
1442 tree check = build_concept_check (decl, args, tf_warning_or_error);
1443 if (check == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1444 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1445 return unpack_concept_check (check);
1446}
1447
1448/* Build a template-id that can participate in a concept check, preserving
1449 the source location of the original template-id. */
1450
1451tree
1452build_concept_id (tree expr)
1453{
1454 gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR)((void)(!(((enum tree_code) (expr)->base.code) == TEMPLATE_ID_EXPR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1454, __FUNCTION__), 0 : 0))
;
1455 tree id = build_concept_id (TREE_OPERAND (expr, 0)(*((const_cast<tree*> (tree_operand_check ((expr), (0),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1455, __FUNCTION__)))))
, TREE_OPERAND (expr, 1)(*((const_cast<tree*> (tree_operand_check ((expr), (1),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1455, __FUNCTION__)))))
);
1456 protected_set_expr_location (id, cp_expr_location (expr));
1457 return id;
1458}
1459
1460/* Build as template-id with a placeholder that can be used as a
1461 type constraint.
1462
1463 Note that this will diagnose errors if the initial concept check
1464 cannot be built. */
1465
1466tree
1467build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
1468{
1469 tree wildcard = build_nt (WILDCARD_DECL);
1470 ++processing_template_declscope_chain->x_processing_template_decl;
1471 tree check = build_concept_check (decl, wildcard, args, complain);
1472 --processing_template_declscope_chain->x_processing_template_decl;
1473 if (check == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1474 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1475 return unpack_concept_check (check);
1476}
1477
1478/* Returns a TYPE_DECL that contains sufficient information to
1479 build a template parameter of the same kind as PROTO and
1480 constrained by the concept declaration CNC. Note that PROTO
1481 is the first template parameter of CNC.
1482
1483 If specified, ARGS provides additional arguments to the
1484 constraint check. */
1485tree
1486build_constrained_parameter (tree cnc, tree proto, tree args)
1487{
1488 tree name = DECL_NAME (cnc)((contains_struct_check ((cnc), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1488, __FUNCTION__))->decl_minimal.name)
;
1489 tree type = TREE_TYPE (proto)((contains_struct_check ((proto), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1489, __FUNCTION__))->typed.type)
;
1490 tree decl = build_decl (input_location, TYPE_DECL, name, type);
1491 CONSTRAINED_PARM_PROTOTYPE (decl)((contains_struct_check (((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1491, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1491, __FUNCTION__))->decl_common.initial)
= proto;
1492 CONSTRAINED_PARM_CONCEPT (decl)((contains_struct_check (((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1492, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1492, __FUNCTION__))->decl_common.size_unit)
= cnc;
1493 CONSTRAINED_PARM_EXTRA_ARGS (decl)((contains_struct_check (((tree_check ((decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1493, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1493, __FUNCTION__))->decl_common.size)
= args;
1494 return decl;
1495}
1496
1497/* Create a constraint expression for the given DECL that evaluates the
1498 requirements specified by CONSTR, a TYPE_DECL that contains all the
1499 information necessary to build the requirements (see finish_concept_name
1500 for the layout of that TYPE_DECL).
1501
1502 Note that the constraints are neither reduced nor decomposed. That is
1503 done only after the requires clause has been parsed (or not). */
1504
1505tree
1506finish_shorthand_constraint (tree decl, tree constr)
1507{
1508 /* No requirements means no constraints. */
1509 if (!constr)
1510 return NULL_TREE(tree) __null;
1511
1512 if (error_operand_p (constr))
1513 return NULL_TREE(tree) __null;
1514
1515 tree proto = CONSTRAINED_PARM_PROTOTYPE (constr)((contains_struct_check (((tree_check ((constr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1515, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1515, __FUNCTION__))->decl_common.initial)
;
1516 tree con = CONSTRAINED_PARM_CONCEPT (constr)((contains_struct_check (((tree_check ((constr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1516, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1516, __FUNCTION__))->decl_common.size_unit)
;
1517 tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr)((contains_struct_check (((tree_check ((constr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1517, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1517, __FUNCTION__))->decl_common.size)
;
1518
1519 /* The TS lets use shorthand to constrain a pack of arguments, but the
1520 standard does not.
1521
1522 For the TS, consider:
1523
1524 template<C... Ts> struct s;
1525
1526 If C is variadic (and because Ts is a pack), we associate the
1527 constraint C<Ts...>. In all other cases, we associate
1528 the constraint (C<Ts> && ...).
1529
1530 The standard behavior cannot be overridden by -fconcepts-ts. */
1531 bool variadic_concept_p = template_parameter_pack_p (proto);
1532 bool declared_pack_p = template_parameter_pack_p (decl);
1533 bool apply_to_each_p = (cxx_dialect >= cxx20) ? true : !variadic_concept_p;
1534
1535 /* Get the argument and overload used for the requirement
1536 and adjust it if we're going to expand later. */
1537 tree arg = template_parm_to_arg (decl);
1538 if (apply_to_each_p && declared_pack_p)
1539 arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0))(((enum tree_code) ((*((const_cast<tree *> (tree_vec_elt_check
(((((enum tree_code) (arg)->base.code) == TYPE_ARGUMENT_PACK
? ((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))))))->base.code) == TYPE_PACK_EXPANSION
? ((contains_struct_check (((*((const_cast<tree *> (tree_vec_elt_check
(((((enum tree_code) (arg)->base.code) == TYPE_ARGUMENT_PACK
? ((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__)))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check (((*((const_cast<tree *> (tree_vec_elt_check
(((((enum tree_code) (arg)->base.code) == TYPE_ARGUMENT_PACK
? ((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__)))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1539, __FUNCTION__))))))
;
1540
1541 /* Build the concept constraint-expression. */
1542 tree tmpl = DECL_TI_TEMPLATE (con)((struct tree_template_info*)(tree_check (((((contains_struct_check
((template_info_decl_check ((con), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1542, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1542, __FUNCTION__))->decl_common.lang_specific) ->u.
min.template_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1542, __FUNCTION__, (TEMPLATE_INFO))))->tmpl
;
1543 tree check = tmpl;
1544 if (TREE_CODE (con)((enum tree_code) (con)->base.code) == FUNCTION_DECL)
1545 check = ovl_make (tmpl);
1546 check = build_concept_check (check, arg, args, tf_warning_or_error);
1547
1548 /* Make the check a fold-expression if needed. */
1549 if (apply_to_each_p && declared_pack_p)
1550 check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR);
1551
1552 return check;
1553}
1554
1555/* Returns a conjunction of shorthand requirements for the template
1556 parameter list PARMS. Note that the requirements are stored in
1557 the TYPE of each tree node. */
1558
1559tree
1560get_shorthand_constraints (tree parms)
1561{
1562 tree result = NULL_TREE(tree) __null;
1563 parms = INNERMOST_TEMPLATE_PARMS (parms)((tree_check ((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1563, __FUNCTION__, (TREE_LIST)))->list.value)
;
1564 for (int i = 0; i < TREE_VEC_LENGTH (parms)((tree_check ((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1564, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++i)
1565 {
1566 tree parm = TREE_VEC_ELT (parms, i)(*((const_cast<tree *> (tree_vec_elt_check ((parms), (i
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1566, __FUNCTION__)))))
;
1567 tree constr = TEMPLATE_PARM_CONSTRAINTS (parm)((contains_struct_check (((tree_check ((parm), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1567, __FUNCTION__, (TREE_LIST)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1567, __FUNCTION__))->typed.type)
;
1568 result = combine_constraint_expressions (result, constr);
1569 }
1570 return result;
1571}
1572
1573/* Get the deduced wildcard from a DEDUCED placeholder. If the deduced
1574 wildcard is a pack, return the first argument of that pack. */
1575
1576static tree
1577get_deduced_wildcard (tree wildcard)
1578{
1579 if (ARGUMENT_PACK_P (wildcard)(((enum tree_code) (wildcard)->base.code) == TYPE_ARGUMENT_PACK
|| ((enum tree_code) (wildcard)->base.code) == NONTYPE_ARGUMENT_PACK
)
)
1580 wildcard = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (wildcard), 0)(*((const_cast<tree *> (tree_vec_elt_check (((((enum tree_code
) (wildcard)->base.code) == TYPE_ARGUMENT_PACK? ((contains_struct_check
((wildcard), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1580, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((wildcard), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1580, __FUNCTION__))))))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1580, __FUNCTION__)))))
;
1581 gcc_assert (TREE_CODE (wildcard) == WILDCARD_DECL)((void)(!(((enum tree_code) (wildcard)->base.code) == WILDCARD_DECL
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1581, __FUNCTION__), 0 : 0))
;
1582 return wildcard;
1583}
1584
1585/* Returns the prototype parameter for the nth deduced wildcard. */
1586
1587static tree
1588get_introduction_prototype (tree wildcards, int index)
1589{
1590 return TREE_TYPE (get_deduced_wildcard (TREE_VEC_ELT (wildcards, index)))((contains_struct_check ((get_deduced_wildcard ((*((const_cast
<tree *> (tree_vec_elt_check ((wildcards), (index), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1590, __FUNCTION__))))))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1590, __FUNCTION__))->typed.type)
;
1591}
1592
1593/* Introduce a type template parameter. */
1594
1595static tree
1596introduce_type_template_parameter (tree wildcard, bool& non_type_p)
1597{
1598 non_type_p = false;
1599 return finish_template_type_parm (class_type_nodecp_global_trees[CPTI_CLASS_TYPE], DECL_NAME (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1599, __FUNCTION__))->decl_minimal.name)
);
1600}
1601
1602/* Introduce a template template parameter. */
1603
1604static tree
1605introduce_template_template_parameter (tree wildcard, bool& non_type_p)
1606{
1607 non_type_p = false;
1608 begin_template_parm_list ();
1609 current_template_parmsscope_chain->template_parms = DECL_TEMPLATE_PARMS (TREE_TYPE (wildcard))((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((((contains_struct_check ((wildcard), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1609, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1609, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments
;
1610 end_template_parm_list ();
1611 return finish_template_template_parm (class_type_nodecp_global_trees[CPTI_CLASS_TYPE], DECL_NAME (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1611, __FUNCTION__))->decl_minimal.name)
);
1612}
1613
1614/* Introduce a template non-type parameter. */
1615
1616static tree
1617introduce_nontype_template_parameter (tree wildcard, bool& non_type_p)
1618{
1619 non_type_p = true;
1620 tree parm = copy_decl (TREE_TYPE (wildcard)((contains_struct_check ((wildcard), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1620, __FUNCTION__))->typed.type)
);
1621 DECL_NAME (parm)((contains_struct_check ((parm), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1621, __FUNCTION__))->decl_minimal.name)
= DECL_NAME (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1621, __FUNCTION__))->decl_minimal.name)
;
1622 return parm;
1623}
1624
1625/* Introduce a single template parameter. */
1626
1627static tree
1628build_introduced_template_parameter (tree wildcard, bool& non_type_p)
1629{
1630 tree proto = TREE_TYPE (wildcard)((contains_struct_check ((wildcard), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1630, __FUNCTION__))->typed.type)
;
1631
1632 tree parm;
1633 if (TREE_CODE (proto)((enum tree_code) (proto)->base.code) == TYPE_DECL)
1634 parm = introduce_type_template_parameter (wildcard, non_type_p);
1635 else if (TREE_CODE (proto)((enum tree_code) (proto)->base.code) == TEMPLATE_DECL)
1636 parm = introduce_template_template_parameter (wildcard, non_type_p);
1637 else
1638 parm = introduce_nontype_template_parameter (wildcard, non_type_p);
1639
1640 /* Wrap in a TREE_LIST for process_template_parm. Note that introduced
1641 parameters do not retain the defaults from the source parameter. */
1642 return build_tree_list (NULL_TREE(tree) __null, parm);
1643}
1644
1645/* Introduce a single template parameter. */
1646
1647static tree
1648introduce_template_parameter (tree parms, tree wildcard)
1649{
1650 gcc_assert (!ARGUMENT_PACK_P (wildcard))((void)(!(!(((enum tree_code) (wildcard)->base.code) == TYPE_ARGUMENT_PACK
|| ((enum tree_code) (wildcard)->base.code) == NONTYPE_ARGUMENT_PACK
)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1650, __FUNCTION__), 0 : 0))
;
1651 tree proto = TREE_TYPE (wildcard)((contains_struct_check ((wildcard), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1651, __FUNCTION__))->typed.type)
;
1652 location_t loc = DECL_SOURCE_LOCATION (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1652, __FUNCTION__))->decl_minimal.locus)
;
1653
1654 /* Diagnose the case where we have C{...Args}. */
1655 if (WILDCARD_PACK_P (wildcard)((tree_not_check2 ((wildcard), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1655, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
1656 {
1657 tree id = DECL_NAME (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1657, __FUNCTION__))->decl_minimal.name)
;
1658 error_at (loc, "%qE cannot be introduced with an ellipsis %<...%>", id);
1659 inform (DECL_SOURCE_LOCATION (proto)((contains_struct_check ((proto), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1659, __FUNCTION__))->decl_minimal.locus)
, "prototype declared here");
1660 }
1661
1662 bool non_type_p;
1663 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
1664 return process_template_parm (parms, loc, parm, non_type_p, false);
1665}
1666
1667/* Introduce a template parameter pack. */
1668
1669static tree
1670introduce_template_parameter_pack (tree parms, tree wildcard)
1671{
1672 bool non_type_p;
1673 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
1674 location_t loc = DECL_SOURCE_LOCATION (wildcard)((contains_struct_check ((wildcard), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1674, __FUNCTION__))->decl_minimal.locus)
;
1675 return process_template_parm (parms, loc, parm, non_type_p, true);
1676}
1677
1678/* Introduce the nth template parameter. */
1679
1680static tree
1681introduce_template_parameter (tree parms, tree wildcards, int& index)
1682{
1683 tree deduced = TREE_VEC_ELT (wildcards, index++)(*((const_cast<tree *> (tree_vec_elt_check ((wildcards)
, (index++), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1683, __FUNCTION__)))))
;
1684 return introduce_template_parameter (parms, deduced);
1685}
1686
1687/* Introduce either a template parameter pack or a list of template
1688 parameters. */
1689
1690static tree
1691introduce_template_parameters (tree parms, tree wildcards, int& index)
1692{
1693 /* If the prototype was a parameter, we better have deduced an
1694 argument pack, and that argument must be the last deduced value
1695 in the wildcard vector. */
1696 tree deduced = TREE_VEC_ELT (wildcards, index++)(*((const_cast<tree *> (tree_vec_elt_check ((wildcards)
, (index++), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1696, __FUNCTION__)))))
;
1697 gcc_assert (ARGUMENT_PACK_P (deduced))((void)(!((((enum tree_code) (deduced)->base.code) == TYPE_ARGUMENT_PACK
|| ((enum tree_code) (deduced)->base.code) == NONTYPE_ARGUMENT_PACK
)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1697, __FUNCTION__), 0 : 0))
;
1698 gcc_assert (index == TREE_VEC_LENGTH (wildcards))((void)(!(index == ((tree_check ((wildcards), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1698, __FUNCTION__, (TREE_VEC)))->base.u.length)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1698, __FUNCTION__), 0 : 0))
;
1699
1700 /* Introduce each element in the pack. */
1701 tree args = ARGUMENT_PACK_ARGS (deduced)(((enum tree_code) (deduced)->base.code) == TYPE_ARGUMENT_PACK
? ((contains_struct_check ((deduced), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1701, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((deduced), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1701, __FUNCTION__))))))
;
1702 for (int i = 0; i < TREE_VEC_LENGTH (args)((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1702, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++i)
1703 {
1704 tree arg = TREE_VEC_ELT (args, i)(*((const_cast<tree *> (tree_vec_elt_check ((args), (i)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1704, __FUNCTION__)))))
;
1705 if (WILDCARD_PACK_P (arg)((tree_not_check2 ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1705, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
1706 parms = introduce_template_parameter_pack (parms, arg);
1707 else
1708 parms = introduce_template_parameter (parms, arg);
1709 }
1710
1711 return parms;
1712}
1713
1714/* Builds the template parameter list PARMS by chaining introduced
1715 parameters from the WILDCARD vector. INDEX is the position of
1716 the current parameter. */
1717
1718static tree
1719process_introduction_parms (tree parms, tree wildcards, int& index)
1720{
1721 tree proto = get_introduction_prototype (wildcards, index);
1722 if (template_parameter_pack_p (proto))
1723 return introduce_template_parameters (parms, wildcards, index);
1724 else
1725 return introduce_template_parameter (parms, wildcards, index);
1726}
1727
1728/* Ensure that all template parameters have been introduced for the concept
1729 named in CHECK. If not, emit a diagnostic.
1730
1731 Note that implicitly introducing a parameter with a default argument
1732 creates a case where a parameter is declared, but unnamed, making
1733 it unusable in the definition. */
1734
1735static bool
1736check_introduction_list (tree intros, tree check)
1737{
1738 check = unpack_concept_check (check);
1739 tree tmpl = TREE_OPERAND (check, 0)(*((const_cast<tree*> (tree_operand_check ((check), (0)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1739, __FUNCTION__)))))
;
1740 if (OVL_P (tmpl)(((enum tree_code) (tmpl)->base.code) == FUNCTION_DECL || (
(enum tree_code) (tmpl)->base.code) == OVERLOAD)
)
1741 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
1742
1743 tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl)((tree_check ((((struct tree_template_decl *)(const_cast<union
tree_node *> ((((tree_check ((tmpl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1743, __FUNCTION__, (TEMPLATE_DECL))))))))->arguments), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1743, __FUNCTION__, (TREE_LIST)))->list.value)
;
1744 if (TREE_VEC_LENGTH (intros)((tree_check ((intros), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1744, __FUNCTION__, (TREE_VEC)))->base.u.length)
< TREE_VEC_LENGTH (parms)((tree_check ((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1744, __FUNCTION__, (TREE_VEC)))->base.u.length)
)
1745 {
1746 error_at (input_location, "all template parameters of %qD must "
1747 "be introduced", tmpl);
1748 return false;
1749 }
1750
1751 return true;
1752}
1753
1754/* Associates a constraint check to the current template based on the
1755 introduction parameters. INTRO_LIST must be a TREE_VEC of WILDCARD_DECLs
1756 containing a chained PARM_DECL which contains the identifier as well as
1757 the source location. TMPL_DECL is the decl for the concept being used.
1758 If we take a concept, C, this will form a check in the form of
1759 C<INTRO_LIST> filling in any extra arguments needed by the defaults
1760 deduced.
1761
1762 Returns NULL_TREE if no concept could be matched and error_mark_node if
1763 an error occurred when matching. */
1764
1765tree
1766finish_template_introduction (tree tmpl_decl,
1767 tree intro_list,
1768 location_t intro_loc)
1769{
1770 /* Build a concept check to deduce the actual parameters. */
1771 tree expr = build_concept_check (tmpl_decl, intro_list, tf_none);
1772 if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1773 {
1774 error_at (intro_loc, "cannot deduce template parameters from "
1775 "introduction list");
1776 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1777 }
1778
1779 if (!check_introduction_list (intro_list, expr))
1780 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1781
1782 tree parms = deduce_concept_introduction (expr);
1783 if (!parms)
1784 return NULL_TREE(tree) __null;
1785
1786 /* Build template parameter scope for introduction. */
1787 tree parm_list = NULL_TREE(tree) __null;
1788 begin_template_parm_list ();
1789 int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list))((((tree_check ((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1789, __FUNCTION__, (TREE_VEC)))->base.u.length)) < (
((tree_check ((intro_list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1789, __FUNCTION__, (TREE_VEC)))->base.u.length)) ? (((tree_check
((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1789, __FUNCTION__, (TREE_VEC)))->base.u.length)) : (((tree_check
((intro_list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1789, __FUNCTION__, (TREE_VEC)))->base.u.length)))
;
1790 for (int n = 0; n < nargs; )
1791 parm_list = process_introduction_parms (parm_list, parms, n);
1792 parm_list = end_template_parm_list (parm_list);
1793
1794 /* Update the number of arguments to reflect the number of deduced
1795 template parameter introductions. */
1796 nargs = TREE_VEC_LENGTH (parm_list)((tree_check ((parm_list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1796, __FUNCTION__, (TREE_VEC)))->base.u.length)
;
1797
1798 /* Determine if any errors occurred during matching. */
1799 for (int i = 0; i < TREE_VEC_LENGTH (parm_list)((tree_check ((parm_list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1799, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++i)
1800 if (TREE_VALUE (TREE_VEC_ELT (parm_list, i))((tree_check (((*((const_cast<tree *> (tree_vec_elt_check
((parm_list), (i), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1800, __FUNCTION__)))))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1800, __FUNCTION__, (TREE_LIST)))->list.value)
== error_mark_nodeglobal_trees[TI_ERROR_MARK])
1801 {
1802 end_template_decl ();
1803 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1804 }
1805
1806 /* Build a concept check for our constraint. */
1807 tree check_args = make_tree_vec (nargs);
1808 int n = 0;
1809 for (; n < TREE_VEC_LENGTH (parm_list)((tree_check ((parm_list), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1809, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++n)
1810 {
1811 tree parm = TREE_VEC_ELT (parm_list, n)(*((const_cast<tree *> (tree_vec_elt_check ((parm_list)
, (n), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1811, __FUNCTION__)))))
;
1812 TREE_VEC_ELT (check_args, n)(*((const_cast<tree *> (tree_vec_elt_check ((check_args
), (n), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1812, __FUNCTION__)))))
= template_parm_to_arg (parm);
1813 }
1814 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n)((contains_struct_check (((tree_check ((check_args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1814, __FUNCTION__, (TREE_VEC)))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1814, __FUNCTION__))->common.chain) = build_int_cst ((tree
) __null, n)
;
1815
1816 /* If the template expects more parameters we should be able
1817 to use the defaults from our deduced concept. */
1818 for (; n < TREE_VEC_LENGTH (parms)((tree_check ((parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1818, __FUNCTION__, (TREE_VEC)))->base.u.length)
; ++n)
1819 TREE_VEC_ELT (check_args, n)(*((const_cast<tree *> (tree_vec_elt_check ((check_args
), (n), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1819, __FUNCTION__)))))
= TREE_VEC_ELT (parms, n)(*((const_cast<tree *> (tree_vec_elt_check ((parms), (n
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1819, __FUNCTION__)))))
;
1820
1821 /* Associate the constraint. */
1822 tree check = build_concept_check (tmpl_decl,
1823 check_args,
1824 tf_warning_or_error);
1825 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms)((contains_struct_check (((tree_check ((scope_chain->template_parms
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1825, __FUNCTION__, (TREE_LIST)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1825, __FUNCTION__))->typed.type)
= check;
1826
1827 return parm_list;
1828}
1829
1830
1831/* Given the concept check T from a constrained-type-specifier, extract
1832 its TMPL and ARGS. FIXME why do we need two different forms of
1833 constrained-type-specifier? */
1834
1835void
1836placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args)
1837{
1838 if (concept_check_p (t))
1839 {
1840 t = unpack_concept_check (t);
1841 tmpl = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1841, __FUNCTION__)))))
;
1842 if (TREE_CODE (tmpl)((enum tree_code) (tmpl)->base.code) == OVERLOAD)
1843 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
1844 args = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1844, __FUNCTION__)))))
;
1845 return;
1846 }
1847
1848 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == TYPE_DECL)
1849 {
1850 /* A constrained parameter. Build a constraint check
1851 based on the prototype parameter and then extract the
1852 arguments from that. */
1853 tree proto = CONSTRAINED_PARM_PROTOTYPE (t)((contains_struct_check (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1853, __FUNCTION__, (TYPE_DECL)))), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1853, __FUNCTION__))->decl_common.initial)
;
1854 tree check = finish_shorthand_constraint (proto, t);
1855 placeholder_extract_concept_and_args (check, tmpl, args);
1856 return;
1857 }
1858}
1859
1860/* Returns true iff the placeholders C1 and C2 are equivalent. C1
1861 and C2 can be either TEMPLATE_TYPE_PARM or template-ids. */
1862
1863bool
1864equivalent_placeholder_constraints (tree c1, tree c2)
1865{
1866 if (c1 && TREE_CODE (c1)((enum tree_code) (c1)->base.code) == TEMPLATE_TYPE_PARM)
1867 /* A constrained auto. */
1868 c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1)(((contains_struct_check ((((tree_class_check ((c1), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1868, __FUNCTION__))->type_common.name)), (TS_DECL_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1868, __FUNCTION__))->decl_common.size_unit) ? ((tree_check
((((contains_struct_check ((((tree_class_check ((c1), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1868, __FUNCTION__))->type_common.name)), (TS_DECL_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1868, __FUNCTION__))->decl_common.size_unit)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1868, __FUNCTION__, (TREE_LIST)))->list.value) : (tree) __null
)
;
1869 if (c2 && TREE_CODE (c2)((enum tree_code) (c2)->base.code) == TEMPLATE_TYPE_PARM)
1870 c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2)(((contains_struct_check ((((tree_class_check ((c2), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1870, __FUNCTION__))->type_common.name)), (TS_DECL_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1870, __FUNCTION__))->decl_common.size_unit) ? ((tree_check
((((contains_struct_check ((((tree_class_check ((c2), (tcc_type
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1870, __FUNCTION__))->type_common.name)), (TS_DECL_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1870, __FUNCTION__))->decl_common.size_unit)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1870, __FUNCTION__, (TREE_LIST)))->list.value) : (tree) __null
)
;
1871
1872 if (c1 == c2)
1873 return true;
1874 if (!c1 || !c2)
1875 return false;
1876 if (c1 == error_mark_nodeglobal_trees[TI_ERROR_MARK] || c2 == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1877 /* We get here during satisfaction; when a deduction constraint
1878 fails, substitution can produce an error_mark_node for the
1879 placeholder constraints. */
1880 return false;
1881
1882 tree t1, t2, a1, a2;
1883 placeholder_extract_concept_and_args (c1, t1, a1);
1884 placeholder_extract_concept_and_args (c2, t2, a2);
1885
1886 if (t1 != t2)
1887 return false;
1888
1889 int len1 = TREE_VEC_LENGTH (a1)((tree_check ((a1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1889, __FUNCTION__, (TREE_VEC)))->base.u.length)
;
1890 int len2 = TREE_VEC_LENGTH (a2)((tree_check ((a2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1890, __FUNCTION__, (TREE_VEC)))->base.u.length)
;
1891 if (len1 != len2)
1892 return false;
1893
1894 /* Skip the first argument so we don't infinitely recurse.
1895 Also, they may differ in template parameter index. */
1896 for (int i = 1; i < len1; ++i)
1897 {
1898 tree t1 = TREE_VEC_ELT (a1, i)(*((const_cast<tree *> (tree_vec_elt_check ((a1), (i), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1898, __FUNCTION__)))))
;
1899 tree t2 = TREE_VEC_ELT (a2, i)(*((const_cast<tree *> (tree_vec_elt_check ((a2), (i), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1899, __FUNCTION__)))))
;
1900 if (!template_args_equal (t1, t2))
1901 return false;
1902 }
1903 return true;
1904}
1905
1906/* Return a hash value for the placeholder ATOMIC_CONSTR C. */
1907
1908hashval_t
1909hash_placeholder_constraint (tree c)
1910{
1911 tree t, a;
1912 placeholder_extract_concept_and_args (c, t, a);
1913
1914 /* Like hash_tmpl_and_args, but skip the first argument. */
1915 hashval_t val = iterative_hash_object (DECL_UID (t), 0)iterative_hash (&((contains_struct_check ((t), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1915, __FUNCTION__))->decl_minimal.uid), sizeof (((contains_struct_check
((t), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1915, __FUNCTION__))->decl_minimal.uid)), 0)
;
1916
1917 for (int i = TREE_VEC_LENGTH (a)((tree_check ((a), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1917, __FUNCTION__, (TREE_VEC)))->base.u.length)
-1; i > 0; --i)
1918 val = iterative_hash_template_arg (TREE_VEC_ELT (a, i)(*((const_cast<tree *> (tree_vec_elt_check ((a), (i), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1918, __FUNCTION__)))))
, val);
1919
1920 return val;
1921}
1922
1923/* Substitute through the expression of a simple requirement or
1924 compound requirement. */
1925
1926static tree
1927tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
1928{
1929 tree r = tsubst_expr (t, args, tf_none, info.in_decl, false);
1930 if (convert_to_void (r, ICV_STATEMENT, tf_none) != error_mark_nodeglobal_trees[TI_ERROR_MARK])
1931 return r;
1932
1933 if (info.diagnose_unsatisfaction_p ())
1934 {
1935 location_t loc = cp_expr_loc_or_input_loc (t);
1936 if (diagnosing_failed_constraint::replay_errors_p ())
1937 {
1938 inform (loc, "the required expression %qE is invalid, because", t);
1939 if (r == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1940 tsubst_expr (t, args, info.complain, info.in_decl, false);
1941 else
1942 convert_to_void (r, ICV_STATEMENT, info.complain);
1943 }
1944 else
1945 inform (loc, "the required expression %qE is invalid", t);
1946 }
1947 else if (info.noisy ())
1948 {
1949 r = tsubst_expr (t, args, info.complain, info.in_decl, false);
1950 convert_to_void (r, ICV_STATEMENT, info.complain);
1951 }
1952
1953 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1954}
1955
1956
1957/* Substitute through the simple requirement. */
1958
1959static tree
1960tsubst_simple_requirement (tree t, tree args, sat_info info)
1961{
1962 tree t0 = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 1962, __FUNCTION__)))))
;
1963 tree expr = tsubst_valid_expression_requirement (t0, args, info);
1964 if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
1965 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1966 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
1967}
1968
1969/* Subroutine of tsubst_type_requirement that performs the actual substitution
1970 and diagnosing. Also used by tsubst_compound_requirement. */
1971
1972static tree
1973tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
1974{
1975 tree r = tsubst (t, args, tf_none, info.in_decl);
1976 if (r != error_mark_nodeglobal_trees[TI_ERROR_MARK])
1977 return r;
1978
1979 if (info.diagnose_unsatisfaction_p ())
1980 {
1981 if (diagnosing_failed_constraint::replay_errors_p ())
1982 {
1983 /* Replay the substitution error. */
1984 inform (loc, "the required type %qT is invalid, because", t);
1985 tsubst (t, args, info.complain, info.in_decl);
1986 }
1987 else
1988 inform (loc, "the required type %qT is invalid", t);
1989 }
1990 else if (info.noisy ())
1991 tsubst (t, args, info.complain, info.in_decl);
1992
1993 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
1994}
1995
1996
1997/* Substitute through the type requirement. */
1998
1999static tree
2000tsubst_type_requirement (tree t, tree args, sat_info info)
2001{
2002 tree t0 = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2002, __FUNCTION__)))))
;
2003 tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) (
(t))->base.code))]) >= tcc_reference && (tree_code_type
[(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression
)) ? (t)->exp.locus : ((location_t) 0))
);
2004 if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2005 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2006 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
2007}
2008
2009/* True if TYPE can be deduced from EXPR. */
2010
2011static bool
2012type_deducible_p (tree expr, tree type, tree placeholder, tree args,
2013 subst_info info)
2014{
2015 /* Make sure deduction is performed against ( EXPR ), so that
2016 references are preserved in the result. */
2017 expr = force_paren_expr_uneval (expr);
2018
2019 /* When args is NULL, we're evaluating a non-templated requires expression,
2020 but even those are parsed under processing_template_decl == 1, and so the
2021 placeholder 'auto' inside this return-type-requirement has level 2. In
2022 order to have all parms and arguments match up for satisfaction, we need
2023 to pass an empty level of OUTER_TARGS in this case. */
2024 if (!args)
2025 args = make_tree_vec (0);
2026
2027 tree deduced_type = do_auto_deduction (type, expr, placeholder,
2028 info.complain, adc_requirement,
2029 /*outer_targs=*/args);
2030
2031 return deduced_type != error_mark_nodeglobal_trees[TI_ERROR_MARK];
2032}
2033
2034/* True if EXPR can not be converted to TYPE. */
2035
2036static bool
2037expression_convertible_p (tree expr, tree type, subst_info info)
2038{
2039 tree conv =
2040 perform_direct_initialization_if_possible (type, expr, false,
2041 info.complain);
2042 if (conv == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2043 return false;
2044 if (conv == NULL_TREE(tree) __null)
2045 {
2046 if (info.complain & tf_error)
2047 {
2048 location_t loc = EXPR_LOC_OR_LOC (expr, input_location)((((IS_ADHOC_LOC (((((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)))) ? get_location_from_adhoc_loc (line_table
, ((((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))) : (((((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)))) != ((location_t) 0)) ? (expr)->exp.locus : (input_location
))
;
2049 error_at (loc, "cannot convert %qE to %qT", expr, type);
2050 }
2051 return false;
2052 }
2053 return true;
2054}
2055
2056
2057/* Substitute through the compound requirement. */
2058
2059static tree
2060tsubst_compound_requirement (tree t, tree args, sat_info info)
2061{
2062 tree t0 = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2062, __FUNCTION__)))))
;
2063 tree t1 = TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2063, __FUNCTION__)))))
;
2064 tree expr = tsubst_valid_expression_requirement (t0, args, info);
2065 if (expr == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2066 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2067
2068 location_t loc = cp_expr_loc_or_input_loc (expr);
2069
2070 /* Check the noexcept condition. */
2071 bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t)((tree_not_check2 (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2071, __FUNCTION__, (COMPOUND_REQ)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2071, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
;
2072 if (noexcept_p && !expr_noexcept_p (expr, tf_none))
2073 {
2074 if (info.diagnose_unsatisfaction_p ())
2075 inform (loc, "%qE is not %<noexcept%>", expr);
2076 else
2077 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2078 }
2079
2080 /* Substitute through the type expression, if any. */
2081 tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t)((((t)) && ((tree_code_type[(int) (((enum tree_code) (
(t))->base.code))]) >= tcc_reference && (tree_code_type
[(int) (((enum tree_code) ((t))->base.code))]) <= tcc_expression
)) ? (t)->exp.locus : ((location_t) 0))
);
2082 if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2083 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2084
2085 subst_info quiet (tf_none, info.in_decl);
2086
2087 /* Check expression against the result type. */
2088 if (type)
2089 {
2090 if (tree placeholder = type_uses_auto (type))
2091 {
2092 if (!type_deducible_p (expr, type, placeholder, args, quiet))
2093 {
2094 if (info.diagnose_unsatisfaction_p ())
2095 {
2096 if (diagnosing_failed_constraint::replay_errors_p ())
2097 {
2098 inform (loc,
2099 "%qE does not satisfy return-type-requirement, "
2100 "because", t0);
2101 /* Further explain the reason for the error. */
2102 type_deducible_p (expr, type, placeholder, args, info);
2103 }
2104 else
2105 inform (loc,
2106 "%qE does not satisfy return-type-requirement", t0);
2107 }
2108 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2109 }
2110 }
2111 else if (!expression_convertible_p (expr, type, quiet))
2112 {
2113 if (info.diagnose_unsatisfaction_p ())
2114 {
2115 if (diagnosing_failed_constraint::replay_errors_p ())
2116 {
2117 inform (loc, "cannot convert %qE to %qT because", t0, type);
2118 /* Further explain the reason for the error. */
2119 expression_convertible_p (expr, type, info);
2120 }
2121 else
2122 inform (loc, "cannot convert %qE to %qT", t0, type);
2123 }
2124 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2125 }
2126 }
2127
2128 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
2129}
2130
2131/* Substitute through the nested requirement. */
2132
2133static tree
2134tsubst_nested_requirement (tree t, tree args, sat_info info)
2135{
2136 sat_info quiet (tf_none, info.in_decl);
2137 tree result = constraint_satisfaction_value (t, args, quiet);
2138 if (result == boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE])
2139 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
2140
2141 if (result == boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE]
2142 && info.diagnose_unsatisfaction_p ())
2143 {
2144 tree expr = TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2144, __FUNCTION__)))))
;
2145 location_t loc = cp_expr_location (t);
2146 if (diagnosing_failed_constraint::replay_errors_p ())
2147 {
2148 /* Replay the substitution error. */
2149 inform (loc, "nested requirement %qE is not satisfied, because", expr);
2150 constraint_satisfaction_value (t, args, info);
2151 }
2152 else
2153 inform (loc, "nested requirement %qE is not satisfied", expr);
2154 }
2155
2156 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2157}
2158
2159/* Substitute ARGS into the requirement T. */
2160
2161static tree
2162tsubst_requirement (tree t, tree args, sat_info info)
2163{
2164 iloc_sentinel loc_s (cp_expr_location (t));
2165 switch (TREE_CODE (t)((enum tree_code) (t)->base.code))
2166 {
2167 case SIMPLE_REQ:
2168 return tsubst_simple_requirement (t, args, info);
2169 case TYPE_REQ:
2170 return tsubst_type_requirement (t, args, info);
2171 case COMPOUND_REQ:
2172 return tsubst_compound_requirement (t, args, info);
2173 case NESTED_REQ:
2174 return tsubst_nested_requirement (t, args, info);
2175 default:
2176 break;
2177 }
2178 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2178, __FUNCTION__))
;
2179}
2180
2181static tree
2182declare_constraint_vars (tree parms, tree vars)
2183{
2184 tree s = vars;
2185 for (tree t = parms; t; t = DECL_CHAIN (t)(((contains_struct_check (((contains_struct_check ((t), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2185, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2185, __FUNCTION__))->common.chain))
)
2186 {
2187 if (DECL_PACK_P (t)((tree_code_type[(int) (((enum tree_code) (t)->base.code))
] == tcc_declaration) && (((enum tree_code) (((contains_struct_check
((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2187, __FUNCTION__))->typed.type))->base.code) == TYPE_PACK_EXPANSION
|| ((enum tree_code) (((contains_struct_check ((t), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2187, __FUNCTION__))->typed.type))->base.code) == EXPR_PACK_EXPANSION
))
)
2188 {
2189 tree pack = extract_fnparm_pack (t, &s);
2190 register_local_specialization (pack, t);
2191 }
2192 else
2193 {
2194 register_local_specialization (s, t);
2195 s = DECL_CHAIN (s)(((contains_struct_check (((contains_struct_check ((s), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2195, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2195, __FUNCTION__))->common.chain))
;
2196 }
2197 }
2198 return vars;
2199}
2200
2201/* Substitute through as if checking function parameter types. This
2202 will diagnose common parameter type errors. Returns error_mark_node
2203 if an error occurred. */
2204
2205static tree
2206check_constraint_variables (tree t, tree args, subst_info info)
2207{
2208 tree types = NULL_TREE(tree) __null;
2209 tree p = t;
2210 while (p && !VOID_TYPE_P (p)(((enum tree_code) (p)->base.code) == VOID_TYPE))
2211 {
2212 types = tree_cons (NULL_TREE(tree) __null, TREE_TYPE (p)((contains_struct_check ((p), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2212, __FUNCTION__))->typed.type)
, types);
2213 p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2213, __FUNCTION__))->common.chain)
;
2214 }
2215 types = chainon (nreverse (types), void_list_nodeglobal_trees[TI_VOID_LIST_NODE]);
2216 return tsubst_function_parms (types, args, info.complain, info.in_decl);
2217}
2218
2219/* A subroutine of tsubst_parameterized_constraint. Substitute ARGS
2220 into the parameter list T, producing a sequence of constraint
2221 variables, declared in the current scope.
2222
2223 Note that the caller must establish a local specialization stack
2224 prior to calling this function since this substitution will
2225 declare the substituted parameters. */
2226
2227static tree
2228tsubst_constraint_variables (tree t, tree args, subst_info info)
2229{
2230 /* Perform a trial substitution to check for type errors. */
2231 tree parms = check_constraint_variables (t, args, info);
2232 if (parms == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2233 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2234
2235 /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
2236 of PARM_DECLs. */
2237 int saved_unevaluated_operand = cp_unevaluated_operand;
2238 cp_unevaluated_operand = 0;
2239 tree vars = tsubst (t, args, info.complain, info.in_decl);
2240 cp_unevaluated_operand = saved_unevaluated_operand;
2241 if (vars == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2242 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2243 return declare_constraint_vars (t, vars);
2244}
2245
2246/* Substitute ARGS into the requires-expression T. [8.4.7]p6. The
2247 substitution of template arguments into a requires-expression
2248 may result in the formation of invalid types or expressions
2249 in its requirements ... In such cases, the expression evaluates
2250 to false; it does not cause the program to be ill-formed.
2251
2252 When substituting through a REQUIRES_EXPR as part of template
2253 instantiation, we call this routine with info.quiet() true.
2254
2255 When evaluating a REQUIRES_EXPR that appears outside a template in
2256 cp_parser_requires_expression, we call this routine with
2257 info.noisy() true.
2258
2259 Finally, when diagnosing unsatisfaction from diagnose_atomic_constraint
2260 and when diagnosing a false REQUIRES_EXPR via diagnose_constraints,
2261 we call this routine with info.diagnose_unsatisfaction_p() true. */
2262
2263static tree
2264tsubst_requires_expr (tree t, tree args, sat_info info)
2265{
2266 local_specialization_stack stack (lss_copy);
2267
2268 /* A requires-expression is an unevaluated context. */
2269 cp_unevaluated u;
2270
2271 args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2271, __FUNCTION__, (REQUIRES_EXPR)))), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2271, __FUNCTION__)))))
, args,
2272 info.complain, info.in_decl);
2273 if (processing_template_declscope_chain->x_processing_template_decl)
2274 {
2275 /* We're partially instantiating a generic lambda. Substituting into
2276 this requires-expression now may cause its requirements to get
2277 checked out of order, so instead just remember the template
2278 arguments and wait until we can substitute them all at once. */
2279 t = copy_node (t);
2280 REQUIRES_EXPR_EXTRA_ARGS (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2280, __FUNCTION__, (REQUIRES_EXPR)))), (2), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2280, __FUNCTION__)))))
= build_extra_args (t, args, info.complain);
2281 return t;
2282 }
2283
2284 if (tree parms = REQUIRES_EXPR_PARMS (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2284, __FUNCTION__, (REQUIRES_EXPR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2284, __FUNCTION__)))))
)
2285 {
2286 parms = tsubst_constraint_variables (parms, args, info);
2287 if (parms == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2288 return boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE];
2289 }
2290
2291 tree result = boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
2292 for (tree reqs = REQUIRES_EXPR_REQS (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2292, __FUNCTION__, (REQUIRES_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2292, __FUNCTION__)))))
; reqs; reqs = TREE_CHAIN (reqs)((contains_struct_check ((reqs), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2292, __FUNCTION__))->common.chain)
)
2293 {
2294 tree req = TREE_VALUE (reqs)((tree_check ((reqs), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2294, __FUNCTION__, (TREE_LIST)))->list.value)
;
2295 if (tsubst_requirement (req, args, info) == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2296 {
2297 result = boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE];
2298 if (info.diagnose_unsatisfaction_p ())
2299 /* Keep going so that we diagnose all failed requirements. */;
2300 else
2301 break;
2302 }
2303 }
2304 return result;
2305}
2306
2307/* Public wrapper for the above. */
2308
2309tree
2310tsubst_requires_expr (tree t, tree args,
2311 tsubst_flags_t complain, tree in_decl)
2312{
2313 sat_info info (complain, in_decl);
2314 return tsubst_requires_expr (t, args, info);
2315}
2316
2317/* Substitute ARGS into the constraint information CI, producing a new
2318 constraint record. */
2319
2320tree
2321tsubst_constraint_info (tree t, tree args,
2322 tsubst_flags_t complain, tree in_decl)
2323{
2324 if (!t || t == error_mark_nodeglobal_trees[TI_ERROR_MARK] || !check_constraint_info (t))
2325 return NULL_TREE(tree) __null;
2326
2327 tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t)check_constraint_info (check_nonnull (t))->template_reqs, args, complain, in_decl);
2328 tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t)check_constraint_info (check_nonnull (t))->declarator_reqs, args, complain, in_decl);
2329 return build_constraints (tr, dr);
2330}
2331
2332/* Substitute through a parameter mapping, in order to get the actual
2333 arguments used to instantiate an atomic constraint. This may fail
2334 if the substitution into arguments produces something ill-formed. */
2335
2336static tree
2337tsubst_parameter_mapping (tree map, tree args, subst_info info)
2338{
2339 if (!map)
2340 return NULL_TREE(tree) __null;
2341
2342 tsubst_flags_t complain = info.complain;
2343 tree in_decl = info.in_decl;
2344
2345 tree result = NULL_TREE(tree) __null;
2346 for (tree p = map; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2346, __FUNCTION__))->common.chain)
)
2347 {
2348 if (p == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2349 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2350 tree parm = TREE_VALUE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2350, __FUNCTION__, (TREE_LIST)))->list.value)
;
2351 tree arg = TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2351, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
2352 tree new_arg;
2353 if (ARGUMENT_PACK_P (arg)(((enum tree_code) (arg)->base.code) == TYPE_ARGUMENT_PACK
|| ((enum tree_code) (arg)->base.code) == NONTYPE_ARGUMENT_PACK
)
)
2354 new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
2355 else
2356 {
2357 new_arg = tsubst_template_arg (arg, args, complain, in_decl);
2358 if (TYPE_P (new_arg)(tree_code_type[(int) (((enum tree_code) (new_arg)->base.code
))] == tcc_type)
)
2359 new_arg = canonicalize_type_argument (new_arg, complain);
2360 }
2361 if (TREE_CODE (new_arg)((enum tree_code) (new_arg)->base.code) == TYPE_ARGUMENT_PACK)
2362 {
2363 tree pack_args = ARGUMENT_PACK_ARGS (new_arg)(((enum tree_code) (new_arg)->base.code) == TYPE_ARGUMENT_PACK
? ((contains_struct_check ((new_arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2363, __FUNCTION__))->typed.type) : (*((const_cast<tree
*> (tree_operand_check ((new_arg), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2363, __FUNCTION__))))))
;
2364 for (int i = 0; i < TREE_VEC_LENGTH (pack_args)((tree_check ((pack_args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2364, __FUNCTION__, (TREE_VEC)))->base.u.length)
; i++)
2365 {
2366 tree& pack_arg = TREE_VEC_ELT (pack_args, i)(*((const_cast<tree *> (tree_vec_elt_check ((pack_args)
, (i), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2366, __FUNCTION__)))))
;
2367 if (TYPE_P (pack_arg)(tree_code_type[(int) (((enum tree_code) (pack_arg)->base.
code))] == tcc_type)
)
2368 pack_arg = canonicalize_type_argument (pack_arg, complain);
2369 }
2370 }
2371 if (new_arg == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2372 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2373
2374 result = tree_cons (new_arg, parm, result);
2375 }
2376 return nreverse (result);
2377}
2378
2379tree
2380tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
2381{
2382 return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
2383}
2384
2385/*---------------------------------------------------------------------------
2386 Constraint satisfaction
2387---------------------------------------------------------------------------*/
2388
2389/* True if we are currently satisfying a constraint. */
2390
2391static bool satisfying_constraint;
2392
2393/* A vector of incomplete types (and of declarations with undeduced return type),
2394 appended to by note_failed_type_completion_for_satisfaction. The
2395 satisfaction caches use this in order to keep track of "potentially unstable"
2396 satisfaction results.
2397
2398 Since references to entries in this vector are stored only in the
2399 GC-deletable sat_cache, it's safe to make this deletable as well. */
2400
2401static GTY((deletable)) vec<tree, va_gc> *failed_type_completions;
2402
2403/* Called whenever a type completion (or return type deduction) failure occurs
2404 that definitely affects the meaning of the program, by e.g. inducing
2405 substitution failure. */
2406
2407void
2408note_failed_type_completion_for_satisfaction (tree t)
2409{
2410 if (satisfying_constraint)
1
Assuming 'satisfying_constraint' is true
2
Taking true branch
2411 {
2412 gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))((void)(!(((tree_code_type[(int) (((enum tree_code) (t)->base
.code))] == tcc_type) && !(((tree_class_check ((t), (
tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2412, __FUNCTION__))->type_common.size) != (tree) __null
)) || ((tree_code_type[(int) (((enum tree_code) (t)->base.
code))] == tcc_declaration) && undeduced_auto_decl (t
))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2413, __FUNCTION__), 0 : 0))
3
Assuming the condition is false
4
Assuming the condition is true
5
Value assigned to 'failed_type_completions'
6
Assuming the condition is false
7
'?' condition is false
2413 || (DECL_P (t) && undeduced_auto_decl (t)))((void)(!(((tree_code_type[(int) (((enum tree_code) (t)->base
.code))] == tcc_type) && !(((tree_class_check ((t), (
tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2412, __FUNCTION__))->type_common.size) != (tree) __null
)) || ((tree_code_type[(int) (((enum tree_code) (t)->base.
code))] == tcc_declaration) && undeduced_auto_decl (t
))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2413, __FUNCTION__), 0 : 0))
;
2414 vec_safe_push (failed_type_completions, t);
8
Passing value via 1st parameter 'v'
9
Calling 'vec_safe_push<tree_node *, va_gc>'
2415 }
2416}
2417
2418/* Returns true if the range [BEGIN, END) of elements within the
2419 failed_type_completions vector contains a complete type (or a
2420 declaration with a non-placeholder return type). */
2421
2422static bool
2423some_type_complete_p (int begin, int end)
2424{
2425 for (int i = begin; i < end; i++)
2426 {
2427 tree t = (*failed_type_completions)[i];
2428 if (TYPE_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))]
== tcc_type)
&& COMPLETE_TYPE_P (t)(((tree_class_check ((t), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2428, __FUNCTION__))->type_common.size) != (tree) __null
)
)
2429 return true;
2430 if (DECL_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))]
== tcc_declaration)
&& !undeduced_auto_decl (t))
2431 return true;
2432 }
2433 return false;
2434}
2435
2436/* Hash functions and data types for satisfaction cache entries. */
2437
2438struct GTY((for_user)) sat_entry
2439{
2440 /* The relevant ATOMIC_CONSTR. */
2441 tree atom;
2442
2443 /* The relevant template arguments. */
2444 tree args;
2445
2446 /* The result of satisfaction of ATOM+ARGS.
2447 This is either boolean_true_node, boolean_false_node or error_mark_node,
2448 where error_mark_node indicates ill-formed satisfaction.
2449 It's set to NULL_TREE while computing satisfaction of ATOM+ARGS for
2450 the first time. */
2451 tree result;
2452
2453 /* The value of input_location when satisfaction of ATOM+ARGS was first
2454 performed. */
2455 location_t location;
2456
2457 /* The range of elements appended to the failed_type_completions vector
2458 during computation of this satisfaction result, encoded as a begin/end
2459 pair of offsets. */
2460 int ftc_begin, ftc_end;
2461
2462 /* True if we want to diagnose the above instability when it's detected.
2463 We don't always want to do so, in order to avoid emitting duplicate
2464 diagnostics in some cases. */
2465 bool diagnose_instability;
2466
2467 /* True if we're in the middle of computing this satisfaction result.
2468 Used during both quiet and noisy satisfaction to detect self-recursive
2469 satisfaction. */
2470 bool evaluating;
2471};
2472
2473struct sat_hasher : ggc_ptr_hash<sat_entry>
2474{
2475 static hashval_t hash (sat_entry *e)
2476 {
2477 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom)((tree_not_check2 (((tree_check ((e->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2477, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2477, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
2478 {
2479 /* Atoms with instantiated mappings are built during satisfaction.
2480 They live only inside the sat_cache, and we build one to query
2481 the cache with each time we instantiate a mapping. */
2482 gcc_assert (!e->args)((void)(!(!e->args) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2482, __FUNCTION__), 0 : 0))
;
2483 return hash_atomic_constraint (e->atom);
2484 }
2485
2486 /* Atoms with uninstantiated mappings are built during normalization.
2487 Since normalize_atom caches the atoms it returns, we can assume
2488 pointer-based identity for fast hashing and comparison. Even if this
2489 assumption is violated, that's okay, we'll just get a cache miss. */
2490 hashval_t value = htab_hash_pointer (e->atom);
2491
2492 if (tree map = ATOMIC_CONSTR_MAP (e->atom)(*((const_cast<tree*> (tree_operand_check (((tree_check
((e->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2492, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2492, __FUNCTION__)))))
)
2493 /* Only the parameters that are used in the targets of the mapping
2494 affect the satisfaction value of the atom. So we consider only
2495 the arguments for these parameters, and ignore the rest. */
2496 for (tree target_parms = TREE_TYPE (map)((contains_struct_check ((map), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2496, __FUNCTION__))->typed.type)
;
2497 target_parms;
2498 target_parms = TREE_CHAIN (target_parms)((contains_struct_check ((target_parms), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2498, __FUNCTION__))->common.chain)
)
2499 {
2500 int level, index;
2501 tree parm = TREE_VALUE (target_parms)((tree_check ((target_parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2501, __FUNCTION__, (TREE_LIST)))->list.value)
;
2502 template_parm_level_and_index (parm, &level, &index);
2503 tree arg = TMPL_ARG (e->args, level, index)((*((const_cast<tree *> (tree_vec_elt_check ((((e->args
&& ((tree_check ((e->args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2503, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((e->args
), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2503, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((e->args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2503, __FUNCTION__))))))->base.code) == TREE_VEC) ? (*((
const_cast<tree *> (tree_vec_elt_check ((e->args), (
(level) - 1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2503, __FUNCTION__))))) : (e->args))), (index), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2503, __FUNCTION__))))))
;
2504 value = iterative_hash_template_arg (arg, value);
2505 }
2506 return value;
2507 }
2508
2509 static bool equal (sat_entry *e1, sat_entry *e2)
2510 {
2511 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)((tree_not_check2 (((tree_check ((e1->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2511, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2511, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
2512 != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom)((tree_not_check2 (((tree_check ((e2->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2512, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2512, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
2513 return false;
2514
2515 /* See sat_hasher::hash. */
2516 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)((tree_not_check2 (((tree_check ((e1->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2516, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2516, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
2517 {
2518 gcc_assert (!e1->args && !e2->args)((void)(!(!e1->args && !e2->args) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2518, __FUNCTION__), 0 : 0))
;
2519 return atomic_constraints_identical_p (e1->atom, e2->atom);
2520 }
2521
2522 if (e1->atom != e2->atom)
2523 return false;
2524
2525 if (tree map = ATOMIC_CONSTR_MAP (e1->atom)(*((const_cast<tree*> (tree_operand_check (((tree_check
((e1->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2525, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2525, __FUNCTION__)))))
)
2526 for (tree target_parms = TREE_TYPE (map)((contains_struct_check ((map), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2526, __FUNCTION__))->typed.type)
;
2527 target_parms;
2528 target_parms = TREE_CHAIN (target_parms)((contains_struct_check ((target_parms), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2528, __FUNCTION__))->common.chain)
)
2529 {
2530 int level, index;
2531 tree parm = TREE_VALUE (target_parms)((tree_check ((target_parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2531, __FUNCTION__, (TREE_LIST)))->list.value)
;
2532 template_parm_level_and_index (parm, &level, &index);
2533 tree arg1 = TMPL_ARG (e1->args, level, index)((*((const_cast<tree *> (tree_vec_elt_check ((((e1->
args && ((tree_check ((e1->args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2533, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((e1->args
), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2533, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((e1->args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2533, __FUNCTION__))))))->base.code) == TREE_VEC) ? (*((
const_cast<tree *> (tree_vec_elt_check ((e1->args), (
(level) - 1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2533, __FUNCTION__))))) : (e1->args))), (index), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2533, __FUNCTION__))))))
;
2534 tree arg2 = TMPL_ARG (e2->args, level, index)((*((const_cast<tree *> (tree_vec_elt_check ((((e2->
args && ((tree_check ((e2->args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2534, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((e2->args
), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2534, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((e2->args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2534, __FUNCTION__))))))->base.code) == TREE_VEC) ? (*((
const_cast<tree *> (tree_vec_elt_check ((e2->args), (
(level) - 1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2534, __FUNCTION__))))) : (e2->args))), (index), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2534, __FUNCTION__))))))
;
2535 if (!template_args_equal (arg1, arg2))
2536 return false;
2537 }
2538 return true;
2539 }
2540};
2541
2542/* Cache the result of satisfy_atom. */
2543static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
2544
2545/* Cache the result of satisfy_declaration_constraints. */
2546static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
2547
2548/* A tool used by satisfy_atom to help manage satisfaction caching and to
2549 diagnose "unstable" satisfaction values. We insert into the cache only
2550 when performing satisfaction quietly. */
2551
2552struct satisfaction_cache
2553{
2554 satisfaction_cache (tree, tree, sat_info);
2555 tree get ();
2556 tree save (tree);
2557
2558 sat_entry *entry;
2559 sat_info info;
2560 int ftc_begin;
2561};
2562
2563/* Constructor for the satisfaction_cache class. We're performing satisfaction
2564 of ATOM+ARGS according to INFO. */
2565
2566satisfaction_cache
2567::satisfaction_cache (tree atom, tree args, sat_info info)
2568 : entry(nullptr), info(info), ftc_begin(-1)
2569{
2570 if (!sat_cache)
2571 sat_cache = hash_table<sat_hasher>::create_ggc (31);
2572
2573 /* When noisy, we query the satisfaction cache in order to diagnose
2574 "unstable" satisfaction values. */
2575 if (info.noisy ())
2576 {
2577 /* When noisy, constraints have been re-normalized, and that breaks the
2578 pointer-based identity assumption of sat_cache (for atoms with
2579 uninstantiated mappings). So undo this re-normalization by looking in
2580 the atom_cache for the corresponding atom that was used during quiet
2581 satisfaction. */
2582 if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom)((tree_not_check2 (((tree_check ((atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2582, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2582, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
2583 {
2584 if (tree found = atom_cache->find (atom))
2585 atom = found;
2586 else
2587 /* The lookup should always succeed, but if it fails then let's
2588 just leave 'entry' empty, effectively disabling the cache. */
2589 return;
2590 }
2591 }
2592
2593 /* Look up or create the corresponding satisfaction entry. */
2594 sat_entry elt;
2595 elt.atom = atom;
2596 elt.args = args;
2597 sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
2598 if (*slot)
2599 entry = *slot;
2600 else if (info.quiet ())
2601 {
2602 entry = ggc_alloc<sat_entry> ();
2603 entry->atom = atom;
2604 entry->args = args;
2605 entry->result = NULL_TREE(tree) __null;
2606 entry->location = input_location;
2607 entry->ftc_begin = entry->ftc_end = -1;
2608 entry->diagnose_instability = false;
2609 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom)((tree_not_check2 (((tree_check ((atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2609, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2609, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
)
2610 /* We always want to diagnose instability of an atom with an
2611 instantiated parameter mapping. For atoms with an uninstantiated
2612 mapping, we set this flag (in satisfy_atom) only if substitution
2613 into its mapping previously failed. */
2614 entry->diagnose_instability = true;
2615 entry->evaluating = false;
2616 *slot = entry;
2617 }
2618 else
2619 /* We shouldn't get here, but if we do, let's just leave 'entry'
2620 empty, effectively disabling the cache. */
2621 return;
2622}
2623
2624/* Returns the cached satisfaction result if we have one and we're not
2625 recomputing the satisfaction result from scratch. Otherwise returns
2626 NULL_TREE. */
2627
2628tree
2629satisfaction_cache::get ()
2630{
2631 if (!entry)
2632 return NULL_TREE(tree) __null;
2633
2634 if (entry->evaluating)
2635 {
2636 /* If we get here, it means satisfaction is self-recursive. */
2637 gcc_checking_assert (!entry->result)((void)(!(!entry->result) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2637, __FUNCTION__), 0 : 0))
;
2638 if (info.noisy ())
2639 error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom))((((((tree_check ((((contains_struct_check (((tree_check3 (((
tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (TREE_LIST)))->list.purpose))) &&
((tree_code_type[(int) (((enum tree_code) ((((tree_check (((
(contains_struct_check (((tree_check3 (((tree_check ((entry->
atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (TREE_LIST)))->list.purpose)))->base
.code))]) >= tcc_reference && (tree_code_type[(int
) (((enum tree_code) ((((tree_check ((((contains_struct_check
(((tree_check3 (((tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (TREE_LIST)))->list.purpose)))->base
.code))]) <= tcc_expression)) ? (((tree_check ((((contains_struct_check
(((tree_check3 (((tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2639, __FUNCTION__, (TREE_LIST)))->list.purpose))->exp
.locus : ((location_t) 0))
,
2640 "satisfaction of atomic constraint %qE depends on itself",
2641 entry->atom);
2642 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2643 }
2644
2645 /* This satisfaction result is "potentially unstable" if a type for which
2646 type completion failed during its earlier computation is now complete. */
2647 bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
2648 entry->ftc_end);
2649
2650 if (info.noisy () || maybe_unstable || !entry->result)
2651 {
2652 /* We're computing the satisfaction result from scratch. */
2653 entry->evaluating = true;
2654 ftc_begin = vec_safe_length (failed_type_completions);
2655 return NULL_TREE(tree) __null;
2656 }
2657 else
2658 return entry->result;
2659}
2660
2661/* RESULT is the computed satisfaction result. If RESULT differs from the
2662 previously cached result, this routine issues an appropriate error.
2663 Otherwise, when evaluating quietly, updates the cache appropriately. */
2664
2665tree
2666satisfaction_cache::save (tree result)
2667{
2668 if (!entry)
2669 return result;
2670
2671 gcc_checking_assert (entry->evaluating)((void)(!(entry->evaluating) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2671, __FUNCTION__), 0 : 0))
;
2672 entry->evaluating = false;
2673
2674 if (entry->result && result != entry->result)
2675 {
2676 if (info.quiet ())
2677 /* Return error_mark_node to force satisfaction to get replayed
2678 noisily. */
2679 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
2680 else
2681 {
2682 if (entry->diagnose_instability)
2683 {
2684 auto_diagnostic_group d;
2685 error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom))((((((tree_check ((((contains_struct_check (((tree_check3 (((
tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (TREE_LIST)))->list.purpose))) &&
((tree_code_type[(int) (((enum tree_code) ((((tree_check (((
(contains_struct_check (((tree_check3 (((tree_check ((entry->
atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (TREE_LIST)))->list.purpose)))->base
.code))]) >= tcc_reference && (tree_code_type[(int
) (((enum tree_code) ((((tree_check ((((contains_struct_check
(((tree_check3 (((tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (TREE_LIST)))->list.purpose)))->base
.code))]) <= tcc_expression)) ? (((tree_check ((((contains_struct_check
(((tree_check3 (((tree_check ((entry->atom), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2685, __FUNCTION__, (TREE_LIST)))->list.purpose))->exp
.locus : ((location_t) 0))
,
2686 "satisfaction value of atomic constraint %qE changed "
2687 "from %qE to %qE", entry->atom, entry->result, result);
2688 inform (entry->location,
2689 "satisfaction value first evaluated to %qE from here",
2690 entry->result);
2691 }
2692 /* For sake of error recovery, allow this latest satisfaction result
2693 to prevail. */
2694 entry->result = result;
2695 return result;
2696 }
2697 }
2698
2699 if (info.quiet ())
2700 {
2701 entry->result = result;
2702 /* Store into this entry the list of relevant failed type completions
2703 that occurred during (re)computation of the satisfaction result. */
2704 gcc_checking_assert (ftc_begin != -1)((void)(!(ftc_begin != -1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2704, __FUNCTION__), 0 : 0))
;
2705 entry->ftc_begin = ftc_begin;
2706 entry->ftc_end = vec_safe_length (failed_type_completions);
2707 }
2708
2709 return result;
2710}
2711
2712/* Substitute ARGS into constraint-expression T during instantiation of
2713 a member of a class template. */
2714
2715tree
2716tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
2717{
2718 /* We also don't want to evaluate concept-checks when substituting the
2719 constraint-expressions of a declaration. */
2720 processing_constraint_expression_sentinel s;
2721 cp_unevaluated u;
2722 tree expr = tsubst_expr (t, args, complain, in_decl, false);
2723 return expr;
2724}
2725
2726static tree satisfy_constraint_r (tree, tree, sat_info info);
2727
2728/* Compute the satisfaction of a conjunction. */
2729
2730static tree
2731satisfy_conjunction (tree t, tree args, sat_info info)
2732{
2733 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2733, __FUNCTION__)))))
, args, info);
2734 if (lhs == error_mark_nodeglobal_trees[TI_ERROR_MARK] || lhs == boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE])
2735 return lhs;
2736 return satisfy_constraint_r (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2736, __FUNCTION__)))))
, args, info);
2737}
2738
2739/* The current depth at which we're replaying an error during recursive
2740 diagnosis of a constraint satisfaction failure. */
2741
2742static int current_constraint_diagnosis_depth;
2743
2744/* Whether CURRENT_CONSTRAINT_DIAGNOSIS_DEPTH has ever exceeded
2745 CONCEPTS_DIAGNOSTICS_MAX_DEPTH during recursive diagnosis of a constraint
2746 satisfaction error. */
2747
2748static bool concepts_diagnostics_max_depth_exceeded_p;
2749
2750/* Recursive subroutine of collect_operands_of_disjunction. T is a normalized
2751 subexpression of a constraint (composed of CONJ_CONSTRs and DISJ_CONSTRs)
2752 and E is the corresponding unnormalized subexpression (composed of
2753 TRUTH_ANDIF_EXPRs and TRUTH_ORIF_EXPRs). */
2754
2755static void
2756collect_operands_of_disjunction_r (tree t, tree e,
2757 auto_vec<tree_pair> *operands)
2758{
2759 if (TREE_CODE (e)((enum tree_code) (e)->base.code) == TRUTH_ORIF_EXPR)
2760 {
2761 collect_operands_of_disjunction_r (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2761, __FUNCTION__)))))
,
2762 TREE_OPERAND (e, 0)(*((const_cast<tree*> (tree_operand_check ((e), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2762, __FUNCTION__)))))
, operands);
2763 collect_operands_of_disjunction_r (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2763, __FUNCTION__)))))
,
2764 TREE_OPERAND (e, 1)(*((const_cast<tree*> (tree_operand_check ((e), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2764, __FUNCTION__)))))
, operands);
2765 }
2766 else
2767 {
2768 tree_pair p = std::make_pair (t, e);
2769 operands->safe_push (p);
2770 }
2771}
2772
2773/* Recursively collect the normalized and unnormalized operands of the
2774 disjunction T and append them to OPERANDS in order. */
2775
2776static void
2777collect_operands_of_disjunction (tree t, auto_vec<tree_pair> *operands)
2778{
2779 collect_operands_of_disjunction_r (t, CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2779, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2779, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2779, __FUNCTION__, (TREE_LIST)))->list.purpose)
, operands);
2780}
2781
2782/* Compute the satisfaction of a disjunction. */
2783
2784static tree
2785satisfy_disjunction (tree t, tree args, sat_info info)
2786{
2787 /* Evaluate each operand with unsatisfaction diagnostics disabled. */
2788 sat_info sub = info;
2789 sub.diagnose_unsatisfaction = false;
2790
2791 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2791, __FUNCTION__)))))
, args, sub);
2792 if (lhs == boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE] || lhs == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2793 return lhs;
2794
2795 tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1)(*((const_cast<tree*> (tree_operand_check ((t), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2795, __FUNCTION__)))))
, args, sub);
2796 if (rhs == boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE] || rhs == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2797 return rhs;
2798
2799 /* Both branches evaluated to false. Explain the satisfaction failure in
2800 each branch. */
2801 if (info.diagnose_unsatisfaction_p ())
2802 {
2803 diagnosing_failed_constraint failure (t, args, info.noisy ());
2804 cp_expr disj_expr = CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2804, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2804, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2804, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
2805 inform (disj_expr.get_location (),
2806 "no operand of the disjunction is satisfied");
2807 if (diagnosing_failed_constraint::replay_errors_p ())
2808 {
2809 /* Replay the error in each branch of the disjunction. */
2810 auto_vec<tree_pair> operands;
2811 collect_operands_of_disjunction (t, &operands);
2812 for (unsigned i = 0; i < operands.length (); i++)
2813 {
2814 tree norm_op = operands[i].first;
2815 tree op = operands[i].second;
2816 location_t loc = make_location (cp_expr_location (op),
2817 disj_expr.get_start (),
2818 disj_expr.get_finish ());
2819 inform (loc, "the operand %qE is unsatisfied because", op);
2820 satisfy_constraint_r (norm_op, args, info);
2821 }
2822 }
2823 }
2824
2825 return boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE];
2826}
2827
2828/* Ensures that T is a truth value and not (accidentally, as sometimes
2829 happens) an integer value. */
2830
2831tree
2832satisfaction_value (tree t)
2833{
2834 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK] || t == boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE] || t == boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE])
2835 return t;
2836
2837 gcc_assert (TREE_CODE (t) == INTEGER_CST((void)(!(((enum tree_code) (t)->base.code) == INTEGER_CST
&& comptypes ((((contains_struct_check ((t), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2838, __FUNCTION__))->typed.type)), (global_trees[TI_BOOLEAN_TYPE
]), 0)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2838, __FUNCTION__), 0 : 0))
2838 && same_type_p (TREE_TYPE (t), boolean_type_node))((void)(!(((enum tree_code) (t)->base.code) == INTEGER_CST
&& comptypes ((((contains_struct_check ((t), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2838, __FUNCTION__))->typed.type)), (global_trees[TI_BOOLEAN_TYPE
]), 0)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2838, __FUNCTION__), 0 : 0))
;
2839 if (integer_zerop (t))
2840 return boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE];
2841 else
2842 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
2843}
2844
2845/* Build a new template argument list with template arguments corresponding
2846 to the parameters used in an atomic constraint. */
2847
2848tree
2849get_mapped_args (tree map)
2850{
2851 /* No map, no arguments. */
2852 if (!map)
2853 return NULL_TREE(tree) __null;
2854
2855 /* Find the mapped parameter with the highest level. */
2856 int count = 0;
2857 for (tree p = map; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2857, __FUNCTION__))->common.chain)
)
2858 {
2859 int level;
2860 int index;
2861 template_parm_level_and_index (TREE_VALUE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2861, __FUNCTION__, (TREE_LIST)))->list.value)
, &level, &index);
2862 if (level > count)
2863 count = level;
2864 }
2865
2866 /* Place each argument at its corresponding position in the argument
2867 list. Note that the list will be sparse (not all arguments supplied),
2868 but instantiation is guaranteed to only use the parameters in the
2869 mapping, so null arguments would never be used. */
2870 auto_vec< vec<tree> > lists (count);
2871 lists.quick_grow_cleared (count);
2872 for (tree p = map; p; p = TREE_CHAIN (p)((contains_struct_check ((p), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2872, __FUNCTION__))->common.chain)
)
2873 {
2874 int level;
2875 int index;
2876 template_parm_level_and_index (TREE_VALUE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2876, __FUNCTION__, (TREE_LIST)))->list.value)
, &level, &index);
2877
2878 /* Insert the argument into its corresponding position. */
2879 vec<tree> &list = lists[level - 1];
2880 if (index >= (int)list.length ())
2881 list.safe_grow_cleared (index + 1, true);
2882 list[index] = TREE_PURPOSE (p)((tree_check ((p), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2882, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
2883 }
2884
2885 /* Build the new argument list. */
2886 tree args = make_tree_vec (lists.length ());
2887 for (unsigned i = 0; i != lists.length (); ++i)
2888 {
2889 vec<tree> &list = lists[i];
2890 tree level = make_tree_vec (list.length ());
2891 for (unsigned j = 0; j < list.length(); ++j)
2892 TREE_VEC_ELT (level, j)(*((const_cast<tree *> (tree_vec_elt_check ((level), (j
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2892, __FUNCTION__)))))
= list[j];
2893 SET_TMPL_ARGS_LEVEL (args, i + 1, level)((*((const_cast<tree *> (tree_vec_elt_check ((args), ((
i + 1) - 1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2893, __FUNCTION__))))) = (level))
;
2894 list.release ();
2895 }
2896 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0)((contains_struct_check (((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2896, __FUNCTION__, (TREE_VEC)))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2896, __FUNCTION__))->common.chain) = build_int_cst ((tree
) __null, 0)
;
2897
2898 return args;
2899}
2900
2901static void diagnose_atomic_constraint (tree, tree, tree, sat_info);
2902
2903/* Compute the satisfaction of an atomic constraint. */
2904
2905static tree
2906satisfy_atom (tree t, tree args, sat_info info)
2907{
2908 /* In case there is a diagnostic, we want to establish the context
2909 prior to printing errors. If no errors occur, this context is
2910 removed before returning. */
2911 diagnosing_failed_constraint failure (t, args, info.noisy ());
2912
2913 satisfaction_cache cache (t, args, info);
2914 if (tree r = cache.get ())
2915 return r;
2916
2917 /* Perform substitution quietly. */
2918 subst_info quiet (tf_none, NULL_TREE(tree) __null);
2919
2920 /* Instantiate the parameter mapping. */
2921 tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2921, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2921, __FUNCTION__)))))
, args, quiet);
2922 if (map == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2923 {
2924 /* If instantiation of the parameter mapping fails, the constraint is
2925 not satisfied. Replay the substitution. */
2926 if (info.diagnose_unsatisfaction_p ())
2927 tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2927, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2927, __FUNCTION__)))))
, args, info);
2928 if (info.quiet ())
2929 /* Since instantiation of the parameter mapping failed, we
2930 want to diagnose potential instability of this satisfaction
2931 result. */
2932 cache.entry->diagnose_instability = true;
2933 return cache.save (boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE]);
2934 }
2935
2936 /* Now build a new atom using the instantiated mapping. We use
2937 this atom as a second key to the satisfaction cache, and we
2938 also pass it to diagnose_atomic_constraint so that diagnostics
2939 which refer to the atom display the instantiated mapping. */
2940 t = copy_node (t);
2941 ATOMIC_CONSTR_MAP (t)(*((const_cast<tree*> (tree_operand_check (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2941, __FUNCTION__, (ATOMIC_CONSTR)))), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2941, __FUNCTION__)))))
= map;
2942 gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t))((void)(!(!((tree_not_check2 (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2942, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2942, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2942, __FUNCTION__), 0 : 0))
;
2943 ATOMIC_CONSTR_MAP_INSTANTIATED_P (t)((tree_not_check2 (((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2943, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2943, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
= true;
2944 satisfaction_cache inst_cache (t, /*args=*/NULL_TREE(tree) __null, info);
2945 if (tree r = inst_cache.get ())
2946 {
2947 cache.entry->location = inst_cache.entry->location;
2948 return cache.save (r);
2949 }
2950
2951 /* Rebuild the argument vector from the parameter mapping. */
2952 args = get_mapped_args (map);
2953
2954 /* Apply the parameter mapping (i.e., just substitute). */
2955 tree expr = ATOMIC_CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2955, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2955, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2955, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2955, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
2956 tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl, false);
2957 if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2958 {
2959 /* If substitution results in an invalid type or expression, the constraint
2960 is not satisfied. Replay the substitution. */
2961 if (info.diagnose_unsatisfaction_p ())
2962 tsubst_expr (expr, args, info.complain, info.in_decl, false);
2963 return cache.save (inst_cache.save (boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE]));
2964 }
2965
2966 /* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
2967 and EXPR shall be a constant expression of type bool. */
2968 result = force_rvalue (result, info.complain);
2969 if (result == error_mark_nodeglobal_trees[TI_ERROR_MARK])
2970 return cache.save (inst_cache.save (error_mark_nodeglobal_trees[TI_ERROR_MARK]));
2971 if (!same_type_p (TREE_TYPE (result), boolean_type_node)comptypes ((((contains_struct_check ((result), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2971, __FUNCTION__))->typed.type)), (global_trees[TI_BOOLEAN_TYPE
]), 0)
)
2972 {
2973 if (info.noisy ())
2974 diagnose_atomic_constraint (t, map, result, info);
2975 return cache.save (inst_cache.save (error_mark_nodeglobal_trees[TI_ERROR_MARK]));
2976 }
2977
2978 /* Compute the value of the constraint. */
2979 if (info.noisy ())
2980 {
2981 iloc_sentinel ils (EXPR_LOCATION (result)((((result)) && ((tree_code_type[(int) (((enum tree_code
) ((result))->base.code))]) >= tcc_reference &&
(tree_code_type[(int) (((enum tree_code) ((result))->base
.code))]) <= tcc_expression)) ? (result)->exp.locus : (
(location_t) 0))
);
2982 result = cxx_constant_value (result);
2983 }
2984 else
2985 {
2986 result = maybe_constant_value (result, NULL_TREE(tree) __null,
2987 /*manifestly_const_eval=*/true);
2988 if (!TREE_CONSTANT (result)((non_type_check ((result), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 2988, __FUNCTION__))->base.constant_flag)
)
2989 result = error_mark_nodeglobal_trees[TI_ERROR_MARK];
2990 }
2991 result = satisfaction_value (result);
2992 if (result == boolean_false_nodeglobal_trees[TI_BOOLEAN_FALSE] && info.diagnose_unsatisfaction_p ())
2993 diagnose_atomic_constraint (t, map, result, info);
2994
2995 return cache.save (inst_cache.save (result));
2996}
2997
2998/* Determine if the normalized constraint T is satisfied.
2999 Returns boolean_true_node if the expression/constraint is
3000 satisfied, boolean_false_node if not, and error_mark_node
3001 if the there was an error evaluating the constraint.
3002
3003 The parameter mapping of atomic constraints is simply the
3004 set of template arguments that will be substituted into
3005 the expression, regardless of template parameters appearing
3006 withing. Whether a template argument is used in the atomic
3007 constraint only matters for subsumption. */
3008
3009static tree
3010satisfy_constraint_r (tree t, tree args, sat_info info)
3011{
3012 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
3013 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
3014
3015 switch (TREE_CODE (t)((enum tree_code) (t)->base.code))
3016 {
3017 case CONJ_CONSTR:
3018 return satisfy_conjunction (t, args, info);
3019 case DISJ_CONSTR:
3020 return satisfy_disjunction (t, args, info);
3021 case ATOMIC_CONSTR:
3022 return satisfy_atom (t, args, info);
3023 default:
3024 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3024, __FUNCTION__))
;
3025 }
3026}
3027
3028/* Check that the normalized constraint T is satisfied for ARGS. */
3029
3030static tree
3031satisfy_normalized_constraints (tree t, tree args, sat_info info)
3032{
3033 auto_timevar time (TV_CONSTRAINT_SAT);
3034
3035 auto ovr = make_temp_override (satisfying_constraint, true);
3036
3037 /* Turn off template processing. Constraint satisfaction only applies
3038 to non-dependent terms, so we want to ensure full checking here. */
3039 processing_template_decl_sentinel proc (true);
3040
3041 /* We need to check access during satisfaction. */
3042 deferring_access_check_sentinel acs (dk_no_deferred);
3043
3044 /* Constraints are unevaluated operands. */
3045 cp_unevaluated u;
3046
3047 return satisfy_constraint_r (t, args, info);
3048}
3049
3050/* Return the normal form of the constraints on the placeholder 'auto'
3051 type T. */
3052
3053static tree
3054normalize_placeholder_type_constraints (tree t, bool diag)
3055{
3056 gcc_assert (is_auto (t))((void)(!(is_auto (t)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3056, __FUNCTION__), 0 : 0))
;
3057 tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t)((contains_struct_check ((((tree_class_check ((t), (tcc_type)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3057, __FUNCTION__))->type_common.name)), (TS_DECL_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3057, __FUNCTION__))->decl_common.size_unit)
;
3058 if (!ci)
3059 return NULL_TREE(tree) __null;
3060
3061 tree constr = TREE_VALUE (ci)((tree_check ((ci), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3061, __FUNCTION__, (TREE_LIST)))->list.value)
;
3062 /* The TREE_PURPOSE contains the set of template parameters that were in
3063 scope for this placeholder type; use them as the initial template
3064 parameters for normalization. */
3065 tree initial_parms = TREE_PURPOSE (ci)((tree_check ((ci), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3065, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
3066
3067 if (!initial_parms && TEMPLATE_TYPE_LEVEL (t)((((template_parm_index*)(tree_check (((((tree_class_check ((
(tree_check3 (((t)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3067, __FUNCTION__, (TEMPLATE_TYPE_PARM), (TEMPLATE_TEMPLATE_PARM
), (BOUND_TEMPLATE_TEMPLATE_PARM)))), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3067, __FUNCTION__))->type_non_common.values))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3067, __FUNCTION__, (TEMPLATE_PARM_INDEX))))->level))
== 2)
3068 /* This is a return-type-requirement of a non-templated requires-expression,
3069 which are parsed under processing_template_decl == 1 and empty
3070 current_template_parms; hence the 'auto' has level 2 and initial_parms
3071 is empty. Fix up initial_parms to be consistent with the value of
3072 processing_template_decl whence the 'auto' was created. */
3073 initial_parms = build_tree_list (size_int (1)size_int_kind (1, stk_sizetype), make_tree_vec (0));
3074
3075 /* The 'auto' itself is used as the first argument in its own constraints,
3076 and its level is one greater than its template depth. So in order to
3077 capture all used template parameters, we need to add an extra level of
3078 template parameters to the context; a dummy level suffices. */
3079 initial_parms
3080 = tree_cons (size_int (initial_parmssize_int_kind (initial_parms ? ((long) ((unsigned long) (*tree_int_cst_elt_check
((((tree_check ((initial_parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3081, __FUNCTION__, (TREE_LIST)))->list.purpose)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3081, __FUNCTION__)))) + 1 : 1, stk_sizetype)
3081 ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1)size_int_kind (initial_parms ? ((long) ((unsigned long) (*tree_int_cst_elt_check
((((tree_check ((initial_parms), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3081, __FUNCTION__, (TREE_LIST)))->list.purpose)), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3081, __FUNCTION__)))) + 1 : 1, stk_sizetype)
,
3082 make_tree_vec (0), initial_parms);
3083
3084 norm_info info (diag ? tf_norm : tf_none);
3085 info.initial_parms = initial_parms;
3086 return normalize_constraint_expression (constr, info);
3087}
3088
3089/* Evaluate the constraints of T using ARGS, returning a satisfaction value.
3090 Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
3091 requires-expression. */
3092
3093static tree
3094satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
3095{
3096 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
3097 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
3098
3099 /* Handle REQUIRES_EXPR directly, bypassing satisfaction. */
3100 if (TREE_CODE (t)((enum tree_code) (t)->base.code) == REQUIRES_EXPR)
3101 {
3102 auto ovr = make_temp_override (current_constraint_diagnosis_depth);
3103 if (info.noisy ())
3104 ++current_constraint_diagnosis_depth;
3105 return tsubst_requires_expr (t, args, info);
3106 }
3107
3108 /* Get the normalized constraints. */
3109 tree norm;
3110 if (concept_check_p (t))
3111 {
3112 gcc_assert (!args)((void)(!(!args) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3112, __FUNCTION__), 0 : 0))
;
3113 tree id = unpack_concept_check (t);
3114 args = TREE_OPERAND (id, 1)(*((const_cast<tree*> (tree_operand_check ((id), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3114, __FUNCTION__)))))
;
3115 tree tmpl = get_concept_check_template (id);
3116 norm = normalize_concept_definition (tmpl, info.noisy ());
3117 }
3118 else if (TREE_CODE (t)((enum tree_code) (t)->base.code) == NESTED_REQ)
3119 {
3120 norm_info ninfo (info.noisy () ? tf_norm : tf_none);
3121 /* The TREE_TYPE contains the set of template parameters that were in
3122 scope for this nested requirement; use them as the initial template
3123 parameters for normalization. */
3124 ninfo.initial_parms = TREE_TYPE (t)((contains_struct_check ((t), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3124, __FUNCTION__))->typed.type)
;
3125 norm = normalize_constraint_expression (TREE_OPERAND (t, 0)(*((const_cast<tree*> (tree_operand_check ((t), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3125, __FUNCTION__)))))
, ninfo);
3126 }
3127 else if (is_auto (t))
3128 {
3129 norm = normalize_placeholder_type_constraints (t, info.noisy ());
3130 if (!norm)
3131 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3132 }
3133 else
3134 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3134, __FUNCTION__))
;
3135
3136 /* Perform satisfaction. */
3137 return satisfy_normalized_constraints (norm, args, info);
3138}
3139
3140/* Evaluate the associated constraints of the template specialization T
3141 according to INFO, returning a satisfaction value. */
3142
3143static tree
3144satisfy_declaration_constraints (tree t, sat_info info)
3145{
3146 gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL)((void)(!((tree_code_type[(int) (((enum tree_code) (t)->base
.code))] == tcc_declaration) && ((enum tree_code) (t)
->base.code) != TEMPLATE_DECL) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3146, __FUNCTION__), 0 : 0))
;
3147 const tree saved_t = t;
3148
3149 /* For inherited constructors, consider the original declaration;
3150 it has the correct template information attached. */
3151 t = strip_inheriting_ctors (t);
3152 tree inh_ctor_targs = NULL_TREE(tree) __null;
3153 if (t != saved_t)
3154 if (tree ti = DECL_TEMPLATE_INFO (saved_t)(((contains_struct_check ((template_info_decl_check ((saved_t
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3154, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3154, __FUNCTION__))->decl_common.lang_specific) ->u.
min.template_info)
)
3155 /* The inherited constructor points to an instantiation of a constructor
3156 template; remember its template arguments. */
3157 inh_ctor_targs = TI_ARGS (ti)((struct tree_template_info*)(tree_check ((ti), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3157, __FUNCTION__, (TEMPLATE_INFO))))->args
;
3158
3159 /* Update the declaration for diagnostics. */
3160 info.in_decl = t;
3161
3162 if (info.quiet ())
3163 if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
3164 return *result;
3165
3166 tree args = NULL_TREE(tree) __null;
3167 if (tree ti = DECL_TEMPLATE_INFO (t)(((contains_struct_check ((template_info_decl_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3167, __FUNCTION__)), (TS_DECL_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3167, __FUNCTION__))->decl_common.lang_specific) ->u.
min.template_info)
)
3168 {
3169 /* The initial parameter mapping is the complete set of
3170 template arguments substituted into the declaration. */
3171 args = TI_ARGS (ti)((struct tree_template_info*)(tree_check ((ti), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3171, __FUNCTION__, (TEMPLATE_INFO))))->args
;
3172 if (inh_ctor_targs)
3173 args = add_outermost_template_args (args, inh_ctor_targs);
3174 }
3175
3176 if (regenerated_lambda_fn_p (t))
3177 {
3178 /* The TI_ARGS of a regenerated lambda contains only the innermost
3179 set of template arguments. Augment this with the outer template
3180 arguments that were used to regenerate the lambda. */
3181 gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1)((void)(!(!args || ((args && ((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3181, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((args), (0
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3181, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3181, __FUNCTION__))))))->base.code) == TREE_VEC) ? ((tree_check
((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3181, __FUNCTION__, (TREE_VEC)))->base.u.length) : 1) ==
1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3181, __FUNCTION__), 0 : 0))
;
3182 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t))((((tree_class_check ((((contains_struct_check ((t), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3182, __FUNCTION__))->decl_minimal.context)), (tcc_type)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3182, __FUNCTION__))->type_with_lang_specific.lang_specific
))->lambda_expr)
;
3183 tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda))((struct tree_template_info*)(tree_check (((((struct tree_lambda_expr
*)(tree_check ((lambda), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3183, __FUNCTION__, (LAMBDA_EXPR))))->regen_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3183, __FUNCTION__, (TEMPLATE_INFO))))->args
;
3184 if (args)
3185 args = add_to_template_args (outer_args, args);
3186 else
3187 args = outer_args;
3188 }
3189
3190 /* If any arguments depend on template parameters, we can't
3191 check constraints. Pretend they're satisfied for now. */
3192 if (uses_template_parms (args))
3193 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3194
3195 /* Get the normalized constraints. */
3196 tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
3197
3198 unsigned ftc_count = vec_safe_length (failed_type_completions);
3199
3200 tree result = boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3201 if (norm)
3202 {
3203 if (!push_tinst_level (t))
3204 return result;
3205 push_access_scope (t);
3206 result = satisfy_normalized_constraints (norm, args, info);
3207 pop_access_scope (t);
3208 pop_tinst_level ();
3209 }
3210
3211 /* True if this satisfaction is (heuristically) potentially unstable, i.e.
3212 if its result may depend on where in the program it was performed. */
3213 bool maybe_unstable_satisfaction = false;
3214 if (ftc_count != vec_safe_length (failed_type_completions))
3215 /* Type completion failure occurred during satisfaction. The satisfaction
3216 result may (or may not) materially depend on the completeness of a type,
3217 so we consider it potentially unstable. */
3218 maybe_unstable_satisfaction = true;
3219
3220 if (maybe_unstable_satisfaction)
3221 /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
3222 to check the stability the next time around. */;
3223 else if (info.quiet ())
3224 hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
3225
3226 return result;
3227}
3228
3229/* Evaluate the associated constraints of the template T using ARGS as the
3230 innermost set of template arguments and according to INFO, returning a
3231 satisfaction value. */
3232
3233static tree
3234satisfy_declaration_constraints (tree t, tree args, sat_info info)
3235{
3236 /* Update the declaration for diagnostics. */
3237 info.in_decl = t;
3238
3239 gcc_assert (TREE_CODE (t) == TEMPLATE_DECL)((void)(!(((enum tree_code) (t)->base.code) == TEMPLATE_DECL
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3239, __FUNCTION__), 0 : 0))
;
3240
3241 if (regenerated_lambda_fn_p (t))
3242 {
3243 /* As in the two-parameter version of this function. */
3244 gcc_assert (TMPL_ARGS_DEPTH (args) == 1)((void)(!(((args && ((tree_check ((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3244, __FUNCTION__, (TREE_VEC)))->base.u.length) &&
(*((const_cast<tree *> (tree_vec_elt_check ((args), (0
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3244, __FUNCTION__))))) && ((enum tree_code) ((*((const_cast
<tree *> (tree_vec_elt_check ((args), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3244, __FUNCTION__))))))->base.code) == TREE_VEC) ? ((tree_check
((args), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3244, __FUNCTION__, (TREE_VEC)))->base.u.length) : 1) ==
1) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3244, __FUNCTION__), 0 : 0))
;
3245 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t))((((tree_class_check ((((contains_struct_check ((t), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3245, __FUNCTION__))->decl_minimal.context)), (tcc_type)
, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3245, __FUNCTION__))->type_with_lang_specific.lang_specific
))->lambda_expr)
;
3246 tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda))((struct tree_template_info*)(tree_check (((((struct tree_lambda_expr
*)(tree_check ((lambda), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3246, __FUNCTION__, (LAMBDA_EXPR))))->regen_info)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3246, __FUNCTION__, (TEMPLATE_INFO))))->args
;
3247 args = add_to_template_args (outer_args, args);
3248 }
3249 else
3250 args = add_outermost_template_args (t, args);
3251
3252 /* If any arguments depend on template parameters, we can't
3253 check constraints. Pretend they're satisfied for now. */
3254 if (uses_template_parms (args))
3255 return boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3256
3257 tree result = boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3258 if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
3259 {
3260 if (!push_tinst_level (t, args))
3261 return result;
3262 tree pattern = DECL_TEMPLATE_RESULT (t)((struct tree_template_decl *)(const_cast<union tree_node *
> ((((tree_check ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3262, __FUNCTION__, (TEMPLATE_DECL))))))))->result
;
3263 push_access_scope (pattern);
3264 result = satisfy_normalized_constraints (norm, args, info);
3265 pop_access_scope (pattern);
3266 pop_tinst_level ();
3267 }
3268
3269 return result;
3270}
3271
3272/* A wrapper around satisfy_declaration_constraints and
3273 satisfy_nondeclaration_constraints which additionally replays
3274 quiet ill-formed satisfaction noisily, so that ill-formed
3275 satisfaction always gets diagnosed. */
3276
3277static tree
3278constraint_satisfaction_value (tree t, tree args, sat_info info)
3279{
3280 tree r;
3281 if (DECL_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))]
== tcc_declaration)
)
3282 {
3283 if (args)
3284 r = satisfy_declaration_constraints (t, args, info);
3285 else
3286 r = satisfy_declaration_constraints (t, info);
3287 }
3288 else
3289 r = satisfy_nondeclaration_constraints (t, args, info);
3290 if (r == error_mark_nodeglobal_trees[TI_ERROR_MARK] && info.quiet ()
3291 && !(DECL_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))]
== tcc_declaration)
&& warning_suppressed_p (t)))
3292 {
3293 /* Replay the error noisily. */
3294 sat_info noisy (tf_warning_or_error, info.in_decl);
3295 constraint_satisfaction_value (t, args, noisy);
3296 if (DECL_P (t)(tree_code_type[(int) (((enum tree_code) (t)->base.code))]
== tcc_declaration)
&& !args)
3297 /* Avoid giving these errors again. */
3298 suppress_warning (t);
3299 }
3300 return r;
3301}
3302
3303/* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
3304 and false otherwise, even in the case of errors.
3305
3306 Here, T can be:
3307 - a template declaration
3308 - a template specialization (in which case ARGS must be empty)
3309 - a concept-id (in which case ARGS must be empty)
3310 - a nested-requirement
3311 - a placeholder 'auto'
3312 - a requires-expression. */
3313
3314bool
3315constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
3316{
3317 if (!flag_conceptsglobal_options.x_flag_concepts)
3318 return true;
3319
3320 sat_info quiet (tf_none, NULL_TREE(tree) __null);
3321 return constraint_satisfaction_value (t, args, quiet) == boolean_true_nodeglobal_trees[TI_BOOLEAN_TRUE];
3322}
3323
3324/* Evaluate a concept check of the form C<ARGS>. This is only used for the
3325 evaluation of template-ids as id-expressions. */
3326
3327tree
3328evaluate_concept_check (tree check)
3329{
3330 if (check == error_mark_nodeglobal_trees[TI_ERROR_MARK])
3331 return error_mark_nodeglobal_trees[TI_ERROR_MARK];
3332
3333 gcc_assert (concept_check_p (check))((void)(!(concept_check_p (check)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3333, __FUNCTION__), 0 : 0))
;
3334
3335 /* Check for satisfaction without diagnostics. */
3336 sat_info quiet (tf_none, NULL_TREE(tree) __null);
3337 return constraint_satisfaction_value (check, /*args=*/NULL_TREE(tree) __null, quiet);
3338}
3339
3340/* Evaluate the requires-expression T, returning either boolean_true_node
3341 or boolean_false_node. This is used during folding and constexpr
3342 evaluation. */
3343
3344tree
3345evaluate_requires_expr (tree t)
3346{
3347 gcc_assert (TREE_CODE (t) == REQUIRES_EXPR)((void)(!(((enum tree_code) (t)->base.code) == REQUIRES_EXPR
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3347, __FUNCTION__), 0 : 0))
;
3348 sat_info quiet (tf_none, NULL_TREE(tree) __null);
3349 return constraint_satisfaction_value (t, /*args=*/NULL_TREE(tree) __null, quiet);
3350}
3351
3352/*---------------------------------------------------------------------------
3353 Semantic analysis of requires-expressions
3354---------------------------------------------------------------------------*/
3355
3356/* Finish a requires expression for the given PARMS (possibly
3357 null) and the non-empty sequence of requirements. */
3358
3359tree
3360finish_requires_expr (location_t loc, tree parms, tree reqs)
3361{
3362 /* Build the node. */
3363 tree r = build_min (REQUIRES_EXPR, boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], parms, reqs, NULL_TREE(tree) __null);
3364 TREE_SIDE_EFFECTS (r)((non_type_check ((r), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3364, __FUNCTION__))->base.side_effects_flag)
= false;
3365 TREE_CONSTANT (r)((non_type_check ((r), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3365, __FUNCTION__))->base.constant_flag)
= true;
3366 SET_EXPR_LOCATION (r, loc)(expr_check (((r)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3366, __FUNCTION__))->exp.locus = (loc)
;
3367 return r;
3368}
3369
3370/* Construct a requirement for the validity of EXPR. */
3371
3372tree
3373finish_simple_requirement (location_t loc, tree expr)
3374{
3375 tree r = build_nt (SIMPLE_REQ, expr);
3376 SET_EXPR_LOCATION (r, loc)(expr_check (((r)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3376, __FUNCTION__))->exp.locus = (loc)
;
3377 return r;
3378}
3379
3380/* Construct a requirement for the validity of TYPE. */
3381
3382tree
3383finish_type_requirement (location_t loc, tree type)
3384{
3385 tree r = build_nt (TYPE_REQ, type);
3386 SET_EXPR_LOCATION (r, loc)(expr_check (((r)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3386, __FUNCTION__))->exp.locus = (loc)
;
3387 return r;
3388}
3389
3390/* Construct a requirement for the validity of EXPR, along with
3391 its properties. if TYPE is non-null, then it specifies either
3392 an implicit conversion or argument deduction constraint,
3393 depending on whether any placeholders occur in the type name.
3394 NOEXCEPT_P is true iff the noexcept keyword was specified. */
3395
3396tree
3397finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept_p)
3398{
3399 tree req = build_nt (COMPOUND_REQ, expr, type);
3400 SET_EXPR_LOCATION (req, loc)(expr_check (((req)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3400, __FUNCTION__))->exp.locus = (loc)
;
3401 COMPOUND_REQ_NOEXCEPT_P (req)((tree_not_check2 (((tree_check ((req), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3401, __FUNCTION__, (COMPOUND_REQ)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3401, __FUNCTION__, (TREE_VEC), (SSA_NAME)))->base.u.bits
.lang_flag_0)
= noexcept_p;
3402 return req;
3403}
3404
3405/* Finish a nested requirement. */
3406
3407tree
3408finish_nested_requirement (location_t loc, tree expr)
3409{
3410 /* Build the requirement, saving the set of in-scope template
3411 parameters as its type. */
3412 tree r = build1 (NESTED_REQ, current_template_parmsscope_chain->template_parms, expr);
3413 SET_EXPR_LOCATION (r, loc)(expr_check (((r)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3413, __FUNCTION__))->exp.locus = (loc)
;
3414 return r;
3415}
3416
3417/* Check that FN satisfies the structural requirements of a
3418 function concept definition. */
3419tree
3420check_function_concept (tree fn)
3421{
3422 /* Check that the function is comprised of only a return statement. */
3423 tree body = DECL_SAVED_TREE (fn)((tree_check ((fn), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3423, __FUNCTION__, (FUNCTION_DECL)))->function_decl.saved_tree
)
;
3424 if (TREE_CODE (body)((enum tree_code) (body)->base.code) == BIND_EXPR)
3425 body = BIND_EXPR_BODY (body)((*((const_cast<tree*> (tree_operand_check (((tree_check
((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3425, __FUNCTION__, (BIND_EXPR)))), (1), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3425, __FUNCTION__))))))
;
3426
3427 /* Sometimes a function call results in the creation of clean up
3428 points. Allow these to be preserved in the body of the
3429 constraint, as we might actually need them for some constexpr
3430 evaluations. */
3431 if (TREE_CODE (body)((enum tree_code) (body)->base.code) == CLEANUP_POINT_EXPR)
3432 body = TREE_OPERAND (body, 0)(*((const_cast<tree*> (tree_operand_check ((body), (0),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3432, __FUNCTION__)))))
;
3433
3434 /* Check that the definition is written correctly. */
3435 if (TREE_CODE (body)((enum tree_code) (body)->base.code) != RETURN_EXPR)
3436 {
3437 location_t loc = DECL_SOURCE_LOCATION (fn)((contains_struct_check ((fn), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3437, __FUNCTION__))->decl_minimal.locus)
;
3438 if (TREE_CODE (body)((enum tree_code) (body)->base.code) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body)((tree_check ((body), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3438, __FUNCTION__, (STATEMENT_LIST)))->stmt_list.head)
)
3439 {
3440 if (seen_error ())
3441 /* The definition was probably erroneous, not empty. */;
3442 else
3443 error_at (loc, "definition of concept %qD is empty", fn);
3444 }
3445 else
3446 error_at (loc, "definition of concept %qD has multiple statements", fn);
3447 }
3448
3449 return NULL_TREE(tree) __null;
3450}
3451
3452/*---------------------------------------------------------------------------
3453 Equivalence of constraints
3454---------------------------------------------------------------------------*/
3455
3456/* Returns true when A and B are equivalent constraints. */
3457bool
3458equivalent_constraints (tree a, tree b)
3459{
3460 gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO)((void)(!(!a || ((enum tree_code) (a)->base.code) == CONSTRAINT_INFO
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3460, __FUNCTION__), 0 : 0))
;
3461 gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO)((void)(!(!b || ((enum tree_code) (b)->base.code) == CONSTRAINT_INFO
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3461, __FUNCTION__), 0 : 0))
;
3462 return cp_tree_equal (a, b);
3463}
3464
3465/* Returns true if the template declarations A and B have equivalent
3466 constraints. This is the case when A's constraints subsume B's and
3467 when B's also constrain A's. */
3468bool
3469equivalently_constrained (tree d1, tree d2)
3470{
3471 gcc_assert (TREE_CODE (d1) == TREE_CODE (d2))((void)(!(((enum tree_code) (d1)->base.code) == ((enum tree_code
) (d2)->base.code)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3471, __FUNCTION__), 0 : 0))
;
3472 return equivalent_constraints (get_constraints (d1), get_constraints (d2));
3473}
3474
3475/*---------------------------------------------------------------------------
3476 Partial ordering of constraints
3477---------------------------------------------------------------------------*/
3478
3479/* Returns true when the constraints in CI strictly subsume
3480 the associated constraints of TMPL. */
3481
3482bool
3483strictly_subsumes (tree ci, tree tmpl)
3484{
3485 tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE(tree) __null);
3486 tree n2 = get_normalized_constraints_from_decl (tmpl);
3487
3488 return subsumes (n1, n2) && !subsumes (n2, n1);
3489}
3490
3491/* Returns true when the constraints in CI subsume the
3492 associated constraints of TMPL. */
3493
3494bool
3495weakly_subsumes (tree ci, tree tmpl)
3496{
3497 tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE(tree) __null);
3498 tree n2 = get_normalized_constraints_from_decl (tmpl);
3499
3500 return subsumes (n1, n2);
3501}
3502
3503/* Determines which of the declarations, A or B, is more constrained.
3504 That is, which declaration's constraints subsume but are not subsumed
3505 by the other's?
3506
3507 Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
3508 than D1, and 0 otherwise. */
3509
3510int
3511more_constrained (tree d1, tree d2)
3512{
3513 tree n1 = get_normalized_constraints_from_decl (d1);
3514 tree n2 = get_normalized_constraints_from_decl (d2);
3515
3516 int winner = 0;
3517 if (subsumes (n1, n2))
3518 ++winner;
3519 if (subsumes (n2, n1))
3520 --winner;
3521 return winner;
3522}
3523
3524/* Return whether D1 is at least as constrained as D2. */
3525
3526bool
3527at_least_as_constrained (tree d1, tree d2)
3528{
3529 tree n1 = get_normalized_constraints_from_decl (d1);
3530 tree n2 = get_normalized_constraints_from_decl (d2);
3531
3532 return subsumes (n1, n2);
3533}
3534
3535/*---------------------------------------------------------------------------
3536 Constraint diagnostics
3537---------------------------------------------------------------------------*/
3538
3539/* Returns the best location to diagnose a constraint error. */
3540
3541static location_t
3542get_constraint_error_location (tree t)
3543{
3544 if (location_t loc = cp_expr_location (t))
3545 return loc;
3546
3547 /* If we have a specific location give it. */
3548 tree expr = CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3548, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3548, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3548, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
3549 if (location_t loc = cp_expr_location (expr))
3550 return loc;
3551
3552 /* If the constraint is normalized from a requires-clause, give
3553 the location as that of the constrained declaration. */
3554 tree cxt = CONSTR_CONTEXT (t)((tree_check ((((contains_struct_check (((tree_check3 ((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3554, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3554, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3554, __FUNCTION__, (TREE_LIST)))->list.value)
;
3555 tree src = cxt ? TREE_VALUE (cxt)((tree_check ((cxt), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3555, __FUNCTION__, (TREE_LIST)))->list.value)
: NULL_TREE(tree) __null;
3556 if (!src)
3557 /* TODO: This only happens for constrained non-template declarations. */
3558 ;
3559 else if (DECL_P (src)(tree_code_type[(int) (((enum tree_code) (src)->base.code)
)] == tcc_declaration)
)
3560 return DECL_SOURCE_LOCATION (src)((contains_struct_check ((src), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3560, __FUNCTION__))->decl_minimal.locus)
;
3561 /* Otherwise, give the location as the defining concept. */
3562 else if (concept_check_p (src))
3563 {
3564 tree id = unpack_concept_check (src);
3565 tree tmpl = TREE_OPERAND (id, 0)(*((const_cast<tree*> (tree_operand_check ((id), (0), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3565, __FUNCTION__)))))
;
3566 if (OVL_P (tmpl)(((enum tree_code) (tmpl)->base.code) == FUNCTION_DECL || (
(enum tree_code) (tmpl)->base.code) == OVERLOAD)
)
3567 tmpl = OVL_FIRST (tmpl)ovl_first (tmpl);
3568 return DECL_SOURCE_LOCATION (tmpl)((contains_struct_check ((tmpl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3568, __FUNCTION__))->decl_minimal.locus)
;
3569 }
3570
3571 return input_location;
3572}
3573
3574/* Emit a diagnostic for a failed trait. */
3575
3576static void
3577diagnose_trait_expr (tree expr, tree args)
3578{
3579 location_t loc = cp_expr_location (expr);
3580
3581 /* Build a "fake" version of the instantiated trait, so we can
3582 get the instantiated types from result. */
3583 ++processing_template_declscope_chain->x_processing_template_decl;
3584 expr = tsubst_expr (expr, args, tf_none, NULL_TREE(tree) __null, false);
3585 --processing_template_declscope_chain->x_processing_template_decl;
3586
3587 tree t1 = TRAIT_EXPR_TYPE1 (expr)(((struct tree_trait_expr *)(tree_check ((expr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3587, __FUNCTION__, (TRAIT_EXPR))))->type1)
;
3588 tree t2 = TRAIT_EXPR_TYPE2 (expr)(((struct tree_trait_expr *)(tree_check ((expr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3588, __FUNCTION__, (TRAIT_EXPR))))->type2)
;
3589 switch (TRAIT_EXPR_KIND (expr)(((struct tree_trait_expr *)(tree_check ((expr), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3589, __FUNCTION__, (TRAIT_EXPR))))->kind)
)
3590 {
3591 case CPTK_HAS_NOTHROW_ASSIGN:
3592 inform (loc, " %qT is not %<nothrow%> copy assignable", t1);
3593 break;
3594 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
3595 inform (loc, " %qT is not %<nothrow%> default constructible", t1);
3596 break;
3597 case CPTK_HAS_NOTHROW_COPY:
3598 inform (loc, " %qT is not %<nothrow%> copy constructible", t1);
3599 break;
3600 case CPTK_HAS_TRIVIAL_ASSIGN:
3601 inform (loc, " %qT is not trivially copy assignable", t1);
3602 break;
3603 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
3604 inform (loc, " %qT is not trivially default constructible", t1);
3605 break;
3606 case CPTK_HAS_TRIVIAL_COPY:
3607 inform (loc, " %qT is not trivially copy constructible", t1);
3608 break;
3609 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
3610 inform (loc, " %qT is not trivially destructible", t1);
3611 break;
3612 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
3613 inform (loc, " %qT does not have a virtual destructor", t1);
3614 break;
3615 case CPTK_IS_ABSTRACT:
3616 inform (loc, " %qT is not an abstract class", t1);
3617 break;
3618 case CPTK_IS_BASE_OF:
3619 inform (loc, " %qT is not a base of %qT", t1, t2);
3620 break;
3621 case CPTK_IS_CLASS:
3622 inform (loc, " %qT is not a class", t1);
3623 break;
3624 case CPTK_IS_EMPTY:
3625 inform (loc, " %qT is not an empty class", t1);
3626 break;
3627 case CPTK_IS_ENUM:
3628 inform (loc, " %qT is not an enum", t1);
3629 break;
3630 case CPTK_IS_FINAL:
3631 inform (loc, " %qT is not a final class", t1);
3632 break;
3633 case CPTK_IS_LAYOUT_COMPATIBLE:
3634 inform (loc, " %qT is not layout compatible with %qT", t1, t2);
3635 break;
3636 case CPTK_IS_LITERAL_TYPE:
3637 inform (loc, " %qT is not a literal type", t1);
3638 break;
3639 case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
3640 inform (loc, " %qT is not pointer-interconvertible base of %qT",
3641 t1, t2);
3642 break;
3643 case CPTK_IS_POD:
3644 inform (loc, " %qT is not a POD type", t1);
3645 break;
3646 case CPTK_IS_POLYMORPHIC:
3647 inform (loc, " %qT is not a polymorphic type", t1);
3648 break;
3649 case CPTK_IS_SAME_AS:
3650 inform (loc, " %qT is not the same as %qT", t1, t2);
3651 break;
3652 case CPTK_IS_STD_LAYOUT:
3653 inform (loc, " %qT is not an standard layout type", t1);
3654 break;
3655 case CPTK_IS_TRIVIAL:
3656 inform (loc, " %qT is not a trivial type", t1);
3657 break;
3658 case CPTK_IS_UNION:
3659 inform (loc, " %qT is not a union", t1);
3660 break;
3661 default:
3662 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3662, __FUNCTION__))
;
3663 }
3664}
3665
3666/* Diagnose a substitution failure in the atomic constraint T when applied
3667 with the instantiated parameter mapping MAP. */
3668
3669static void
3670diagnose_atomic_constraint (tree t, tree map, tree result, sat_info info)
3671{
3672 /* If the constraint is already ill-formed, we've previously diagnosed
3673 the reason. We should still say why the constraints aren't satisfied. */
3674 if (t == error_mark_nodeglobal_trees[TI_ERROR_MARK])
3675 {
3676 location_t loc;
3677 if (info.in_decl)
3678 loc = DECL_SOURCE_LOCATION (info.in_decl)((contains_struct_check ((info.in_decl), (TS_DECL_MINIMAL), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3678, __FUNCTION__))->decl_minimal.locus)
;
3679 else
3680 loc = input_location;
3681 inform (loc, "invalid constraints");
3682 return;
3683 }
3684
3685 location_t loc = get_constraint_error_location (t);
3686 iloc_sentinel loc_s (loc);
3687
3688 /* Generate better diagnostics for certain kinds of expressions. */
3689 tree expr = ATOMIC_CONSTR_EXPR (t)((tree_check ((((contains_struct_check (((tree_check3 (((tree_check
((t), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3689, __FUNCTION__, (ATOMIC_CONSTR)))), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3689, __FUNCTION__, (ATOMIC_CONSTR), (CONJ_CONSTR), (DISJ_CONSTR
)))), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3689, __FUNCTION__))->typed.type)), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3689, __FUNCTION__, (TREE_LIST)))->list.purpose)
;
3690 STRIP_ANY_LOCATION_WRAPPER (expr)(expr) = tree_strip_any_location_wrapper ((const_cast<union
tree_node *> (((expr)))))
;
3691 tree args = get_mapped_args (map);
3692 switch (TREE_CODE (expr)((enum tree_code) (expr)->base.code))
3693 {
3694 case TRAIT_EXPR:
3695 diagnose_trait_expr (expr, args);
3696 break;
3697 case REQUIRES_EXPR:
3698 gcc_checking_assert (info.diagnose_unsatisfaction_p ())((void)(!(info.diagnose_unsatisfaction_p ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3698, __FUNCTION__), 0 : 0))
;
3699 /* Clear in_decl before replaying the substitution to avoid emitting
3700 seemingly unhelpful "in declaration ..." notes that follow some
3701 substitution failure error messages. */
3702 info.in_decl = NULL_TREE(tree) __null;
3703 tsubst_requires_expr (expr, args, info);
3704 break;
3705 default:
3706 if (!same_type_p (TREE_TYPE (result), boolean_type_node)comptypes ((((contains_struct_check ((result), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3706, __FUNCTION__))->typed.type)), (global_trees[TI_BOOLEAN_TYPE
]), 0)
)
3707 error_at (loc, "constraint %qE has type %qT, not %<bool%>",
3708 t, TREE_TYPE (result)((contains_struct_check ((result), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3708, __FUNCTION__))->typed.type)
);
3709 else
3710 inform (loc, "the expression %qE evaluated to %<false%>", t);
3711 }
3712}
3713
3714GTY(()) tree current_failed_constraint;
3715
3716diagnosing_failed_constraint::
3717diagnosing_failed_constraint (tree t, tree args, bool diag)
3718 : diagnosing_error (diag)
3719{
3720 if (diagnosing_error)
3721 {
3722 current_failed_constraint
3723 = tree_cons (args, t, current_failed_constraint);
3724 ++current_constraint_diagnosis_depth;
3725 }
3726}
3727
3728diagnosing_failed_constraint::
3729~diagnosing_failed_constraint ()
3730{
3731 if (diagnosing_error)
3732 {
3733 --current_constraint_diagnosis_depth;
3734 if (current_failed_constraint)
3735 current_failed_constraint = TREE_CHAIN (current_failed_constraint)((contains_struct_check ((current_failed_constraint), (TS_COMMON
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/cp/constraint.cc"
, 3735, __FUNCTION__))->common.chain)
;
3736 }
3737
3738}
3739
3740/* Whether we are allowed to replay an error that underlies a constraint failure
3741 at the current diagnosis depth. */
3742
3743bool
3744diagnosing_failed_constraint::replay_errors_p ()
3745{
3746 if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depthglobal_options.x_concepts_diagnostics_max_depth)
3747 {
3748 concepts_diagnostics_max_depth_exceeded_p = true;
3749 return false;
3750 }
3751 else
3752 return true;
3753}
3754
3755/* Emit diagnostics detailing the failure ARGS to satisfy the constraints
3756 of T. Here, T and ARGS are as in constraints_satisfied_p. */
3757
3758void
3759diagnose_constraints (location_t loc, tree t, tree args)
3760{
3761 inform (loc, "constraints not satisfied");
3762
3763 if (concepts_diagnostics_max_depthglobal_options.x_concepts_diagnostics_max_depth == 0)
3764 return;
3765
3766 /* Replay satisfaction, but diagnose unsatisfaction. */
3767 sat_info noisy (tf_warning_or_error, NULL_TREE(tree) __null, /*diag_unsat=*/true);
3768 constraint_satisfaction_value (t, args, noisy);
3769
3770 static bool suggested_p;
3771 if (concepts_diagnostics_max_depth_exceeded_p
3772 && current_constraint_diagnosis_depth == 0
3773 && !suggested_p)
3774 {
3775 inform (UNKNOWN_LOCATION((location_t) 0),
3776 "set %qs to at least %d for more detail",
3777 "-fconcepts-diagnostics-depth=",
3778 concepts_diagnostics_max_depthglobal_options.x_concepts_diagnostics_max_depth + 1);
3779 suggested_p = true;
3780 }
3781}
3782
3783#include "gt-cp-constraint.h"

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

1/* Vector API for GNU compiler.
2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#ifndef GCC_VEC_H
23#define GCC_VEC_H
24
25/* Some gen* file have no ggc support as the header file gtype-desc.h is
26 missing. Provide these definitions in case ggc.h has not been included.
27 This is not a problem because any code that runs before gengtype is built
28 will never need to use GC vectors.*/
29
30extern void ggc_free (void *);
31extern size_t ggc_round_alloc_size (size_t requested_size);
32extern void *ggc_realloc (void *, size_t MEM_STAT_DECL);
33
34/* Templated vector type and associated interfaces.
35
36 The interface functions are typesafe and use inline functions,
37 sometimes backed by out-of-line generic functions. The vectors are
38 designed to interoperate with the GTY machinery.
39
40 There are both 'index' and 'iterate' accessors. The index accessor
41 is implemented by operator[]. The iterator returns a boolean
42 iteration condition and updates the iteration variable passed by
43 reference. Because the iterator will be inlined, the address-of
44 can be optimized away.
45
46 Each operation that increases the number of active elements is
47 available in 'quick' and 'safe' variants. The former presumes that
48 there is sufficient allocated space for the operation to succeed
49 (it dies if there is not). The latter will reallocate the
50 vector, if needed. Reallocation causes an exponential increase in
51 vector size. If you know you will be adding N elements, it would
52 be more efficient to use the reserve operation before adding the
53 elements with the 'quick' operation. This will ensure there are at
54 least as many elements as you ask for, it will exponentially
55 increase if there are too few spare slots. If you want reserve a
56 specific number of slots, but do not want the exponential increase
57 (for instance, you know this is the last allocation), use the
58 reserve_exact operation. You can also create a vector of a
59 specific size from the get go.
60
61 You should prefer the push and pop operations, as they append and
62 remove from the end of the vector. If you need to remove several
63 items in one go, use the truncate operation. The insert and remove
64 operations allow you to change elements in the middle of the
65 vector. There are two remove operations, one which preserves the
66 element ordering 'ordered_remove', and one which does not
67 'unordered_remove'. The latter function copies the end element
68 into the removed slot, rather than invoke a memmove operation. The
69 'lower_bound' function will determine where to place an item in the
70 array using insert that will maintain sorted order.
71
72 Vectors are template types with three arguments: the type of the
73 elements in the vector, the allocation strategy, and the physical
74 layout to use
75
76 Four allocation strategies are supported:
77
78 - Heap: allocation is done using malloc/free. This is the
79 default allocation strategy.
80
81 - GC: allocation is done using ggc_alloc/ggc_free.
82
83 - GC atomic: same as GC with the exception that the elements
84 themselves are assumed to be of an atomic type that does
85 not need to be garbage collected. This means that marking
86 routines do not need to traverse the array marking the
87 individual elements. This increases the performance of
88 GC activities.
89
90 Two physical layouts are supported:
91
92 - Embedded: The vector is structured using the trailing array
93 idiom. The last member of the structure is an array of size
94 1. When the vector is initially allocated, a single memory
95 block is created to hold the vector's control data and the
96 array of elements. These vectors cannot grow without
97 reallocation (see discussion on embeddable vectors below).
98
99 - Space efficient: The vector is structured as a pointer to an
100 embedded vector. This is the default layout. It means that
101 vectors occupy a single word of storage before initial
102 allocation. Vectors are allowed to grow (the internal
103 pointer is reallocated but the main vector instance does not
104 need to relocate).
105
106 The type, allocation and layout are specified when the vector is
107 declared.
108
109 If you need to directly manipulate a vector, then the 'address'
110 accessor will return the address of the start of the vector. Also
111 the 'space' predicate will tell you whether there is spare capacity
112 in the vector. You will not normally need to use these two functions.
113
114 Notes on the different layout strategies
115
116 * Embeddable vectors (vec<T, A, vl_embed>)
117
118 These vectors are suitable to be embedded in other data
119 structures so that they can be pre-allocated in a contiguous
120 memory block.
121
122 Embeddable vectors are implemented using the trailing array
123 idiom, thus they are not resizeable without changing the address
124 of the vector object itself. This means you cannot have
125 variables or fields of embeddable vector type -- always use a
126 pointer to a vector. The one exception is the final field of a
127 structure, which could be a vector type.
128
129 You will have to use the embedded_size & embedded_init calls to
130 create such objects, and they will not be resizeable (so the
131 'safe' allocation variants are not available).
132
133 Properties of embeddable vectors:
134
135 - The whole vector and control data are allocated in a single
136 contiguous block. It uses the trailing-vector idiom, so
137 allocation must reserve enough space for all the elements
138 in the vector plus its control data.
139 - The vector cannot be re-allocated.
140 - The vector cannot grow nor shrink.
141 - No indirections needed for access/manipulation.
142 - It requires 2 words of storage (prior to vector allocation).
143
144
145 * Space efficient vector (vec<T, A, vl_ptr>)
146
147 These vectors can grow dynamically and are allocated together
148 with their control data. They are suited to be included in data
149 structures. Prior to initial allocation, they only take a single
150 word of storage.
151
152 These vectors are implemented as a pointer to embeddable vectors.
153 The semantics allow for this pointer to be NULL to represent
154 empty vectors. This way, empty vectors occupy minimal space in
155 the structure containing them.
156
157 Properties:
158
159 - The whole vector and control data are allocated in a single
160 contiguous block.
161 - The whole vector may be re-allocated.
162 - Vector data may grow and shrink.
163 - Access and manipulation requires a pointer test and
164 indirection.
165 - It requires 1 word of storage (prior to vector allocation).
166
167 An example of their use would be,
168
169 struct my_struct {
170 // A space-efficient vector of tree pointers in GC memory.
171 vec<tree, va_gc, vl_ptr> v;
172 };
173
174 struct my_struct *s;
175
176 if (s->v.length ()) { we have some contents }
177 s->v.safe_push (decl); // append some decl onto the end
178 for (ix = 0; s->v.iterate (ix, &elt); ix++)
179 { do something with elt }
180*/
181
182/* Support function for statistics. */
183extern void dump_vec_loc_statistics (void);
184
185/* Hashtable mapping vec addresses to descriptors. */
186extern htab_t vec_mem_usage_hash;
187
188/* Control data for vectors. This contains the number of allocated
189 and used slots inside a vector. */
190
191struct vec_prefix
192{
193 /* FIXME - These fields should be private, but we need to cater to
194 compilers that have stricter notions of PODness for types. */
195
196 /* Memory allocation support routines in vec.c. */
197 void register_overhead (void *, size_t, size_t CXX_MEM_STAT_INFO);
198 void release_overhead (void *, size_t, size_t, bool CXX_MEM_STAT_INFO);
199 static unsigned calculate_allocation (vec_prefix *, unsigned, bool);
200 static unsigned calculate_allocation_1 (unsigned, unsigned);
201
202 /* Note that vec_prefix should be a base class for vec, but we use
203 offsetof() on vector fields of tree structures (e.g.,
204 tree_binfo::base_binfos), and offsetof only supports base types.
205
206 To compensate, we make vec_prefix a field inside vec and make
207 vec a friend class of vec_prefix so it can access its fields. */
208 template <typename, typename, typename> friend struct vec;
209
210 /* The allocator types also need access to our internals. */
211 friend struct va_gc;
212 friend struct va_gc_atomic;
213 friend struct va_heap;
214
215 unsigned m_alloc : 31;
216 unsigned m_using_auto_storage : 1;
217 unsigned m_num;
218};
219
220/* Calculate the number of slots to reserve a vector, making sure that
221 RESERVE slots are free. If EXACT grow exactly, otherwise grow
222 exponentially. PFX is the control data for the vector. */
223
224inline unsigned
225vec_prefix::calculate_allocation (vec_prefix *pfx, unsigned reserve,
226 bool exact)
227{
228 if (exact)
229 return (pfx ? pfx->m_num : 0) + reserve;
230 else if (!pfx)
231 return MAX (4, reserve)((4) > (reserve) ? (4) : (reserve));
232 return calculate_allocation_1 (pfx->m_alloc, pfx->m_num + reserve);
233}
234
235template<typename, typename, typename> struct vec;
236
237/* Valid vector layouts
238
239 vl_embed - Embeddable vector that uses the trailing array idiom.
240 vl_ptr - Space efficient vector that uses a pointer to an
241 embeddable vector. */
242struct vl_embed { };
243struct vl_ptr { };
244
245
246/* Types of supported allocations
247
248 va_heap - Allocation uses malloc/free.
249 va_gc - Allocation uses ggc_alloc.
250 va_gc_atomic - Same as GC, but individual elements of the array
251 do not need to be marked during collection. */
252
253/* Allocator type for heap vectors. */
254struct va_heap
255{
256 /* Heap vectors are frequently regular instances, so use the vl_ptr
257 layout for them. */
258 typedef vl_ptr default_layout;
259
260 template<typename T>
261 static void reserve (vec<T, va_heap, vl_embed> *&, unsigned, bool
262 CXX_MEM_STAT_INFO);
263
264 template<typename T>
265 static void release (vec<T, va_heap, vl_embed> *&);
266};
267
268
269/* Allocator for heap memory. Ensure there are at least RESERVE free
270 slots in V. If EXACT is true, grow exactly, else grow
271 exponentially. As a special case, if the vector had not been
272 allocated and RESERVE is 0, no vector will be created. */
273
274template<typename T>
275inline void
276va_heap::reserve (vec<T, va_heap, vl_embed> *&v, unsigned reserve, bool exact
277 MEM_STAT_DECL)
278{
279 size_t elt_size = sizeof (T);
280 unsigned alloc
281 = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
282 gcc_checking_assert (alloc)((void)(!(alloc) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 282, __FUNCTION__), 0 : 0))
;
283
284 if (GATHER_STATISTICS0 && v)
285 v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
286 v->allocated (), false);
287
288 size_t size = vec<T, va_heap, vl_embed>::embedded_size (alloc);
289 unsigned nelem = v ? v->length () : 0;
290 v = static_cast <vec<T, va_heap, vl_embed> *> (xrealloc (v, size));
291 v->embedded_init (alloc, nelem);
292
293 if (GATHER_STATISTICS0)
294 v->m_vecpfx.register_overhead (v, alloc, elt_size PASS_MEM_STAT);
295}
296
297
298#if GCC_VERSION(4 * 1000 + 2) >= 4007
299#pragma GCC diagnostic push
300#pragma GCC diagnostic ignored "-Wfree-nonheap-object"
301#endif
302
303/* Free the heap space allocated for vector V. */
304
305template<typename T>
306void
307va_heap::release (vec<T, va_heap, vl_embed> *&v)
308{
309 size_t elt_size = sizeof (T);
310 if (v == NULL__null)
311 return;
312
313 if (GATHER_STATISTICS0)
314 v->m_vecpfx.release_overhead (v, elt_size * v->allocated (),
315 v->allocated (), true);
316 ::free (v);
317 v = NULL__null;
318}
319
320#if GCC_VERSION(4 * 1000 + 2) >= 4007
321#pragma GCC diagnostic pop
322#endif
323
324/* Allocator type for GC vectors. Notice that we need the structure
325 declaration even if GC is not enabled. */
326
327struct va_gc
328{
329 /* Use vl_embed as the default layout for GC vectors. Due to GTY
330 limitations, GC vectors must always be pointers, so it is more
331 efficient to use a pointer to the vl_embed layout, rather than
332 using a pointer to a pointer as would be the case with vl_ptr. */
333 typedef vl_embed default_layout;
334
335 template<typename T, typename A>
336 static void reserve (vec<T, A, vl_embed> *&, unsigned, bool
337 CXX_MEM_STAT_INFO);
338
339 template<typename T, typename A>
340 static void release (vec<T, A, vl_embed> *&v);
341};
342
343
344/* Free GC memory used by V and reset V to NULL. */
345
346template<typename T, typename A>
347inline void
348va_gc::release (vec<T, A, vl_embed> *&v)
349{
350 if (v)
351 ::ggc_free (v);
352 v = NULL__null;
353}
354
355
356/* Allocator for GC memory. Ensure there are at least RESERVE free
357 slots in V. If EXACT is true, grow exactly, else grow
358 exponentially. As a special case, if the vector had not been
359 allocated and RESERVE is 0, no vector will be created. */
360
361template<typename T, typename A>
362void
363va_gc::reserve (vec<T, A, vl_embed> *&v, unsigned reserve, bool exact
364 MEM_STAT_DECL)
365{
366 unsigned alloc
367 = vec_prefix::calculate_allocation (v ? &v->m_vecpfx : 0, reserve, exact);
15
Assuming 'v' is non-null
16
'?' condition is true
368 if (!alloc)
17
Assuming 'alloc' is 0
18
Taking true branch
369 {
370 ::ggc_free (v);
371 v = NULL__null;
19
Null pointer value stored to 'failed_type_completions'
372 return;
373 }
374
375 /* Calculate the amount of space we want. */
376 size_t size = vec<T, A, vl_embed>::embedded_size (alloc);
377
378 /* Ask the allocator how much space it will really give us. */
379 size = ::ggc_round_alloc_size (size);
380
381 /* Adjust the number of slots accordingly. */
382 size_t vec_offset = sizeof (vec_prefix);
383 size_t elt_size = sizeof (T);
384 alloc = (size - vec_offset) / elt_size;
385
386 /* And finally, recalculate the amount of space we ask for. */
387 size = vec_offset + alloc * elt_size;
388
389 unsigned nelem = v ? v->length () : 0;
390 v = static_cast <vec<T, A, vl_embed> *> (::ggc_realloc (v, size
391 PASS_MEM_STAT));
392 v->embedded_init (alloc, nelem);
393}
394
395
396/* Allocator type for GC vectors. This is for vectors of types
397 atomics w.r.t. collection, so allocation and deallocation is
398 completely inherited from va_gc. */
399struct va_gc_atomic : va_gc
400{
401};
402
403
404/* Generic vector template. Default values for A and L indicate the
405 most commonly used strategies.
406
407 FIXME - Ideally, they would all be vl_ptr to encourage using regular
408 instances for vectors, but the existing GTY machinery is limited
409 in that it can only deal with GC objects that are pointers
410 themselves.
411
412 This means that vector operations that need to deal with
413 potentially NULL pointers, must be provided as free
414 functions (see the vec_safe_* functions above). */
415template<typename T,
416 typename A = va_heap,
417 typename L = typename A::default_layout>
418struct GTY((user)) vec
419{
420};
421
422/* Allow C++11 range-based 'for' to work directly on vec<T>*. */
423template<typename T, typename A, typename L>
424T* begin (vec<T,A,L> *v) { return v ? v->begin () : nullptr; }
425template<typename T, typename A, typename L>
426T* end (vec<T,A,L> *v) { return v ? v->end () : nullptr; }
427template<typename T, typename A, typename L>
428const T* begin (const vec<T,A,L> *v) { return v ? v->begin () : nullptr; }
429template<typename T, typename A, typename L>
430const T* end (const vec<T,A,L> *v) { return v ? v->end () : nullptr; }
431
432/* Generic vec<> debug helpers.
433
434 These need to be instantiated for each vec<TYPE> used throughout
435 the compiler like this:
436
437 DEFINE_DEBUG_VEC (TYPE)
438
439 The reason we have a debug_helper() is because GDB can't
440 disambiguate a plain call to debug(some_vec), and it must be called
441 like debug<TYPE>(some_vec). */
442
443template<typename T>
444void
445debug_helper (vec<T> &ref)
446{
447 unsigned i;
448 for (i = 0; i < ref.length (); ++i)
449 {
450 fprintf (stderrstderr, "[%d] = ", i);
451 debug_slim (ref[i]);
452 fputc ('\n', stderrstderr);
453 }
454}
455
456/* We need a separate va_gc variant here because default template
457 argument for functions cannot be used in c++-98. Once this
458 restriction is removed, those variant should be folded with the
459 above debug_helper. */
460
461template<typename T>
462void
463debug_helper (vec<T, va_gc> &ref)
464{
465 unsigned i;
466 for (i = 0; i < ref.length (); ++i)
467 {
468 fprintf (stderrstderr, "[%d] = ", i);
469 debug_slim (ref[i]);
470 fputc ('\n', stderrstderr);
471 }
472}
473
474/* Macro to define debug(vec<T>) and debug(vec<T, va_gc>) helper
475 functions for a type T. */
476
477#define DEFINE_DEBUG_VEC(T)template void debug_helper (vec<T> &); template void
debug_helper (vec<T, va_gc> &); __attribute__ ((__used__
)) void debug (vec<T> &ref) { debug_helper <T>
(ref); } __attribute__ ((__used__)) void debug (vec<T>
*ptr) { if (ptr) debug (*ptr); else fprintf (stderr, "<nil>\n"
); } __attribute__ ((__used__)) void debug (vec<T, va_gc>
&ref) { debug_helper <T> (ref); } __attribute__ ((
__used__)) void debug (vec<T, va_gc> *ptr) { if (ptr) debug
(*ptr); else fprintf (stderr, "<nil>\n"); }
\
478 template void debug_helper (vec<T> &); \
479 template void debug_helper (vec<T, va_gc> &); \
480 /* Define the vec<T> debug functions. */ \
481 DEBUG_FUNCTION__attribute__ ((__used__)) void \
482 debug (vec<T> &ref) \
483 { \
484 debug_helper <T> (ref); \
485 } \
486 DEBUG_FUNCTION__attribute__ ((__used__)) void \
487 debug (vec<T> *ptr) \
488 { \
489 if (ptr) \
490 debug (*ptr); \
491 else \
492 fprintf (stderrstderr, "<nil>\n"); \
493 } \
494 /* Define the vec<T, va_gc> debug functions. */ \
495 DEBUG_FUNCTION__attribute__ ((__used__)) void \
496 debug (vec<T, va_gc> &ref) \
497 { \
498 debug_helper <T> (ref); \
499 } \
500 DEBUG_FUNCTION__attribute__ ((__used__)) void \
501 debug (vec<T, va_gc> *ptr) \
502 { \
503 if (ptr) \
504 debug (*ptr); \
505 else \
506 fprintf (stderrstderr, "<nil>\n"); \
507 }
508
509/* Default-construct N elements in DST. */
510
511template <typename T>
512inline void
513vec_default_construct (T *dst, unsigned n)
514{
515#ifdef BROKEN_VALUE_INITIALIZATION
516 /* Versions of GCC before 4.4 sometimes leave certain objects
517 uninitialized when value initialized, though if the type has
518 user defined default ctor, that ctor is invoked. As a workaround
519 perform clearing first and then the value initialization, which
520 fixes the case when value initialization doesn't initialize due to
521 the bugs and should initialize to all zeros, but still allows
522 vectors for types with user defined default ctor that initializes
523 some or all elements to non-zero. If T has no user defined
524 default ctor and some non-static data members have user defined
525 default ctors that initialize to non-zero the workaround will
526 still not work properly; in that case we just need to provide
527 user defined default ctor. */
528 memset (dst, '\0', sizeof (T) * n);
529#endif
530 for ( ; n; ++dst, --n)
531 ::new (static_cast<void*>(dst)) T ();
532}
533
534/* Copy-construct N elements in DST from *SRC. */
535
536template <typename T>
537inline void
538vec_copy_construct (T *dst, const T *src, unsigned n)
539{
540 for ( ; n; ++dst, ++src, --n)
541 ::new (static_cast<void*>(dst)) T (*src);
542}
543
544/* Type to provide zero-initialized values for vec<T, A, L>. This is
545 used to provide nil initializers for vec instances. Since vec must
546 be a trivially copyable type that can be copied by memcpy and zeroed
547 out by memset, it must have defaulted default and copy ctor and copy
548 assignment. To initialize a vec either use value initialization
549 (e.g., vec() or vec v{ };) or assign it the value vNULL. This isn't
550 needed for file-scope and function-local static vectors, which are
551 zero-initialized by default. */
552struct vnull { };
553constexpr vnull vNULL{ };
554
555
556/* Embeddable vector. These vectors are suitable to be embedded
557 in other data structures so that they can be pre-allocated in a
558 contiguous memory block.
559
560 Embeddable vectors are implemented using the trailing array idiom,
561 thus they are not resizeable without changing the address of the
562 vector object itself. This means you cannot have variables or
563 fields of embeddable vector type -- always use a pointer to a
564 vector. The one exception is the final field of a structure, which
565 could be a vector type.
566
567 You will have to use the embedded_size & embedded_init calls to
568 create such objects, and they will not be resizeable (so the 'safe'
569 allocation variants are not available).
570
571 Properties:
572
573 - The whole vector and control data are allocated in a single
574 contiguous block. It uses the trailing-vector idiom, so
575 allocation must reserve enough space for all the elements
576 in the vector plus its control data.
577 - The vector cannot be re-allocated.
578 - The vector cannot grow nor shrink.
579 - No indirections needed for access/manipulation.
580 - It requires 2 words of storage (prior to vector allocation). */
581
582template<typename T, typename A>
583struct GTY((user)) vec<T, A, vl_embed>
584{
585public:
586 unsigned allocated (void) const { return m_vecpfx.m_alloc; }
587 unsigned length (void) const { return m_vecpfx.m_num; }
588 bool is_empty (void) const { return m_vecpfx.m_num == 0; }
589 T *address (void) { return m_vecdata; }
590 const T *address (void) const { return m_vecdata; }
591 T *begin () { return address (); }
592 const T *begin () const { return address (); }
593 T *end () { return address () + length (); }
594 const T *end () const { return address () + length (); }
595 const T &operator[] (unsigned) const;
596 T &operator[] (unsigned);
597 T &last (void);
598 bool space (unsigned) const;
599 bool iterate (unsigned, T *) const;
600 bool iterate (unsigned, T **) const;
601 vec *copy (ALONE_CXX_MEM_STAT_INFO) const;
602 void splice (const vec &);
603 void splice (const vec *src);
604 T *quick_push (const T &);
605 T &pop (void);
606 void truncate (unsigned);
607 void quick_insert (unsigned, const T &);
608 void ordered_remove (unsigned);
609 void unordered_remove (unsigned);
610 void block_remove (unsigned, unsigned);
611 void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *));
612 void sort (int (*) (const void *, const void *, void *), void *);
613 void stablesort (int (*) (const void *, const void *, void *), void *);
614 T *bsearch (const void *key, int (*compar)(const void *, const void *));
615 T *bsearch (const void *key,
616 int (*compar)(const void *, const void *, void *), void *);
617 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
618 bool contains (const T &search) const;
619 static size_t embedded_size (unsigned);
620 void embedded_init (unsigned, unsigned = 0, unsigned = 0);
621 void quick_grow (unsigned len);
622 void quick_grow_cleared (unsigned len);
623
624 /* vec class can access our internal data and functions. */
625 template <typename, typename, typename> friend struct vec;
626
627 /* The allocator types also need access to our internals. */
628 friend struct va_gc;
629 friend struct va_gc_atomic;
630 friend struct va_heap;
631
632 /* FIXME - These fields should be private, but we need to cater to
633 compilers that have stricter notions of PODness for types. */
634 vec_prefix m_vecpfx;
635 T m_vecdata[1];
636};
637
638
639/* Convenience wrapper functions to use when dealing with pointers to
640 embedded vectors. Some functionality for these vectors must be
641 provided via free functions for these reasons:
642
643 1- The pointer may be NULL (e.g., before initial allocation).
644
645 2- When the vector needs to grow, it must be reallocated, so
646 the pointer will change its value.
647
648 Because of limitations with the current GC machinery, all vectors
649 in GC memory *must* be pointers. */
650
651
652/* If V contains no room for NELEMS elements, return false. Otherwise,
653 return true. */
654template<typename T, typename A>
655inline bool
656vec_safe_space (const vec<T, A, vl_embed> *v, unsigned nelems)
657{
658 return v ? v->space (nelems) : nelems == 0;
659}
660
661
662/* If V is NULL, return 0. Otherwise, return V->length(). */
663template<typename T, typename A>
664inline unsigned
665vec_safe_length (const vec<T, A, vl_embed> *v)
666{
667 return v ? v->length () : 0;
668}
669
670
671/* If V is NULL, return NULL. Otherwise, return V->address(). */
672template<typename T, typename A>
673inline T *
674vec_safe_address (vec<T, A, vl_embed> *v)
675{
676 return v ? v->address () : NULL__null;
677}
678
679
680/* If V is NULL, return true. Otherwise, return V->is_empty(). */
681template<typename T, typename A>
682inline bool
683vec_safe_is_empty (vec<T, A, vl_embed> *v)
684{
685 return v ? v->is_empty () : true;
686}
687
688/* If V does not have space for NELEMS elements, call
689 V->reserve(NELEMS, EXACT). */
690template<typename T, typename A>
691inline bool
692vec_safe_reserve (vec<T, A, vl_embed> *&v, unsigned nelems, bool exact = false
693 CXX_MEM_STAT_INFO)
694{
695 bool extend = nelems
10.1
'nelems' is 1
10.1
'nelems' is 1
? !vec_safe_space (v, nelems) : false;
11
'?' condition is true
12
Assuming the condition is true
696 if (extend
12.1
'extend' is true
12.1
'extend' is true
)
13
Taking true branch
697 A::reserve (v, nelems, exact PASS_MEM_STAT);
14
Calling 'va_gc::reserve'
20
Returning from 'va_gc::reserve'
698 return extend;
699}
700
701template<typename T, typename A>
702inline bool
703vec_safe_reserve_exact (vec<T, A, vl_embed> *&v, unsigned nelems
704 CXX_MEM_STAT_INFO)
705{
706 return vec_safe_reserve (v, nelems, true PASS_MEM_STAT);
707}
708
709
710/* Allocate GC memory for V with space for NELEMS slots. If NELEMS
711 is 0, V is initialized to NULL. */
712
713template<typename T, typename A>
714inline void
715vec_alloc (vec<T, A, vl_embed> *&v, unsigned nelems CXX_MEM_STAT_INFO)
716{
717 v = NULL__null;
718 vec_safe_reserve (v, nelems, false PASS_MEM_STAT);
719}
720
721
722/* Free the GC memory allocated by vector V and set it to NULL. */
723
724template<typename T, typename A>
725inline void
726vec_free (vec<T, A, vl_embed> *&v)
727{
728 A::release (v);
729}
730
731
732/* Grow V to length LEN. Allocate it, if necessary. */
733template<typename T, typename A>
734inline void
735vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
736 bool exact = false CXX_MEM_STAT_INFO)
737{
738 unsigned oldlen = vec_safe_length (v);
739 gcc_checking_assert (len >= oldlen)((void)(!(len >= oldlen) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 739, __FUNCTION__), 0 : 0))
;
740 vec_safe_reserve (v, len - oldlen, exact PASS_MEM_STAT);
741 v->quick_grow (len);
742}
743
744
745/* If V is NULL, allocate it. Call V->safe_grow_cleared(LEN). */
746template<typename T, typename A>
747inline void
748vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
749 bool exact = false CXX_MEM_STAT_INFO)
750{
751 unsigned oldlen = vec_safe_length (v);
752 vec_safe_grow (v, len, exact PASS_MEM_STAT);
753 vec_default_construct (v->address () + oldlen, len - oldlen);
754}
755
756
757/* Assume V is not NULL. */
758
759template<typename T>
760inline void
761vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
762 unsigned len, bool exact = false CXX_MEM_STAT_INFO)
763{
764 v->safe_grow_cleared (len, exact PASS_MEM_STAT);
765}
766
767/* If V does not have space for NELEMS elements, call
768 V->reserve(NELEMS, EXACT). */
769
770template<typename T>
771inline bool
772vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false
773 CXX_MEM_STAT_INFO)
774{
775 return v->reserve (nelems, exact);
776}
777
778
779/* If V is NULL return false, otherwise return V->iterate(IX, PTR). */
780template<typename T, typename A>
781inline bool
782vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T **ptr)
783{
784 if (v)
785 return v->iterate (ix, ptr);
786 else
787 {
788 *ptr = 0;
789 return false;
790 }
791}
792
793template<typename T, typename A>
794inline bool
795vec_safe_iterate (const vec<T, A, vl_embed> *v, unsigned ix, T *ptr)
796{
797 if (v)
798 return v->iterate (ix, ptr);
799 else
800 {
801 *ptr = 0;
802 return false;
803 }
804}
805
806
807/* If V has no room for one more element, reallocate it. Then call
808 V->quick_push(OBJ). */
809template<typename T, typename A>
810inline T *
811vec_safe_push (vec<T, A, vl_embed> *&v, const T &obj CXX_MEM_STAT_INFO)
812{
813 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
10
Calling 'vec_safe_reserve<tree_node *, va_gc>'
21
Returning from 'vec_safe_reserve<tree_node *, va_gc>'
814 return v->quick_push (obj);
22
Called C++ object pointer is null
815}
816
817
818/* if V has no room for one more element, reallocate it. Then call
819 V->quick_insert(IX, OBJ). */
820template<typename T, typename A>
821inline void
822vec_safe_insert (vec<T, A, vl_embed> *&v, unsigned ix, const T &obj
823 CXX_MEM_STAT_INFO)
824{
825 vec_safe_reserve (v, 1, false PASS_MEM_STAT);
826 v->quick_insert (ix, obj);
827}
828
829
830/* If V is NULL, do nothing. Otherwise, call V->truncate(SIZE). */
831template<typename T, typename A>
832inline void
833vec_safe_truncate (vec<T, A, vl_embed> *v, unsigned size)
834{
835 if (v)
836 v->truncate (size);
837}
838
839
840/* If SRC is not NULL, return a pointer to a copy of it. */
841template<typename T, typename A>
842inline vec<T, A, vl_embed> *
843vec_safe_copy (vec<T, A, vl_embed> *src CXX_MEM_STAT_INFO)
844{
845 return src ? src->copy (ALONE_PASS_MEM_STAT) : NULL__null;
846}
847
848/* Copy the elements from SRC to the end of DST as if by memcpy.
849 Reallocate DST, if necessary. */
850template<typename T, typename A>
851inline void
852vec_safe_splice (vec<T, A, vl_embed> *&dst, const vec<T, A, vl_embed> *src
853 CXX_MEM_STAT_INFO)
854{
855 unsigned src_len = vec_safe_length (src);
856 if (src_len)
857 {
858 vec_safe_reserve_exact (dst, vec_safe_length (dst) + src_len
859 PASS_MEM_STAT);
860 dst->splice (*src);
861 }
862}
863
864/* Return true if SEARCH is an element of V. Note that this is O(N) in the
865 size of the vector and so should be used with care. */
866
867template<typename T, typename A>
868inline bool
869vec_safe_contains (vec<T, A, vl_embed> *v, const T &search)
870{
871 return v ? v->contains (search) : false;
872}
873
874/* Index into vector. Return the IX'th element. IX must be in the
875 domain of the vector. */
876
877template<typename T, typename A>
878inline const T &
879vec<T, A, vl_embed>::operator[] (unsigned ix) const
880{
881 gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 881, __FUNCTION__), 0 : 0))
;
882 return m_vecdata[ix];
883}
884
885template<typename T, typename A>
886inline T &
887vec<T, A, vl_embed>::operator[] (unsigned ix)
888{
889 gcc_checking_assert (ix < m_vecpfx.m_num)((void)(!(ix < m_vecpfx.m_num) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 889, __FUNCTION__), 0 : 0))
;
890 return m_vecdata[ix];
891}
892
893
894/* Get the final element of the vector, which must not be empty. */
895
896template<typename T, typename A>
897inline T &
898vec<T, A, vl_embed>::last (void)
899{
900 gcc_checking_assert (m_vecpfx.m_num > 0)((void)(!(m_vecpfx.m_num > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 900, __FUNCTION__), 0 : 0))
;
901 return (*this)[m_vecpfx.m_num - 1];
902}
903
904
905/* If this vector has space for NELEMS additional entries, return
906 true. You usually only need to use this if you are doing your
907 own vector reallocation, for instance on an embedded vector. This
908 returns true in exactly the same circumstances that vec::reserve
909 will. */
910
911template<typename T, typename A>
912inline bool
913vec<T, A, vl_embed>::space (unsigned nelems) const
914{
915 return m_vecpfx.m_alloc - m_vecpfx.m_num >= nelems;
916}
917
918
919/* Return iteration condition and update PTR to point to the IX'th
920 element of this vector. Use this to iterate over the elements of a
921 vector as follows,
922
923 for (ix = 0; vec<T, A>::iterate (v, ix, &ptr); ix++)
924 continue; */
925
926template<typename T, typename A>
927inline bool
928vec<T, A, vl_embed>::iterate (unsigned ix, T *ptr) const
929{
930 if (ix < m_vecpfx.m_num)
931 {
932 *ptr = m_vecdata[ix];
933 return true;
934 }
935 else
936 {
937 *ptr = 0;
938 return false;
939 }
940}
941
942
943/* Return iteration condition and update *PTR to point to the
944 IX'th element of this vector. Use this to iterate over the
945 elements of a vector as follows,
946
947 for (ix = 0; v->iterate (ix, &ptr); ix++)
948 continue;
949
950 This variant is for vectors of objects. */
951
952template<typename T, typename A>
953inline bool
954vec<T, A, vl_embed>::iterate (unsigned ix, T **ptr) const
955{
956 if (ix < m_vecpfx.m_num)
957 {
958 *ptr = CONST_CAST (T *, &m_vecdata[ix])(const_cast<T *> ((&m_vecdata[ix])));
959 return true;
960 }
961 else
962 {
963 *ptr = 0;
964 return false;
965 }
966}
967
968
969/* Return a pointer to a copy of this vector. */
970
971template<typename T, typename A>
972inline vec<T, A, vl_embed> *
973vec<T, A, vl_embed>::copy (ALONE_MEM_STAT_DECLvoid) const
974{
975 vec<T, A, vl_embed> *new_vec = NULL__null;
976 unsigned len = length ();
977 if (len)
978 {
979 vec_alloc (new_vec, len PASS_MEM_STAT);
980 new_vec->embedded_init (len, len);
981 vec_copy_construct (new_vec->address (), m_vecdata, len);
982 }
983 return new_vec;
984}
985
986
987/* Copy the elements from SRC to the end of this vector as if by memcpy.
988 The vector must have sufficient headroom available. */
989
990template<typename T, typename A>
991inline void
992vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> &src)
993{
994 unsigned len = src.length ();
995 if (len)
996 {
997 gcc_checking_assert (space (len))((void)(!(space (len)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 997, __FUNCTION__), 0 : 0))
;
998 vec_copy_construct (end (), src.address (), len);
999 m_vecpfx.m_num += len;
1000 }
1001}
1002
1003template<typename T, typename A>
1004inline void
1005vec<T, A, vl_embed>::splice (const vec<T, A, vl_embed> *src)
1006{
1007 if (src)
1008 splice (*src);
1009}
1010
1011
1012/* Push OBJ (a new element) onto the end of the vector. There must be
1013 sufficient space in the vector. Return a pointer to the slot
1014 where OBJ was inserted. */
1015
1016template<typename T, typename A>
1017inline T *
1018vec<T, A, vl_embed>::quick_push (const T &obj)
1019{
1020 gcc_checking_assert (space (1))((void)(!(space (1)) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1020, __FUNCTION__), 0 : 0))
;
1021 T *slot = &m_vecdata[m_vecpfx.m_num++];
1022 *slot = obj;
1023 return slot;
1024}
1025
1026
1027/* Pop and return the last element off the end of the vector. */
1028
1029template<typename T, typename A>
1030inline T &
1031vec<T, A, vl_embed>::pop (void)
1032{
1033 gcc_checking_assert (length () > 0)((void)(!(length () > 0) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1033, __FUNCTION__), 0 : 0))
;
1034 return m_vecdata[--m_vecpfx.m_num];
1035}
1036
1037
1038/* Set the length of the vector to SIZE. The new length must be less
1039 than or equal to the current length. This is an O(1) operation. */
1040
1041template<typename T, typename A>
1042inline void
1043vec<T, A, vl_embed>::truncate (unsigned size)
1044{
1045 gcc_checking_assert (length () >= size)((void)(!(length () >= size) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1045, __FUNCTION__), 0 : 0))
;
1046 m_vecpfx.m_num = size;
1047}
1048
1049
1050/* Insert an element, OBJ, at the IXth position of this vector. There
1051 must be sufficient space. */
1052
1053template<typename T, typename A>
1054inline void
1055vec<T, A, vl_embed>::quick_insert (unsigned ix, const T &obj)
1056{
1057 gcc_checking_assert (length () < allocated ())((void)(!(length () < allocated ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1057, __FUNCTION__), 0 : 0))
;
1058 gcc_checking_assert (ix <= length ())((void)(!(ix <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1058, __FUNCTION__), 0 : 0))
;
1059 T *slot = &m_vecdata[ix];
1060 memmove (slot + 1, slot, (m_vecpfx.m_num++ - ix) * sizeof (T));
1061 *slot = obj;
1062}
1063
1064
1065/* Remove an element from the IXth position of this vector. Ordering of
1066 remaining elements is preserved. This is an O(N) operation due to
1067 memmove. */
1068
1069template<typename T, typename A>
1070inline void
1071vec<T, A, vl_embed>::ordered_remove (unsigned ix)
1072{
1073 gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1073, __FUNCTION__), 0 : 0))
;
1074 T *slot = &m_vecdata[ix];
1075 memmove (slot, slot + 1, (--m_vecpfx.m_num - ix) * sizeof (T));
1076}
1077
1078
1079/* Remove elements in [START, END) from VEC for which COND holds. Ordering of
1080 remaining elements is preserved. This is an O(N) operation. */
1081
1082#define VEC_ORDERED_REMOVE_IF_FROM_TO(vec, read_index, write_index, \{ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1083, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (start); read_index < (end); ++read_index) { elem_ptr =
&(vec)[read_index]; bool remove_p = (cond); if (remove_p
) continue; if (read_index != write_index) (vec)[write_index]
= (vec)[read_index]; write_index++; } if (read_index - write_index
> 0) (vec).block_remove (write_index, read_index - write_index
); }
1083 elem_ptr, start, end, cond){ ((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1083, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (start); read_index < (end); ++read_index) { elem_ptr =
&(vec)[read_index]; bool remove_p = (cond); if (remove_p
) continue; if (read_index != write_index) (vec)[write_index]
= (vec)[read_index]; write_index++; } if (read_index - write_index
> 0) (vec).block_remove (write_index, read_index - write_index
); }
\
1084 { \
1085 gcc_assert ((end) <= (vec).length ())((void)(!((end) <= (vec).length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1085, __FUNCTION__), 0 : 0))
; \
1086 for (read_index = write_index = (start); read_index < (end); \
1087 ++read_index) \
1088 { \
1089 elem_ptr = &(vec)[read_index]; \
1090 bool remove_p = (cond); \
1091 if (remove_p) \
1092 continue; \
1093 \
1094 if (read_index != write_index) \
1095 (vec)[write_index] = (vec)[read_index]; \
1096 \
1097 write_index++; \
1098 } \
1099 \
1100 if (read_index - write_index > 0) \
1101 (vec).block_remove (write_index, read_index - write_index); \
1102 }
1103
1104
1105/* Remove elements from VEC for which COND holds. Ordering of remaining
1106 elements is preserved. This is an O(N) operation. */
1107
1108#define VEC_ORDERED_REMOVE_IF(vec, read_index, write_index, elem_ptr, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1109, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1109 cond){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1109, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
\
1110 VEC_ORDERED_REMOVE_IF_FROM_TO ((vec), read_index, write_index, \{ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1111, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1111 elem_ptr, 0, (vec).length (), (cond)){ ((void)(!(((vec).length ()) <= ((vec)).length ()) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1111, __FUNCTION__), 0 : 0)); for (read_index = write_index
= (0); read_index < ((vec).length ()); ++read_index) { elem_ptr
= &((vec))[read_index]; bool remove_p = ((cond)); if (remove_p
) continue; if (read_index != write_index) ((vec))[write_index
] = ((vec))[read_index]; write_index++; } if (read_index - write_index
> 0) ((vec)).block_remove (write_index, read_index - write_index
); }
1112
1113/* Remove an element from the IXth position of this vector. Ordering of
1114 remaining elements is destroyed. This is an O(1) operation. */
1115
1116template<typename T, typename A>
1117inline void
1118vec<T, A, vl_embed>::unordered_remove (unsigned ix)
1119{
1120 gcc_checking_assert (ix < length ())((void)(!(ix < length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1120, __FUNCTION__), 0 : 0))
;
1121 m_vecdata[ix] = m_vecdata[--m_vecpfx.m_num];
1122}
1123
1124
1125/* Remove LEN elements starting at the IXth. Ordering is retained.
1126 This is an O(N) operation due to memmove. */
1127
1128template<typename T, typename A>
1129inline void
1130vec<T, A, vl_embed>::block_remove (unsigned ix, unsigned len)
1131{
1132 gcc_checking_assert (ix + len <= length ())((void)(!(ix + len <= length ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1132, __FUNCTION__), 0 : 0))
;
1133 T *slot = &m_vecdata[ix];
1134 m_vecpfx.m_num -= len;
1135 memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T));
1136}
1137
1138
1139/* Sort the contents of this vector with qsort. CMP is the comparison
1140 function to pass to qsort. */
1141
1142template<typename T, typename A>
1143inline void
1144vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))qsort (int (*cmp) (const void *, const void *))
1145{
1146 if (length () > 1)
1147 gcc_qsort (address (), length (), sizeof (T), cmp);
1148}
1149
1150/* Sort the contents of this vector with qsort. CMP is the comparison
1151 function to pass to qsort. */
1152
1153template<typename T, typename A>
1154inline void
1155vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *),
1156 void *data)
1157{
1158 if (length () > 1)
1159 gcc_sort_r (address (), length (), sizeof (T), cmp, data);
1160}
1161
1162/* Sort the contents of this vector with gcc_stablesort_r. CMP is the
1163 comparison function to pass to qsort. */
1164
1165template<typename T, typename A>
1166inline void
1167vec<T, A, vl_embed>::stablesort (int (*cmp) (const void *, const void *,
1168 void *), void *data)
1169{
1170 if (length () > 1)
1171 gcc_stablesort_r (address (), length (), sizeof (T), cmp, data);
1172}
1173
1174/* Search the contents of the sorted vector with a binary search.
1175 CMP is the comparison function to pass to bsearch. */
1176
1177template<typename T, typename A>
1178inline T *
1179vec<T, A, vl_embed>::bsearch (const void *key,
1180 int (*compar) (const void *, const void *))
1181{
1182 const void *base = this->address ();
1183 size_t nmemb = this->length ();
1184 size_t size = sizeof (T);
1185 /* The following is a copy of glibc stdlib-bsearch.h. */
1186 size_t l, u, idx;
1187 const void *p;
1188 int comparison;
1189
1190 l = 0;
1191 u = nmemb;
1192 while (l < u)
1193 {
1194 idx = (l + u) / 2;
1195 p = (const void *) (((const char *) base) + (idx * size));
1196 comparison = (*compar) (key, p);
1197 if (comparison < 0)
1198 u = idx;
1199 else if (comparison > 0)
1200 l = idx + 1;
1201 else
1202 return (T *)const_cast<void *>(p);
1203 }
1204
1205 return NULL__null;
1206}
1207
1208/* Search the contents of the sorted vector with a binary search.
1209 CMP is the comparison function to pass to bsearch. */
1210
1211template<typename T, typename A>
1212inline T *
1213vec<T, A, vl_embed>::bsearch (const void *key,
1214 int (*compar) (const void *, const void *,
1215 void *), void *data)
1216{
1217 const void *base = this->address ();
1218 size_t nmemb = this->length ();
1219 size_t size = sizeof (T);
1220 /* The following is a copy of glibc stdlib-bsearch.h. */
1221 size_t l, u, idx;
1222 const void *p;
1223 int comparison;
1224
1225 l = 0;
1226 u = nmemb;
1227 while (l < u)
1228 {
1229 idx = (l + u) / 2;
1230 p = (const void *) (((const char *) base) + (idx * size));
1231 comparison = (*compar) (key, p, data);
1232 if (comparison < 0)
1233 u = idx;
1234 else if (comparison > 0)
1235 l = idx + 1;
1236 else
1237 return (T *)const_cast<void *>(p);
1238 }
1239
1240 return NULL__null;
1241}
1242
1243/* Return true if SEARCH is an element of V. Note that this is O(N) in the
1244 size of the vector and so should be used with care. */
1245
1246template<typename T, typename A>
1247inline bool
1248vec<T, A, vl_embed>::contains (const T &search) const
1249{
1250 unsigned int len = length ();
1251 for (unsigned int i = 0; i < len; i++)
1252 if ((*this)[i] == search)
1253 return true;
1254
1255 return false;
1256}
1257
1258/* Find and return the first position in which OBJ could be inserted
1259 without changing the ordering of this vector. LESSTHAN is a
1260 function that returns true if the first argument is strictly less
1261 than the second. */
1262
1263template<typename T, typename A>
1264unsigned
1265vec<T, A, vl_embed>::lower_bound (T obj, bool (*lessthan)(const T &, const T &))
1266 const
1267{
1268 unsigned int len = length ();
1269 unsigned int half, middle;
1270 unsigned int first = 0;
1271 while (len > 0)
1272 {
1273 half = len / 2;
1274 middle = first;
1275 middle += half;
1276 T middle_elem = (*this)[middle];
1277 if (lessthan (middle_elem, obj))
1278 {
1279 first = middle;
1280 ++first;
1281 len = len - half - 1;
1282 }
1283 else
1284 len = half;
1285 }
1286 return first;
1287}
1288
1289
1290/* Return the number of bytes needed to embed an instance of an
1291 embeddable vec inside another data structure.
1292
1293 Use these methods to determine the required size and initialization
1294 of a vector V of type T embedded within another structure (as the
1295 final member):
1296
1297 size_t vec<T, A, vl_embed>::embedded_size (unsigned alloc);
1298 void v->embedded_init (unsigned alloc, unsigned num);
1299
1300 These allow the caller to perform the memory allocation. */
1301
1302template<typename T, typename A>
1303inline size_t
1304vec<T, A, vl_embed>::embedded_size (unsigned alloc)
1305{
1306 struct alignas (T) U { char data[sizeof (T)]; };
1307 typedef vec<U, A, vl_embed> vec_embedded;
1308 typedef typename std::conditional<std::is_standard_layout<T>::value,
1309 vec, vec_embedded>::type vec_stdlayout;
1310 static_assert (sizeof (vec_stdlayout) == sizeof (vec), "");
1311 static_assert (alignof (vec_stdlayout) == alignof (vec), "");
1312 return offsetof (vec_stdlayout, m_vecdata)__builtin_offsetof(vec_stdlayout, m_vecdata) + alloc * sizeof (T);
1313}
1314
1315
1316/* Initialize the vector to contain room for ALLOC elements and
1317 NUM active elements. */
1318
1319template<typename T, typename A>
1320inline void
1321vec<T, A, vl_embed>::embedded_init (unsigned alloc, unsigned num, unsigned aut)
1322{
1323 m_vecpfx.m_alloc = alloc;
1324 m_vecpfx.m_using_auto_storage = aut;
1325 m_vecpfx.m_num = num;
1326}
1327
1328
1329/* Grow the vector to a specific length. LEN must be as long or longer than
1330 the current length. The new elements are uninitialized. */
1331
1332template<typename T, typename A>
1333inline void
1334vec<T, A, vl_embed>::quick_grow (unsigned len)
1335{
1336 gcc_checking_assert (length () <= len && len <= m_vecpfx.m_alloc)((void)(!(length () <= len && len <= m_vecpfx.m_alloc
) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1336, __FUNCTION__), 0 : 0))
;
1337 m_vecpfx.m_num = len;
1338}
1339
1340
1341/* Grow the vector to a specific length. LEN must be as long or longer than
1342 the current length. The new elements are initialized to zero. */
1343
1344template<typename T, typename A>
1345inline void
1346vec<T, A, vl_embed>::quick_grow_cleared (unsigned len)
1347{
1348 unsigned oldlen = length ();
1349 size_t growby = len - oldlen;
1350 quick_grow (len);
1351 if (growby != 0)
1352 vec_default_construct (address () + oldlen, growby);
1353}
1354
1355/* Garbage collection support for vec<T, A, vl_embed>. */
1356
1357template<typename T>
1358void
1359gt_ggc_mx (vec<T, va_gc> *v)
1360{
1361 extern void gt_ggc_mx (T &);
1362 for (unsigned i = 0; i < v->length (); i++)
1363 gt_ggc_mx ((*v)[i]);
1364}
1365
1366template<typename T>
1367void
1368gt_ggc_mx (vec<T, va_gc_atomic, vl_embed> *v ATTRIBUTE_UNUSED__attribute__ ((__unused__)))
1369{
1370 /* Nothing to do. Vectors of atomic types wrt GC do not need to
1371 be traversed. */
1372}
1373
1374
1375/* PCH support for vec<T, A, vl_embed>. */
1376
1377template<typename T, typename A>
1378void
1379gt_pch_nx (vec<T, A, vl_embed> *v)
1380{
1381 extern void gt_pch_nx (T &);
1382 for (unsigned i = 0; i < v->length (); i++)
1383 gt_pch_nx ((*v)[i]);
1384}
1385
1386template<typename T, typename A>
1387void
1388gt_pch_nx (vec<T *, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1389{
1390 for (unsigned i = 0; i < v->length (); i++)
1391 op (&((*v)[i]), cookie);
1392}
1393
1394template<typename T, typename A>
1395void
1396gt_pch_nx (vec<T, A, vl_embed> *v, gt_pointer_operator op, void *cookie)
1397{
1398 extern void gt_pch_nx (T *, gt_pointer_operator, void *);
1399 for (unsigned i = 0; i < v->length (); i++)
1400 gt_pch_nx (&((*v)[i]), op, cookie);
1401}
1402
1403
1404/* Space efficient vector. These vectors can grow dynamically and are
1405 allocated together with their control data. They are suited to be
1406 included in data structures. Prior to initial allocation, they
1407 only take a single word of storage.
1408
1409 These vectors are implemented as a pointer to an embeddable vector.
1410 The semantics allow for this pointer to be NULL to represent empty
1411 vectors. This way, empty vectors occupy minimal space in the
1412 structure containing them.
1413
1414 Properties:
1415
1416 - The whole vector and control data are allocated in a single
1417 contiguous block.
1418 - The whole vector may be re-allocated.
1419 - Vector data may grow and shrink.
1420 - Access and manipulation requires a pointer test and
1421 indirection.
1422 - It requires 1 word of storage (prior to vector allocation).
1423
1424
1425 Limitations:
1426
1427 These vectors must be PODs because they are stored in unions.
1428 (http://en.wikipedia.org/wiki/Plain_old_data_structures).
1429 As long as we use C++03, we cannot have constructors nor
1430 destructors in classes that are stored in unions. */
1431
1432template<typename T, size_t N = 0>
1433class auto_vec;
1434
1435template<typename T>
1436struct vec<T, va_heap, vl_ptr>
1437{
1438public:
1439 /* Default ctors to ensure triviality. Use value-initialization
1440 (e.g., vec() or vec v{ };) or vNULL to create a zero-initialized
1441 instance. */
1442 vec () = default;
1443 vec (const vec &) = default;
1444 /* Initialization from the generic vNULL. */
1445 vec (vnull): m_vec () { }
1446 /* Same as default ctor: vec storage must be released manually. */
1447 ~vec () = default;
1448
1449 /* Defaulted same as copy ctor. */
1450 vec& operator= (const vec &) = default;
1451
1452 /* Prevent implicit conversion from auto_vec. Use auto_vec::to_vec()
1453 instead. */
1454 template <size_t N>
1455 vec (auto_vec<T, N> &) = delete;
1456
1457 template <size_t N>
1458 void operator= (auto_vec<T, N> &) = delete;
1459
1460 /* Memory allocation and deallocation for the embedded vector.
1461 Needed because we cannot have proper ctors/dtors defined. */
1462 void create (unsigned nelems CXX_MEM_STAT_INFO);
1463 void release (void);
1464
1465 /* Vector operations. */
1466 bool exists (void) const
1467 { return m_vec != NULL__null; }
1468
1469 bool is_empty (void) const
1470 { return m_vec ? m_vec->is_empty () : true; }
1471
1472 unsigned length (void) const
1473 { return m_vec ? m_vec->length () : 0; }
1474
1475 T *address (void)
1476 { return m_vec ? m_vec->m_vecdata : NULL__null; }
1477
1478 const T *address (void) const
1479 { return m_vec ? m_vec->m_vecdata : NULL__null; }
1480
1481 T *begin () { return address (); }
1482 const T *begin () const { return address (); }
1483 T *end () { return begin () + length (); }
1484 const T *end () const { return begin () + length (); }
1485 const T &operator[] (unsigned ix) const
1486 { return (*m_vec)[ix]; }
1487
1488 bool operator!=(const vec &other) const
1489 { return !(*this == other); }
1490
1491 bool operator==(const vec &other) const
1492 { return address () == other.address (); }
1493
1494 T &operator[] (unsigned ix)
1495 { return (*m_vec)[ix]; }
1496
1497 T &last (void)
1498 { return m_vec->last (); }
1499
1500 bool space (int nelems) const
1501 { return m_vec ? m_vec->space (nelems) : nelems == 0; }
1502
1503 bool iterate (unsigned ix, T *p) const;
1504 bool iterate (unsigned ix, T **p) const;
1505 vec copy (ALONE_CXX_MEM_STAT_INFO) const;
1506 bool reserve (unsigned, bool = false CXX_MEM_STAT_INFO);
1507 bool reserve_exact (unsigned CXX_MEM_STAT_INFO);
1508 void splice (const vec &);
1509 void safe_splice (const vec & CXX_MEM_STAT_INFO);
1510 T *quick_push (const T &);
1511 T *safe_push (const T &CXX_MEM_STAT_INFO);
1512 T &pop (void);
1513 void truncate (unsigned);
1514 void safe_grow (unsigned, bool = false CXX_MEM_STAT_INFO);
1515 void safe_grow_cleared (unsigned, bool = false CXX_MEM_STAT_INFO);
1516 void quick_grow (unsigned);
1517 void quick_grow_cleared (unsigned);
1518 void quick_insert (unsigned, const T &);
1519 void safe_insert (unsigned, const T & CXX_MEM_STAT_INFO);
1520 void ordered_remove (unsigned);
1521 void unordered_remove (unsigned);
1522 void block_remove (unsigned, unsigned);
1523 void qsort (int (*) (const void *, const void *))qsort (int (*) (const void *, const void *));
1524 void sort (int (*) (const void *, const void *, void *), void *);
1525 void stablesort (int (*) (const void *, const void *, void *), void *);
1526 T *bsearch (const void *key, int (*compar)(const void *, const void *));
1527 T *bsearch (const void *key,
1528 int (*compar)(const void *, const void *, void *), void *);
1529 unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
1530 bool contains (const T &search) const;
1531 void reverse (void);
1532
1533 bool using_auto_storage () const;
1534
1535 /* FIXME - This field should be private, but we need to cater to
1536 compilers that have stricter notions of PODness for types. */
1537 vec<T, va_heap, vl_embed> *m_vec;
1538};
1539
1540
1541/* auto_vec is a subclass of vec that automatically manages creating and
1542 releasing the internal vector. If N is non zero then it has N elements of
1543 internal storage. The default is no internal storage, and you probably only
1544 want to ask for internal storage for vectors on the stack because if the
1545 size of the vector is larger than the internal storage that space is wasted.
1546 */
1547template<typename T, size_t N /* = 0 */>
1548class auto_vec : public vec<T, va_heap>
1549{
1550public:
1551 auto_vec ()
1552 {
1553 m_auto.embedded_init (MAX (N, 2)((N) > (2) ? (N) : (2)), 0, 1);
1554 this->m_vec = &m_auto;
1555 }
1556
1557 auto_vec (size_t s CXX_MEM_STAT_INFO)
1558 {
1559 if (s > N)
1560 {
1561 this->create (s PASS_MEM_STAT);
1562 return;
1563 }
1564
1565 m_auto.embedded_init (MAX (N, 2)((N) > (2) ? (N) : (2)), 0, 1);
1566 this->m_vec = &m_auto;
1567 }
1568
1569 ~auto_vec ()
1570 {
1571 this->release ();
1572 }
1573
1574 /* Explicitly convert to the base class. There is no conversion
1575 from a const auto_vec because a copy of the returned vec can
1576 be used to modify *THIS.
1577 This is a legacy function not to be used in new code. */
1578 vec<T, va_heap> to_vec_legacy () {
1579 return *static_cast<vec<T, va_heap> *>(this);
1580 }
1581
1582private:
1583 vec<T, va_heap, vl_embed> m_auto;
1584 T m_data[MAX (N - 1, 1)((N - 1) > (1) ? (N - 1) : (1))];
1585};
1586
1587/* auto_vec is a sub class of vec whose storage is released when it is
1588 destroyed. */
1589template<typename T>
1590class auto_vec<T, 0> : public vec<T, va_heap>
1591{
1592public:
1593 auto_vec () { this->m_vec = NULL__null; }
1594 auto_vec (size_t n CXX_MEM_STAT_INFO) { this->create (n PASS_MEM_STAT); }
1595 ~auto_vec () { this->release (); }
1596
1597 auto_vec (vec<T, va_heap>&& r)
1598 {
1599 gcc_assert (!r.using_auto_storage ())((void)(!(!r.using_auto_storage ()) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/vec.h"
, 1599, __FUNCTION__), 0 : 0))