File: | build/gcc/cp/constraint.cc |
Warning: | line 1988, column 19 1st function call argument is an uninitialized 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 || !c2) | |||
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" |