Bug Summary

File:build/gcc/cp/constraint.cc
Warning:line 1959, column 10
The left operand of '!=' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

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