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