Bug Summary

File:build/gcc/cp/constraint.cc
Warning:line 1944, column 19
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

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