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