]>
Commit | Line | Data |
---|---|---|
971e17ff | 1 | /* Processing rules for constraints. |
a5544970 | 2 | Copyright (C) 2013-2019 Free Software Foundation, Inc. |
971e17ff AS |
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" | |
f078dc7d | 25 | #include "timevar.h" |
971e17ff AS |
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 | /*--------------------------------------------------------------------------- | |
50 | Operations on constraints | |
51 | ---------------------------------------------------------------------------*/ | |
52 | ||
53 | /* Returns true if C is a constraint tree code. Note that ERROR_MARK | |
54 | is a valid constraint. */ | |
55 | ||
56 | static inline bool | |
57 | constraint_p (tree_code c) | |
58 | { | |
f078dc7d AS |
59 | return ((PRED_CONSTR <= c && c <= DISJ_CONSTR) |
60 | || c == EXPR_PACK_EXPANSION | |
61 | || c == ERROR_MARK); | |
971e17ff AS |
62 | } |
63 | ||
64 | /* Returns true if T is a constraint. Note that error_mark_node | |
65 | is a valid constraint. */ | |
66 | ||
67 | bool | |
68 | constraint_p (tree t) | |
69 | { | |
70 | return constraint_p (TREE_CODE (t)); | |
71 | } | |
72 | ||
971e17ff AS |
73 | /* Returns the conjunction of two constraints A and B. Note that |
74 | conjoining a non-null constraint with NULL_TREE is an identity | |
75 | operation. That is, for non-null A, | |
76 | ||
77 | conjoin_constraints(a, NULL_TREE) == a | |
78 | ||
79 | and | |
80 | ||
81 | conjoin_constraints (NULL_TREE, a) == a | |
82 | ||
83 | If both A and B are NULL_TREE, the result is also NULL_TREE. */ | |
84 | ||
85 | tree | |
86 | conjoin_constraints (tree a, tree b) | |
87 | { | |
88 | gcc_assert (a ? constraint_p (a) : true); | |
89 | gcc_assert (b ? constraint_p (b) : true); | |
90 | if (a) | |
91 | return b ? build_nt (CONJ_CONSTR, a, b) : a; | |
92 | else if (b) | |
93 | return b; | |
94 | else | |
95 | return NULL_TREE; | |
96 | } | |
97 | ||
98 | /* Transform the vector of expressions in the T into a conjunction | |
99 | of requirements. T must be a TREE_VEC. */ | |
100 | ||
101 | tree | |
102 | conjoin_constraints (tree t) | |
103 | { | |
104 | gcc_assert (TREE_CODE (t) == TREE_VEC); | |
105 | tree r = NULL_TREE; | |
106 | for (int i = 0; i < TREE_VEC_LENGTH (t); ++i) | |
107 | r = conjoin_constraints (r, TREE_VEC_ELT (t, i)); | |
108 | return r; | |
109 | } | |
110 | ||
111 | /* Returns true if T is a call expression to a function | |
112 | concept. */ | |
113 | ||
114 | bool | |
115 | function_concept_check_p (tree t) | |
116 | { | |
117 | gcc_assert (TREE_CODE (t) == CALL_EXPR); | |
118 | tree fn = CALL_EXPR_FN (t); | |
81fea426 | 119 | if (fn != NULL_TREE |
848bf88d | 120 | && TREE_CODE (fn) == TEMPLATE_ID_EXPR) |
971e17ff | 121 | { |
848bf88d | 122 | tree f1 = OVL_FIRST (TREE_OPERAND (fn, 0)); |
971e17ff AS |
123 | if (TREE_CODE (f1) == TEMPLATE_DECL |
124 | && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (f1))) | |
125 | return true; | |
126 | } | |
127 | return false; | |
128 | } | |
129 | ||
f078dc7d AS |
130 | /* Returns true if any of the arguments in the template |
131 | argument list is a wildcard or wildcard pack. */ | |
132 | ||
133 | bool | |
134 | contains_wildcard_p (tree args) | |
135 | { | |
136 | for (int i = 0; i < TREE_VEC_LENGTH (args); ++i) | |
137 | { | |
138 | tree arg = TREE_VEC_ELT (args, i); | |
139 | if (TREE_CODE (arg) == WILDCARD_DECL) | |
140 | return true; | |
141 | } | |
142 | return false; | |
143 | } | |
144 | ||
145 | /* Build a new call expression, but don't actually generate a | |
146 | new function call. We just want the tree, not the semantics. */ | |
147 | ||
148 | inline tree | |
149 | build_call_check (tree id) | |
150 | { | |
151 | ++processing_template_decl; | |
152 | vec<tree, va_gc> *fargs = make_tree_vector(); | |
153 | tree call = finish_call_expr (id, &fargs, false, false, tf_none); | |
154 | release_tree_vector (fargs); | |
155 | --processing_template_decl; | |
156 | return call; | |
157 | } | |
158 | ||
159 | /* Build an expression that will check a variable concept. If any | |
160 | argument contains a wildcard, don't try to finish the variable | |
161 | template because we can't substitute into a non-existent | |
162 | declaration. */ | |
163 | ||
164 | tree | |
165 | build_variable_check (tree id) | |
166 | { | |
167 | gcc_assert (TREE_CODE (id) == TEMPLATE_ID_EXPR); | |
168 | if (contains_wildcard_p (TREE_OPERAND (id, 1))) | |
169 | return id; | |
170 | ||
171 | ++processing_template_decl; | |
172 | tree var = finish_template_variable (id); | |
173 | --processing_template_decl; | |
174 | return var; | |
175 | } | |
176 | ||
971e17ff AS |
177 | /*--------------------------------------------------------------------------- |
178 | Resolution of qualified concept names | |
179 | ---------------------------------------------------------------------------*/ | |
180 | ||
181 | /* This facility is used to resolve constraint checks from | |
182 | requirement expressions. A constraint check is a call to | |
183 | a function template declared with the keyword 'concept'. | |
184 | ||
185 | The result of resolution is a pair (a TREE_LIST) whose value | |
186 | is the matched declaration, and whose purpose contains the | |
187 | coerced template arguments that can be substituted into the | |
188 | call. */ | |
189 | ||
190 | // Given an overload set OVL, try to find a unique definition that can be | |
191 | // instantiated by the template arguments ARGS. | |
192 | // | |
193 | // This function is not called for arbitrary call expressions. In particular, | |
194 | // the call expression must be written with explicit template arguments | |
195 | // and no function arguments. For example: | |
196 | // | |
197 | // f<T, U>() | |
198 | // | |
199 | // If a single match is found, this returns a TREE_LIST whose VALUE | |
200 | // is the constraint function (not the template), and its PURPOSE is | |
201 | // the complete set of arguments substituted into the parameter list. | |
202 | static tree | |
203 | resolve_constraint_check (tree ovl, tree args) | |
204 | { | |
f078dc7d | 205 | int nerrs = 0; |
971e17ff | 206 | tree cands = NULL_TREE; |
3f267553 | 207 | for (lkp_iterator iter (ovl); iter; ++iter) |
971e17ff AS |
208 | { |
209 | // Get the next template overload. | |
3f267553 | 210 | tree tmpl = *iter; |
971e17ff AS |
211 | if (TREE_CODE (tmpl) != TEMPLATE_DECL) |
212 | continue; | |
213 | ||
214 | // Don't try to deduce checks for non-concepts. We often | |
215 | // end up trying to resolve constraints in functional casts | |
216 | // as part of a postfix-expression. We can save time and | |
217 | // headaches by not instantiating those declarations. | |
218 | // | |
219 | // NOTE: This masks a potential error, caused by instantiating | |
220 | // non-deduced contexts using placeholder arguments. | |
221 | tree fn = DECL_TEMPLATE_RESULT (tmpl); | |
222 | if (DECL_ARGUMENTS (fn)) | |
223 | continue; | |
224 | if (!DECL_DECLARED_CONCEPT_P (fn)) | |
225 | continue; | |
226 | ||
227 | // Remember the candidate if we can deduce a substitution. | |
228 | ++processing_template_decl; | |
229 | tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl)); | |
230 | if (tree subst = coerce_template_parms (parms, args, tmpl)) | |
f078dc7d AS |
231 | { |
232 | if (subst == error_mark_node) | |
233 | ++nerrs; | |
234 | else | |
235 | cands = tree_cons (subst, fn, cands); | |
236 | } | |
971e17ff AS |
237 | --processing_template_decl; |
238 | } | |
239 | ||
f078dc7d AS |
240 | if (!cands) |
241 | /* We either had no candidates or failed deductions. */ | |
242 | return nerrs ? error_mark_node : NULL_TREE; | |
243 | else if (TREE_CHAIN (cands)) | |
244 | /* There are multiple candidates. */ | |
245 | return error_mark_node; | |
971e17ff AS |
246 | |
247 | return cands; | |
248 | } | |
249 | ||
250 | // Determine if the the call expression CALL is a constraint check, and | |
251 | // return the concept declaration and arguments being checked. If CALL | |
252 | // does not denote a constraint check, return NULL. | |
253 | tree | |
254 | resolve_constraint_check (tree call) | |
255 | { | |
256 | gcc_assert (TREE_CODE (call) == CALL_EXPR); | |
257 | ||
258 | // A constraint check must be only a template-id expression. If | |
259 | // it's a call to a base-link, its function(s) should be a | |
260 | // template-id expression. If this is not a template-id, then it | |
261 | // cannot be a concept-check. | |
262 | tree target = CALL_EXPR_FN (call); | |
263 | if (BASELINK_P (target)) | |
264 | target = BASELINK_FUNCTIONS (target); | |
265 | if (TREE_CODE (target) != TEMPLATE_ID_EXPR) | |
266 | return NULL_TREE; | |
267 | ||
268 | // Get the overload set and template arguments and try to | |
269 | // resolve the target. | |
270 | tree ovl = TREE_OPERAND (target, 0); | |
271 | ||
272 | /* This is a function call of a variable concept... ill-formed. */ | |
273 | if (TREE_CODE (ovl) == TEMPLATE_DECL) | |
274 | { | |
275 | error_at (location_of (call), | |
276 | "function call of variable concept %qE", call); | |
277 | return error_mark_node; | |
278 | } | |
279 | ||
280 | tree args = TREE_OPERAND (target, 1); | |
281 | return resolve_constraint_check (ovl, args); | |
282 | } | |
283 | ||
284 | /* Returns a pair containing the checked variable concept | |
285 | and its associated prototype parameter. The result | |
286 | is a TREE_LIST whose TREE_VALUE is the variable concept | |
287 | and whose TREE_PURPOSE is the prototype parameter. */ | |
288 | ||
289 | tree | |
290 | resolve_variable_concept_check (tree id) | |
291 | { | |
292 | tree tmpl = TREE_OPERAND (id, 0); | |
293 | tree args = TREE_OPERAND (id, 1); | |
294 | ||
295 | if (!variable_concept_p (tmpl)) | |
296 | return NULL_TREE; | |
297 | ||
298 | /* Make sure that we have the right parameters before | |
299 | assuming that it works. Note that failing to deduce | |
300 | will result in diagnostics. */ | |
301 | tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); | |
f078dc7d | 302 | ++processing_template_decl; |
971e17ff | 303 | tree result = coerce_template_parms (parms, args, tmpl); |
f078dc7d | 304 | --processing_template_decl; |
971e17ff AS |
305 | if (result != error_mark_node) |
306 | { | |
307 | tree decl = DECL_TEMPLATE_RESULT (tmpl); | |
308 | return build_tree_list (result, decl); | |
309 | } | |
310 | else | |
f078dc7d | 311 | return error_mark_node; |
971e17ff AS |
312 | } |
313 | ||
314 | ||
315 | /* Given a call expression or template-id expression to | |
316 | a concept EXPR possibly including a wildcard, deduce | |
317 | the concept being checked and the prototype parameter. | |
318 | Returns true if the constraint and prototype can be | |
319 | deduced and false otherwise. Note that the CHECK and | |
320 | PROTO arguments are set to NULL_TREE if this returns | |
321 | false. */ | |
322 | ||
323 | bool | |
324 | deduce_constrained_parameter (tree expr, tree& check, tree& proto) | |
325 | { | |
326 | tree info = NULL_TREE; | |
327 | if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) | |
328 | info = resolve_variable_concept_check (expr); | |
329 | else if (TREE_CODE (expr) == CALL_EXPR) | |
330 | info = resolve_constraint_check (expr); | |
331 | else | |
332 | gcc_unreachable (); | |
333 | ||
334 | if (info && info != error_mark_node) | |
335 | { | |
336 | check = TREE_VALUE (info); | |
337 | tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0); | |
338 | if (ARGUMENT_PACK_P (arg)) | |
339 | arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0); | |
340 | proto = TREE_TYPE (arg); | |
341 | return true; | |
342 | } | |
343 | check = proto = NULL_TREE; | |
344 | return false; | |
345 | } | |
346 | ||
347 | // Given a call expression or template-id expression to a concept, EXPR, | |
348 | // deduce the concept being checked and return the template arguments. | |
349 | // Returns NULL_TREE if deduction fails. | |
350 | static tree | |
351 | deduce_concept_introduction (tree expr) | |
352 | { | |
353 | tree info = NULL_TREE; | |
354 | if (TREE_CODE (expr) == TEMPLATE_ID_EXPR) | |
355 | info = resolve_variable_concept_check (expr); | |
356 | else if (TREE_CODE (expr) == CALL_EXPR) | |
357 | info = resolve_constraint_check (expr); | |
358 | else | |
359 | gcc_unreachable (); | |
360 | ||
361 | if (info && info != error_mark_node) | |
362 | return TREE_PURPOSE (info); | |
363 | return NULL_TREE; | |
364 | } | |
365 | ||
366 | namespace { | |
367 | ||
368 | /*--------------------------------------------------------------------------- | |
f078dc7d | 369 | Constraint implication learning |
971e17ff AS |
370 | ---------------------------------------------------------------------------*/ |
371 | ||
f078dc7d AS |
372 | /* The implication context determines how we memoize concept checks. |
373 | Given two checks C1 and C2, the direction of implication depends | |
374 | on whether we are learning implications of a conjunction or disjunction. | |
375 | For example: | |
971e17ff | 376 | |
f078dc7d AS |
377 | template<typename T> concept bool C = ...; |
378 | template<typenaem T> concept bool D = C<T> && true; | |
971e17ff | 379 | |
f078dc7d AS |
380 | From this, we can learn that D<T> implies C<T>. We cannot learn, |
381 | without further testing, that C<T> does not imply D<T>. If, for | |
382 | example, C<T> were defined as true, then these constraints would | |
383 | be logically equivalent. | |
384 | ||
385 | In rare cases, we may start with a logical equivalence. For example: | |
386 | ||
387 | template<typename T> concept bool C = ...; | |
388 | template<typename T> concept bool D = C<T>; | |
389 | ||
390 | Here, we learn that C<T> implies D<T> and vice versa. */ | |
391 | ||
392 | enum implication_context | |
393 | { | |
394 | conjunction_cxt, /* C1 implies C2. */ | |
395 | disjunction_cxt, /* C2 implies C1. */ | |
396 | equivalence_cxt /* C1 implies C2, C2 implies C1. */ | |
397 | }; | |
398 | ||
399 | void learn_implications(tree, tree, implication_context); | |
400 | ||
401 | void | |
402 | learn_implication (tree parent, tree child, implication_context cxt) | |
971e17ff | 403 | { |
f078dc7d | 404 | switch (cxt) |
971e17ff | 405 | { |
f078dc7d AS |
406 | case conjunction_cxt: |
407 | save_subsumption_result (parent, child, true); | |
408 | break; | |
409 | case disjunction_cxt: | |
410 | save_subsumption_result (child, parent, true); | |
411 | break; | |
412 | case equivalence_cxt: | |
413 | save_subsumption_result (parent, child, true); | |
414 | save_subsumption_result (child, parent, true); | |
415 | break; | |
971e17ff | 416 | } |
971e17ff AS |
417 | } |
418 | ||
f078dc7d AS |
419 | void |
420 | learn_logical_operation (tree parent, tree constr, implication_context cxt) | |
971e17ff | 421 | { |
f078dc7d AS |
422 | learn_implications (parent, TREE_OPERAND (constr, 0), cxt); |
423 | learn_implications (parent, TREE_OPERAND (constr, 1), cxt); | |
971e17ff AS |
424 | } |
425 | ||
f078dc7d AS |
426 | void |
427 | learn_implications (tree parent, tree constr, implication_context cxt) | |
428 | { | |
429 | switch (TREE_CODE (constr)) | |
430 | { | |
431 | case CHECK_CONSTR: | |
432 | return learn_implication (parent, constr, cxt); | |
433 | ||
434 | case CONJ_CONSTR: | |
435 | if (cxt == disjunction_cxt) | |
436 | return; | |
437 | return learn_logical_operation (parent, constr, cxt); | |
438 | ||
439 | case DISJ_CONSTR: | |
440 | if (cxt == conjunction_cxt) | |
441 | return; | |
442 | return learn_logical_operation (parent, constr, cxt); | |
443 | ||
444 | default: | |
445 | break; | |
446 | } | |
447 | } | |
448 | ||
449 | /* Quickly scan the top-level constraints of CONSTR to learn and | |
450 | cache logical relations between concepts. The search does not | |
451 | include conjunctions of disjunctions or vice versa. */ | |
452 | ||
453 | void | |
454 | learn_implications (tree tmpl, tree args, tree constr) | |
455 | { | |
456 | /* Don't memoize relations between non-dependent arguemnts. It's not | |
457 | helpful. */ | |
458 | if (!uses_template_parms (args)) | |
459 | return; | |
460 | ||
461 | /* Build a check constraint for the purpose of caching. */ | |
462 | tree parent = build_nt (CHECK_CONSTR, tmpl, args); | |
463 | ||
464 | /* Start learning based on the kind of the top-level contraint. */ | |
465 | if (TREE_CODE (constr) == CONJ_CONSTR) | |
466 | return learn_logical_operation (parent, constr, conjunction_cxt); | |
467 | else if (TREE_CODE (constr) == DISJ_CONSTR) | |
468 | return learn_logical_operation (parent, constr, disjunction_cxt); | |
469 | else if (TREE_CODE (constr) == CHECK_CONSTR) | |
470 | /* This is the rare concept alias case. */ | |
471 | return learn_implication (parent, constr, equivalence_cxt); | |
472 | } | |
473 | ||
474 | /*--------------------------------------------------------------------------- | |
475 | Expansion of concept definitions | |
476 | ---------------------------------------------------------------------------*/ | |
477 | ||
478 | /* Returns the expression of a function concept. */ | |
479 | ||
971e17ff | 480 | tree |
f078dc7d | 481 | get_returned_expression (tree fn) |
971e17ff AS |
482 | { |
483 | /* Extract the body of the function minus the return expression. */ | |
484 | tree body = DECL_SAVED_TREE (fn); | |
485 | if (!body) | |
486 | return error_mark_node; | |
487 | if (TREE_CODE (body) == BIND_EXPR) | |
488 | body = BIND_EXPR_BODY (body); | |
489 | if (TREE_CODE (body) != RETURN_EXPR) | |
490 | return error_mark_node; | |
491 | ||
f078dc7d | 492 | return TREE_OPERAND (body, 0); |
971e17ff AS |
493 | } |
494 | ||
f078dc7d | 495 | /* Returns the initializer of a variable concept. */ |
971e17ff AS |
496 | |
497 | tree | |
f078dc7d | 498 | get_variable_initializer (tree var) |
971e17ff | 499 | { |
971e17ff AS |
500 | tree init = DECL_INITIAL (var); |
501 | if (!init) | |
502 | return error_mark_node; | |
f078dc7d AS |
503 | return init; |
504 | } | |
971e17ff | 505 | |
f078dc7d | 506 | /* Returns the definition of a variable or function concept. */ |
971e17ff | 507 | |
f078dc7d AS |
508 | tree |
509 | get_concept_definition (tree decl) | |
510 | { | |
86287716 | 511 | if (VAR_P (decl)) |
f078dc7d AS |
512 | return get_variable_initializer (decl); |
513 | else if (TREE_CODE (decl) == FUNCTION_DECL) | |
514 | return get_returned_expression (decl); | |
515 | gcc_unreachable (); | |
971e17ff AS |
516 | } |
517 | ||
f078dc7d | 518 | int expansion_level = 0; |
971e17ff | 519 | |
f078dc7d | 520 | struct expanding_concept_sentinel |
971e17ff | 521 | { |
f078dc7d AS |
522 | expanding_concept_sentinel () |
523 | { | |
524 | ++expansion_level; | |
525 | } | |
971e17ff | 526 | |
f078dc7d AS |
527 | ~expanding_concept_sentinel() |
528 | { | |
529 | --expansion_level; | |
530 | } | |
531 | }; | |
971e17ff | 532 | |
971e17ff | 533 | |
f078dc7d | 534 | } /* namespace */ |
971e17ff | 535 | |
f078dc7d AS |
536 | /* Returns true when a concept is being expanded. */ |
537 | ||
538 | bool | |
539 | expanding_concept() | |
971e17ff | 540 | { |
f078dc7d | 541 | return expansion_level > 0; |
971e17ff AS |
542 | } |
543 | ||
f078dc7d AS |
544 | /* Expand a concept declaration (not a template) and its arguments to |
545 | a constraint defined by the concept's initializer or definition. */ | |
546 | ||
971e17ff | 547 | tree |
f078dc7d | 548 | expand_concept (tree decl, tree args) |
971e17ff | 549 | { |
f078dc7d | 550 | expanding_concept_sentinel sentinel; |
971e17ff | 551 | |
f078dc7d AS |
552 | if (TREE_CODE (decl) == TEMPLATE_DECL) |
553 | decl = DECL_TEMPLATE_RESULT (decl); | |
554 | tree tmpl = DECL_TI_TEMPLATE (decl); | |
971e17ff | 555 | |
f078dc7d AS |
556 | /* Check for a previous specialization. */ |
557 | if (tree spec = get_concept_expansion (tmpl, args)) | |
558 | return spec; | |
971e17ff | 559 | |
f078dc7d AS |
560 | /* Substitute the arguments to form a new definition expression. */ |
561 | tree def = get_concept_definition (decl); | |
971e17ff | 562 | |
f078dc7d AS |
563 | ++processing_template_decl; |
564 | tree result = tsubst_expr (def, args, tf_none, NULL_TREE, true); | |
565 | --processing_template_decl; | |
566 | if (result == error_mark_node) | |
567 | return error_mark_node; | |
971e17ff | 568 | |
f078dc7d AS |
569 | /* And lastly, normalize it, check for implications, and save |
570 | the specialization for later. */ | |
571 | tree norm = normalize_expression (result); | |
572 | learn_implications (tmpl, args, norm); | |
573 | return save_concept_expansion (tmpl, args, norm); | |
971e17ff AS |
574 | } |
575 | ||
971e17ff | 576 | |
f078dc7d AS |
577 | /*--------------------------------------------------------------------------- |
578 | Stepwise normalization of expressions | |
971e17ff | 579 | |
f078dc7d AS |
580 | This set of functions will transform an expression into a constraint |
581 | in a sequence of steps. Normalization does not not look into concept | |
582 | definitions. | |
583 | ---------------------------------------------------------------------------*/ | |
971e17ff AS |
584 | |
585 | /* Transform a logical-or or logical-and expression into either | |
586 | a conjunction or disjunction. */ | |
587 | ||
588 | tree | |
f078dc7d | 589 | normalize_logical_operation (tree t, tree_code c) |
971e17ff | 590 | { |
f078dc7d AS |
591 | tree t0 = normalize_expression (TREE_OPERAND (t, 0)); |
592 | tree t1 = normalize_expression (TREE_OPERAND (t, 1)); | |
971e17ff AS |
593 | return build_nt (c, t0, t1); |
594 | } | |
595 | ||
596 | /* A simple requirement T introduces an expression constraint | |
597 | for its expression. */ | |
598 | ||
599 | inline tree | |
f078dc7d | 600 | normalize_simple_requirement (tree t) |
971e17ff AS |
601 | { |
602 | return build_nt (EXPR_CONSTR, TREE_OPERAND (t, 0)); | |
603 | } | |
604 | ||
605 | /* A type requirement T introduce a type constraint for its type. */ | |
606 | ||
607 | inline tree | |
f078dc7d | 608 | normalize_type_requirement (tree t) |
971e17ff AS |
609 | { |
610 | return build_nt (TYPE_CONSTR, TREE_OPERAND (t, 0)); | |
611 | } | |
612 | ||
613 | /* A compound requirement T introduces a conjunction of constraints | |
614 | depending on its form. The conjunction always includes an | |
615 | expression constraint for the expression of the requirement. | |
616 | If a trailing return type was specified, the conjunction includes | |
617 | either an implicit conversion constraint or an argument deduction | |
618 | constraint. If the noexcept specifier is present, the conjunction | |
619 | includes an exception constraint. */ | |
620 | ||
621 | tree | |
f078dc7d | 622 | normalize_compound_requirement (tree t) |
971e17ff AS |
623 | { |
624 | tree expr = TREE_OPERAND (t, 0); | |
625 | tree constr = build_nt (EXPR_CONSTR, TREE_OPERAND (t, 0)); | |
626 | ||
627 | /* If a type is given, append an implicit conversion or | |
628 | argument deduction constraint. */ | |
629 | if (tree type = TREE_OPERAND (t, 1)) | |
630 | { | |
631 | tree type_constr; | |
632 | /* TODO: We should be extracting a list of auto nodes | |
633 | from type_uses_auto, not a single node */ | |
634 | if (tree placeholder = type_uses_auto (type)) | |
635 | type_constr = build_nt (DEDUCT_CONSTR, expr, type, placeholder); | |
636 | else | |
637 | type_constr = build_nt (ICONV_CONSTR, expr, type); | |
638 | constr = conjoin_constraints (constr, type_constr); | |
639 | } | |
640 | ||
641 | /* If noexcept is present, append an exception constraint. */ | |
642 | if (COMPOUND_REQ_NOEXCEPT_P (t)) | |
643 | { | |
644 | tree except = build_nt (EXCEPT_CONSTR, expr); | |
645 | constr = conjoin_constraints (constr, except); | |
646 | } | |
647 | ||
648 | return constr; | |
649 | } | |
650 | ||
651 | /* A nested requirement T introduces a conjunction of constraints | |
652 | corresponding to its constraint-expression. | |
653 | ||
654 | If the result of transforming T is error_mark_node, the resulting | |
655 | constraint is a predicate constraint whose operand is also | |
656 | error_mark_node. This preserves the constraint structure, but | |
657 | will guarantee that the constraint is never satisfied. */ | |
658 | ||
659 | inline tree | |
f078dc7d | 660 | normalize_nested_requirement (tree t) |
971e17ff | 661 | { |
f078dc7d | 662 | return normalize_expression (TREE_OPERAND (t, 0)); |
971e17ff AS |
663 | } |
664 | ||
665 | /* Transform a requirement T into one or more constraints. */ | |
666 | ||
667 | tree | |
f078dc7d | 668 | normalize_requirement (tree t) |
971e17ff AS |
669 | { |
670 | switch (TREE_CODE (t)) | |
671 | { | |
672 | case SIMPLE_REQ: | |
f078dc7d | 673 | return normalize_simple_requirement (t); |
971e17ff AS |
674 | |
675 | case TYPE_REQ: | |
f078dc7d | 676 | return normalize_type_requirement (t); |
971e17ff AS |
677 | |
678 | case COMPOUND_REQ: | |
f078dc7d | 679 | return normalize_compound_requirement (t); |
971e17ff AS |
680 | |
681 | case NESTED_REQ: | |
f078dc7d | 682 | return normalize_nested_requirement (t); |
971e17ff AS |
683 | |
684 | default: | |
685 | gcc_unreachable (); | |
686 | } | |
687 | return error_mark_node; | |
688 | } | |
689 | ||
690 | /* Transform a sequence of requirements into a conjunction of | |
691 | constraints. */ | |
692 | ||
693 | tree | |
f078dc7d | 694 | normalize_requirements (tree t) |
971e17ff AS |
695 | { |
696 | tree result = NULL_TREE; | |
697 | for (; t; t = TREE_CHAIN (t)) | |
698 | { | |
f078dc7d | 699 | tree constr = normalize_requirement (TREE_VALUE (t)); |
971e17ff AS |
700 | result = conjoin_constraints (result, constr); |
701 | } | |
702 | return result; | |
703 | } | |
704 | ||
f078dc7d AS |
705 | /* The normal form of a requires-expression is a parameterized |
706 | constraint having the same parameters and a conjunction of | |
707 | constraints representing the normal form of requirements. */ | |
971e17ff AS |
708 | |
709 | tree | |
f078dc7d | 710 | normalize_requires_expression (tree t) |
971e17ff | 711 | { |
f078dc7d | 712 | tree operand = normalize_requirements (TREE_OPERAND (t, 1)); |
971e17ff AS |
713 | if (tree parms = TREE_OPERAND (t, 0)) |
714 | return build_nt (PARM_CONSTR, parms, operand); | |
715 | else | |
716 | return operand; | |
717 | } | |
718 | ||
f078dc7d AS |
719 | /* For a template-id referring to a variable concept, returns |
720 | a check constraint. Otherwise, returns a predicate constraint. */ | |
971e17ff AS |
721 | |
722 | tree | |
f078dc7d | 723 | normalize_template_id_expression (tree t) |
971e17ff | 724 | { |
f078dc7d AS |
725 | if (tree info = resolve_variable_concept_check (t)) |
726 | { | |
727 | if (info == error_mark_node) | |
728 | { | |
729 | /* We get this when the template arguments don't match | |
730 | the variable concept. */ | |
731 | error ("invalid reference to concept %qE", t); | |
732 | return error_mark_node; | |
733 | } | |
734 | ||
735 | tree decl = TREE_VALUE (info); | |
736 | tree args = TREE_PURPOSE (info); | |
737 | return build_nt (CHECK_CONSTR, decl, args); | |
738 | } | |
739 | ||
740 | /* Check that we didn't refer to a function concept like a variable. */ | |
19b476fb NS |
741 | tree fn = OVL_FIRST (TREE_OPERAND (t, 0)); |
742 | if (TREE_CODE (fn) == TEMPLATE_DECL | |
743 | && DECL_DECLARED_CONCEPT_P (DECL_TEMPLATE_RESULT (fn))) | |
f078dc7d | 744 | { |
19b476fb NS |
745 | error_at (location_of (t), |
746 | "invalid reference to function concept %qD", fn); | |
747 | return error_mark_node; | |
f078dc7d AS |
748 | } |
749 | ||
750 | return build_nt (PRED_CONSTR, t); | |
751 | } | |
752 | ||
753 | /* For a call expression to a function concept, returns a check | |
754 | constraint. Otherwise, returns a predicate constraint. */ | |
755 | ||
756 | tree | |
757 | normalize_call_expression (tree t) | |
758 | { | |
759 | /* Try to resolve this function call as a concept. If not, then | |
760 | it can be returned as a predicate constraint. */ | |
761 | tree check = resolve_constraint_check (t); | |
762 | if (!check) | |
763 | return build_nt (PRED_CONSTR, t); | |
764 | if (check == error_mark_node) | |
765 | { | |
766 | /* TODO: Improve diagnostics. We could report why the reference | |
767 | is invalid. */ | |
768 | error ("invalid reference to concept %qE", t); | |
769 | return error_mark_node; | |
770 | } | |
771 | ||
772 | tree fn = TREE_VALUE (check); | |
773 | tree args = TREE_PURPOSE (check); | |
774 | return build_nt (CHECK_CONSTR, fn, args); | |
775 | } | |
776 | ||
777 | /* If T is a call to an overloaded && or || operator, diagnose that | |
778 | as a non-SFINAEable error. Returns true if an error is emitted. | |
779 | ||
780 | TODO: It would be better to diagnose this at the point of definition, | |
781 | if possible. Perhaps we should immediately do a first-pass normalization | |
782 | of a concept definition to catch obvious non-dependent errors like | |
783 | this. */ | |
784 | ||
785 | bool | |
786 | check_for_logical_overloads (tree t) | |
787 | { | |
788 | if (TREE_CODE (t) != CALL_EXPR) | |
789 | return false; | |
790 | ||
791 | tree fn = CALL_EXPR_FN (t); | |
792 | ||
793 | /* For member calls, try extracting the function from the | |
794 | component ref. */ | |
795 | if (TREE_CODE (fn) == COMPONENT_REF) | |
796 | { | |
797 | fn = TREE_OPERAND (fn, 1); | |
798 | if (TREE_CODE (fn) == BASELINK) | |
799 | fn = BASELINK_FUNCTIONS (fn); | |
800 | } | |
801 | ||
802 | if (TREE_CODE (fn) != FUNCTION_DECL) | |
803 | return false; | |
804 | ||
805 | if (DECL_OVERLOADED_OPERATOR_P (fn)) | |
806 | { | |
6bdfada4 | 807 | location_t loc = cp_expr_loc_or_loc (t, input_location); |
f078dc7d AS |
808 | error_at (loc, "constraint %qE, uses overloaded operator", t); |
809 | return true; | |
810 | } | |
811 | ||
812 | return false; | |
813 | } | |
814 | ||
815 | /* The normal form of an atom depends on the expression. The normal | |
816 | form of a function call to a function concept is a check constraint | |
817 | for that concept. The normal form of a reference to a variable | |
818 | concept is a check constraint for that concept. Otherwise, the | |
819 | constraint is a predicate constraint. */ | |
820 | ||
821 | tree | |
822 | normalize_atom (tree t) | |
823 | { | |
824 | /* We can get constraints pushed down through pack expansions, so | |
825 | just return them. */ | |
826 | if (constraint_p (t)) | |
827 | return t; | |
828 | ||
829 | tree type = TREE_TYPE (t); | |
830 | if (!type || type_unknown_p (t) || TREE_CODE (type) == TEMPLATE_TYPE_PARM) | |
831 | ; | |
832 | else if (!dependent_type_p (type)) | |
833 | { | |
834 | if (check_for_logical_overloads (t)) | |
971e17ff | 835 | return error_mark_node; |
f078dc7d AS |
836 | |
837 | type = cv_unqualified (type); | |
838 | if (!same_type_p (type, boolean_type_node)) | |
839 | { | |
840 | error ("predicate constraint %q+E does not have type %<bool%>", t); | |
841 | return error_mark_node; | |
842 | } | |
843 | } | |
844 | ||
845 | if (TREE_CODE (t) == TEMPLATE_ID_EXPR) | |
846 | return normalize_template_id_expression (t); | |
847 | if (TREE_CODE (t) == CALL_EXPR) | |
848 | return normalize_call_expression (t); | |
971e17ff AS |
849 | return build_nt (PRED_CONSTR, t); |
850 | } | |
851 | ||
852 | /* Push down the pack expansion EXP into the leaves of the constraint PAT. */ | |
853 | ||
854 | tree | |
855 | push_down_pack_expansion (tree exp, tree pat) | |
856 | { | |
857 | switch (TREE_CODE (pat)) | |
858 | { | |
859 | case CONJ_CONSTR: | |
860 | case DISJ_CONSTR: | |
861 | { | |
862 | pat = copy_node (pat); | |
863 | TREE_OPERAND (pat, 0) | |
864 | = push_down_pack_expansion (exp, TREE_OPERAND (pat, 0)); | |
865 | TREE_OPERAND (pat, 1) | |
866 | = push_down_pack_expansion (exp, TREE_OPERAND (pat, 1)); | |
867 | return pat; | |
868 | } | |
869 | default: | |
870 | { | |
871 | exp = copy_node (exp); | |
872 | SET_PACK_EXPANSION_PATTERN (exp, pat); | |
873 | return exp; | |
874 | } | |
875 | } | |
876 | } | |
877 | ||
878 | /* Transform a pack expansion into a constraint. First we transform the | |
879 | pattern of the pack expansion, then we push the pack expansion down into the | |
880 | leaves of the constraint so that partial ordering will work. */ | |
881 | ||
882 | tree | |
f078dc7d | 883 | normalize_pack_expansion (tree t) |
971e17ff | 884 | { |
f078dc7d | 885 | tree pat = normalize_expression (PACK_EXPANSION_PATTERN (t)); |
971e17ff AS |
886 | return push_down_pack_expansion (t, pat); |
887 | } | |
888 | ||
889 | /* Transform an expression into a constraint. */ | |
890 | ||
891 | tree | |
f078dc7d | 892 | normalize_any_expression (tree t) |
971e17ff AS |
893 | { |
894 | switch (TREE_CODE (t)) | |
895 | { | |
896 | case TRUTH_ANDIF_EXPR: | |
f078dc7d | 897 | return normalize_logical_operation (t, CONJ_CONSTR); |
971e17ff AS |
898 | |
899 | case TRUTH_ORIF_EXPR: | |
f078dc7d | 900 | return normalize_logical_operation (t, DISJ_CONSTR); |
971e17ff AS |
901 | |
902 | case REQUIRES_EXPR: | |
f078dc7d | 903 | return normalize_requires_expression (t); |
971e17ff AS |
904 | |
905 | case BIND_EXPR: | |
f078dc7d | 906 | return normalize_expression (BIND_EXPR_BODY (t)); |
971e17ff AS |
907 | |
908 | case EXPR_PACK_EXPANSION: | |
f078dc7d | 909 | return normalize_pack_expansion (t); |
971e17ff AS |
910 | |
911 | default: | |
912 | /* All other constraints are atomic. */ | |
f078dc7d | 913 | return normalize_atom (t); |
971e17ff AS |
914 | } |
915 | } | |
916 | ||
917 | /* Transform a statement into an expression. */ | |
971e17ff | 918 | tree |
f078dc7d | 919 | normalize_any_statement (tree t) |
971e17ff AS |
920 | { |
921 | switch (TREE_CODE (t)) | |
922 | { | |
923 | case RETURN_EXPR: | |
f078dc7d | 924 | return normalize_expression (TREE_OPERAND (t, 0)); |
971e17ff AS |
925 | default: |
926 | gcc_unreachable (); | |
927 | } | |
928 | return error_mark_node; | |
929 | } | |
930 | ||
931 | /* Reduction rules for the declaration T. */ | |
932 | ||
933 | tree | |
f078dc7d | 934 | normalize_any_declaration (tree t) |
971e17ff AS |
935 | { |
936 | switch (TREE_CODE (t)) | |
937 | { | |
938 | case VAR_DECL: | |
f078dc7d | 939 | return normalize_atom (t); |
971e17ff AS |
940 | default: |
941 | gcc_unreachable (); | |
942 | } | |
943 | return error_mark_node; | |
944 | } | |
945 | ||
f078dc7d | 946 | /* Returns the normal form of a constraint expression. */ |
971e17ff AS |
947 | |
948 | tree | |
f078dc7d | 949 | normalize_expression (tree t) |
971e17ff AS |
950 | { |
951 | if (!t) | |
952 | return NULL_TREE; | |
953 | ||
954 | if (t == error_mark_node) | |
955 | return error_mark_node; | |
956 | ||
957 | switch (TREE_CODE_CLASS (TREE_CODE (t))) | |
958 | { | |
959 | case tcc_unary: | |
960 | case tcc_binary: | |
961 | case tcc_expression: | |
962 | case tcc_vl_exp: | |
f078dc7d | 963 | return normalize_any_expression (t); |
971e17ff AS |
964 | |
965 | case tcc_statement: | |
f078dc7d | 966 | return normalize_any_statement (t); |
971e17ff AS |
967 | |
968 | case tcc_declaration: | |
f078dc7d | 969 | return normalize_any_declaration (t); |
971e17ff AS |
970 | |
971 | case tcc_exceptional: | |
972 | case tcc_constant: | |
973 | case tcc_reference: | |
974 | case tcc_comparison: | |
975 | /* These are all atomic predicate constraints. */ | |
f078dc7d | 976 | return normalize_atom (t); |
971e17ff AS |
977 | |
978 | default: | |
979 | /* Unhandled node kind. */ | |
980 | gcc_unreachable (); | |
981 | } | |
982 | return error_mark_node; | |
983 | } | |
984 | ||
f078dc7d | 985 | |
971e17ff AS |
986 | /*--------------------------------------------------------------------------- |
987 | Constraint normalization | |
988 | ---------------------------------------------------------------------------*/ | |
989 | ||
990 | tree normalize_constraint (tree); | |
991 | ||
992 | /* The normal form of the disjunction T0 /\ T1 is the conjunction | |
993 | of the normal form of T0 and the normal form of T1. */ | |
994 | ||
995 | inline tree | |
996 | normalize_conjunction (tree t) | |
997 | { | |
998 | tree t0 = normalize_constraint (TREE_OPERAND (t, 0)); | |
999 | tree t1 = normalize_constraint (TREE_OPERAND (t, 1)); | |
1000 | return build_nt (CONJ_CONSTR, t0, t1); | |
1001 | } | |
1002 | ||
1003 | /* The normal form of the disjunction T0 \/ T1 is the disjunction | |
1004 | of the normal form of T0 and the normal form of T1. */ | |
1005 | ||
1006 | inline tree | |
1007 | normalize_disjunction (tree t) | |
1008 | { | |
1009 | tree t0 = normalize_constraint (TREE_OPERAND (t, 0)); | |
1010 | tree t1 = normalize_constraint (TREE_OPERAND (t, 1)); | |
1011 | return build_nt (DISJ_CONSTR, t0, t1); | |
1012 | } | |
1013 | ||
1014 | /* A predicate constraint is normalized in two stages. First all | |
1015 | references specializations of concepts are replaced by their | |
1016 | substituted definitions. Then, the resulting expression is | |
1017 | transformed into a constraint by transforming && expressions | |
1018 | into conjunctions and || into disjunctions. */ | |
1019 | ||
1020 | tree | |
1021 | normalize_predicate_constraint (tree t) | |
1022 | { | |
1023 | ++processing_template_decl; | |
1024 | tree expr = PRED_CONSTR_EXPR (t); | |
f078dc7d | 1025 | tree constr = normalize_expression (expr); |
971e17ff AS |
1026 | --processing_template_decl; |
1027 | return constr; | |
1028 | } | |
1029 | ||
1030 | /* The normal form of a parameterized constraint is the normal | |
1031 | form of its operand. */ | |
1032 | ||
1033 | tree | |
1034 | normalize_parameterized_constraint (tree t) | |
1035 | { | |
1036 | tree parms = PARM_CONSTR_PARMS (t); | |
1037 | tree operand = normalize_constraint (PARM_CONSTR_OPERAND (t)); | |
1038 | return build_nt (PARM_CONSTR, parms, operand); | |
1039 | } | |
1040 | ||
1041 | /* Normalize the constraint T by reducing it so that it is | |
1042 | comprised of only conjunctions and disjunctions of atomic | |
1043 | constraints. */ | |
1044 | ||
1045 | tree | |
1046 | normalize_constraint (tree t) | |
1047 | { | |
1048 | if (!t) | |
1049 | return NULL_TREE; | |
1050 | ||
1051 | if (t == error_mark_node) | |
1052 | return t; | |
1053 | ||
1054 | switch (TREE_CODE (t)) | |
1055 | { | |
1056 | case CONJ_CONSTR: | |
1057 | return normalize_conjunction (t); | |
1058 | ||
1059 | case DISJ_CONSTR: | |
1060 | return normalize_disjunction (t); | |
1061 | ||
1062 | case PRED_CONSTR: | |
1063 | return normalize_predicate_constraint (t); | |
1064 | ||
1065 | case PARM_CONSTR: | |
1066 | return normalize_parameterized_constraint (t); | |
1067 | ||
1068 | case EXPR_CONSTR: | |
1069 | case TYPE_CONSTR: | |
1070 | case ICONV_CONSTR: | |
1071 | case DEDUCT_CONSTR: | |
1072 | case EXCEPT_CONSTR: | |
1073 | /* These constraints are defined to be atomic. */ | |
1074 | return t; | |
1075 | ||
1076 | default: | |
1077 | /* CONSTR was not a constraint. */ | |
1078 | gcc_unreachable(); | |
1079 | } | |
1080 | return error_mark_node; | |
1081 | } | |
1082 | ||
971e17ff AS |
1083 | |
1084 | ||
1085 | // -------------------------------------------------------------------------- // | |
1086 | // Constraint Semantic Processing | |
1087 | // | |
1088 | // The following functions are called by the parser and substitution rules | |
1089 | // to create and evaluate constraint-related nodes. | |
1090 | ||
1091 | // The constraints associated with the current template parameters. | |
1092 | tree | |
1093 | current_template_constraints (void) | |
1094 | { | |
1095 | if (!current_template_parms) | |
1096 | return NULL_TREE; | |
1097 | tree tmpl_constr = TEMPLATE_PARM_CONSTRAINTS (current_template_parms); | |
1098 | return build_constraints (tmpl_constr, NULL_TREE); | |
1099 | } | |
1100 | ||
1101 | // If the recently parsed TYPE declares or defines a template or template | |
1102 | // specialization, get its corresponding constraints from the current | |
1103 | // template parameters and bind them to TYPE's declaration. | |
1104 | tree | |
1105 | associate_classtype_constraints (tree type) | |
1106 | { | |
1107 | if (!type || type == error_mark_node || TREE_CODE (type) != RECORD_TYPE) | |
1108 | return type; | |
1109 | ||
1110 | // An explicit class template specialization has no template | |
1111 | // parameters. | |
1112 | if (!current_template_parms) | |
1113 | return type; | |
1114 | ||
1115 | if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) | |
1116 | { | |
1117 | tree decl = TYPE_STUB_DECL (type); | |
1118 | tree ci = current_template_constraints (); | |
1119 | ||
1120 | // An implicitly instantiated member template declaration already | |
1121 | // has associated constraints. If it is defined outside of its | |
1122 | // class, then we need match these constraints against those of | |
1123 | // original declaration. | |
1124 | if (tree orig_ci = get_constraints (decl)) | |
1125 | { | |
1126 | if (!equivalent_constraints (ci, orig_ci)) | |
1127 | { | |
1128 | // FIXME: Improve diagnostics. | |
1129 | error ("%qT does not match any declaration", type); | |
1130 | return error_mark_node; | |
1131 | } | |
1132 | return type; | |
1133 | } | |
1134 | set_constraints (decl, ci); | |
1135 | } | |
1136 | return type; | |
1137 | } | |
1138 | ||
1139 | namespace { | |
1140 | ||
1141 | // Create an empty constraint info block. | |
1142 | inline tree_constraint_info* | |
1143 | build_constraint_info () | |
1144 | { | |
1145 | return (tree_constraint_info *)make_node (CONSTRAINT_INFO); | |
1146 | } | |
1147 | ||
1148 | } // namespace | |
1149 | ||
1150 | /* Build a constraint-info object that contains the associated constraints | |
1151 | of a declaration. This also includes the declaration's template | |
1152 | requirements (TREQS) and any trailing requirements for a function | |
1153 | declarator (DREQS). Note that both TREQS and DREQS must be constraints. | |
1154 | ||
1155 | If the declaration has neither template nor declaration requirements | |
1156 | this returns NULL_TREE, indicating an unconstrained declaration. */ | |
1157 | ||
1158 | tree | |
1159 | build_constraints (tree tmpl_reqs, tree decl_reqs) | |
1160 | { | |
1161 | gcc_assert (tmpl_reqs ? constraint_p (tmpl_reqs) : true); | |
1162 | gcc_assert (decl_reqs ? constraint_p (decl_reqs) : true); | |
1163 | ||
1164 | if (!tmpl_reqs && !decl_reqs) | |
1165 | return NULL_TREE; | |
1166 | ||
1167 | tree_constraint_info* ci = build_constraint_info (); | |
1168 | ci->template_reqs = tmpl_reqs; | |
1169 | ci->declarator_reqs = decl_reqs; | |
1170 | ci->associated_constr = conjoin_constraints (tmpl_reqs, decl_reqs); | |
1171 | ||
971e17ff AS |
1172 | return (tree)ci; |
1173 | } | |
1174 | ||
1175 | namespace { | |
1176 | ||
971e17ff AS |
1177 | /* Construct a sequence of template arguments by prepending |
1178 | ARG to REST. Either ARG or REST may be null. */ | |
1179 | tree | |
1180 | build_concept_check_arguments (tree arg, tree rest) | |
1181 | { | |
1182 | gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true); | |
1183 | tree args; | |
1184 | if (arg) | |
1185 | { | |
1186 | int n = rest ? TREE_VEC_LENGTH (rest) : 0; | |
1187 | args = make_tree_vec (n + 1); | |
1188 | TREE_VEC_ELT (args, 0) = arg; | |
1189 | if (rest) | |
1190 | for (int i = 0; i < n; ++i) | |
1191 | TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i); | |
1192 | int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0; | |
1193 | SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1); | |
1194 | } | |
1195 | else | |
1196 | { | |
1197 | gcc_assert (rest != NULL_TREE); | |
1198 | args = rest; | |
1199 | } | |
1200 | return args; | |
1201 | } | |
1202 | ||
1203 | } // namespace | |
1204 | ||
1205 | /* Construct an expression that checks the concept given by | |
1206 | TARGET. The TARGET must be: | |
1207 | ||
1208 | - an OVERLOAD referring to one or more function concepts | |
1209 | - a BASELINK referring to an overload set of the above, or | |
1210 | - a TEMPLTATE_DECL referring to a variable concept. | |
1211 | ||
1212 | ARG and REST are the explicit template arguments for the | |
1213 | eventual concept check. */ | |
1214 | tree | |
1215 | build_concept_check (tree target, tree arg, tree rest) | |
1216 | { | |
1217 | tree args = build_concept_check_arguments (arg, rest); | |
1218 | if (variable_template_p (target)) | |
1219 | return build_variable_check (lookup_template_variable (target, args)); | |
1220 | else | |
1221 | return build_call_check (lookup_template_function (target, args)); | |
1222 | } | |
1223 | ||
1224 | ||
1225 | /* Returns a TYPE_DECL that contains sufficient information to | |
1226 | build a template parameter of the same kind as PROTO and | |
1227 | constrained by the concept declaration CNC. Note that PROTO | |
1228 | is the first template parameter of CNC. | |
1229 | ||
1230 | If specified, ARGS provides additional arguments to the | |
1231 | constraint check. */ | |
1232 | tree | |
1233 | build_constrained_parameter (tree cnc, tree proto, tree args) | |
1234 | { | |
1235 | tree name = DECL_NAME (cnc); | |
1236 | tree type = TREE_TYPE (proto); | |
1237 | tree decl = build_decl (input_location, TYPE_DECL, name, type); | |
1238 | CONSTRAINED_PARM_PROTOTYPE (decl) = proto; | |
1239 | CONSTRAINED_PARM_CONCEPT (decl) = cnc; | |
1240 | CONSTRAINED_PARM_EXTRA_ARGS (decl) = args; | |
1241 | return decl; | |
1242 | } | |
1243 | ||
1244 | /* Create a constraint expression for the given DECL that | |
1245 | evaluates the requirements specified by CONSTR, a TYPE_DECL | |
1246 | that contains all the information necessary to build the | |
1247 | requirements (see finish_concept_name for the layout of | |
1248 | that TYPE_DECL). | |
1249 | ||
1250 | Note that the constraints are neither reduced nor decomposed. | |
1251 | That is done only after the requires clause has been parsed | |
f078dc7d AS |
1252 | (or not). |
1253 | ||
1254 | This will always return a CHECK_CONSTR. */ | |
971e17ff AS |
1255 | tree |
1256 | finish_shorthand_constraint (tree decl, tree constr) | |
1257 | { | |
1258 | /* No requirements means no constraints. */ | |
1259 | if (!constr) | |
1260 | return NULL_TREE; | |
1261 | ||
d1dfeff0 PC |
1262 | if (error_operand_p (constr)) |
1263 | return NULL_TREE; | |
1264 | ||
971e17ff AS |
1265 | tree proto = CONSTRAINED_PARM_PROTOTYPE (constr); |
1266 | tree con = CONSTRAINED_PARM_CONCEPT (constr); | |
1267 | tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr); | |
1268 | ||
1269 | /* If the parameter declaration is variadic, but the concept | |
1270 | is not then we need to apply the concept to every element | |
1271 | in the pack. */ | |
1272 | bool is_proto_pack = template_parameter_pack_p (proto); | |
1273 | bool is_decl_pack = template_parameter_pack_p (decl); | |
1274 | bool apply_to_all_p = is_decl_pack && !is_proto_pack; | |
1275 | ||
1276 | /* Get the argument and overload used for the requirement | |
1277 | and adjust it if we're going to expand later. */ | |
1278 | tree arg = template_parm_to_arg (build_tree_list (NULL_TREE, decl)); | |
1279 | if (apply_to_all_p) | |
1280 | arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0)); | |
1281 | ||
1282 | /* Build the concept check. If it the constraint needs to be | |
1283 | applied to all elements of the parameter pack, then make | |
1284 | the constraint an expansion. */ | |
971e17ff | 1285 | tree tmpl = DECL_TI_TEMPLATE (con); |
19b476fb NS |
1286 | tree check = VAR_P (con) ? tmpl : ovl_make (tmpl); |
1287 | check = build_concept_check (check, arg, args); | |
971e17ff AS |
1288 | |
1289 | /* Make the check a pack expansion if needed. | |
1290 | ||
1291 | FIXME: We should be making a fold expression. */ | |
1292 | if (apply_to_all_p) | |
1293 | { | |
1294 | check = make_pack_expansion (check); | |
1295 | TREE_TYPE (check) = boolean_type_node; | |
1296 | } | |
1297 | ||
f078dc7d | 1298 | return normalize_expression (check); |
971e17ff AS |
1299 | } |
1300 | ||
1301 | /* Returns a conjunction of shorthand requirements for the template | |
1302 | parameter list PARMS. Note that the requirements are stored in | |
1303 | the TYPE of each tree node. */ | |
1304 | tree | |
1305 | get_shorthand_constraints (tree parms) | |
1306 | { | |
1307 | tree result = NULL_TREE; | |
1308 | parms = INNERMOST_TEMPLATE_PARMS (parms); | |
1309 | for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i) | |
1310 | { | |
1311 | tree parm = TREE_VEC_ELT (parms, i); | |
1312 | tree constr = TEMPLATE_PARM_CONSTRAINTS (parm); | |
1313 | result = conjoin_constraints (result, constr); | |
1314 | } | |
1315 | return result; | |
1316 | } | |
1317 | ||
1318 | // Returns and chains a new parameter for PARAMETER_LIST which will conform | |
1319 | // to the prototype given by SRC_PARM. The new parameter will have its | |
1320 | // identifier and location set according to IDENT and PARM_LOC respectively. | |
1321 | static tree | |
1322 | process_introduction_parm (tree parameter_list, tree src_parm) | |
1323 | { | |
1324 | // If we have a pack, we should have a single pack argument which is the | |
1325 | // placeholder we want to look at. | |
1326 | bool is_parameter_pack = ARGUMENT_PACK_P (src_parm); | |
1327 | if (is_parameter_pack) | |
1328 | src_parm = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (src_parm), 0); | |
1329 | ||
1330 | // At this point we should have a wildcard, but we want to | |
1331 | // grab the associated decl from it. Also grab the stored | |
1332 | // identifier and location that should be chained to it in | |
1333 | // a PARM_DECL. | |
1334 | gcc_assert (TREE_CODE (src_parm) == WILDCARD_DECL); | |
1335 | ||
1336 | tree ident = DECL_NAME (src_parm); | |
1337 | location_t parm_loc = DECL_SOURCE_LOCATION (src_parm); | |
1338 | ||
1339 | // If we expect a pack and the deduced template is not a pack, or if the | |
1340 | // template is using a pack and we didn't declare a pack, throw an error. | |
1341 | if (is_parameter_pack != WILDCARD_PACK_P (src_parm)) | |
1342 | { | |
1343 | error_at (parm_loc, "cannot match pack for introduced parameter"); | |
1344 | tree err_parm = build_tree_list (error_mark_node, error_mark_node); | |
1345 | return chainon (parameter_list, err_parm); | |
1346 | } | |
1347 | ||
1348 | src_parm = TREE_TYPE (src_parm); | |
1349 | ||
1350 | tree parm; | |
1351 | bool is_non_type; | |
1352 | if (TREE_CODE (src_parm) == TYPE_DECL) | |
1353 | { | |
1354 | is_non_type = false; | |
1355 | parm = finish_template_type_parm (class_type_node, ident); | |
1356 | } | |
1357 | else if (TREE_CODE (src_parm) == TEMPLATE_DECL) | |
1358 | { | |
1359 | is_non_type = false; | |
1360 | begin_template_parm_list (); | |
1361 | current_template_parms = DECL_TEMPLATE_PARMS (src_parm); | |
1362 | end_template_parm_list (); | |
1363 | parm = finish_template_template_parm (class_type_node, ident); | |
1364 | } | |
1365 | else | |
1366 | { | |
1367 | is_non_type = true; | |
1368 | ||
1369 | // Since we don't have a declarator, so we can copy the source | |
1370 | // parameter and change the name and eventually the location. | |
1371 | parm = copy_decl (src_parm); | |
1372 | DECL_NAME (parm) = ident; | |
1373 | } | |
1374 | ||
1375 | // Wrap in a TREE_LIST for process_template_parm. Introductions do not | |
1376 | // retain the defaults from the source template. | |
1377 | parm = build_tree_list (NULL_TREE, parm); | |
1378 | ||
1379 | return process_template_parm (parameter_list, parm_loc, parm, | |
1380 | is_non_type, is_parameter_pack); | |
1381 | } | |
1382 | ||
1383 | /* Associates a constraint check to the current template based | |
1384 | on the introduction parameters. INTRO_LIST must be a TREE_VEC | |
1385 | of WILDCARD_DECLs containing a chained PARM_DECL which | |
1386 | contains the identifier as well as the source location. | |
1387 | TMPL_DECL is the decl for the concept being used. If we | |
1388 | take a concept, C, this will form a check in the form of | |
1389 | C<INTRO_LIST> filling in any extra arguments needed by the | |
1390 | defaults deduced. | |
1391 | ||
1392 | Returns NULL_TREE if no concept could be matched and | |
1393 | error_mark_node if an error occurred when matching. */ | |
1394 | tree | |
1395 | finish_template_introduction (tree tmpl_decl, tree intro_list) | |
1396 | { | |
1397 | /* Deduce the concept check. */ | |
1398 | tree expr = build_concept_check (tmpl_decl, NULL_TREE, intro_list); | |
1399 | if (expr == error_mark_node) | |
1400 | return NULL_TREE; | |
1401 | ||
1402 | tree parms = deduce_concept_introduction (expr); | |
1403 | if (!parms) | |
1404 | return NULL_TREE; | |
1405 | ||
1406 | /* Build template parameter scope for introduction. */ | |
1407 | tree parm_list = NULL_TREE; | |
1408 | begin_template_parm_list (); | |
1409 | int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list)); | |
1410 | for (int n = 0; n < nargs; ++n) | |
1411 | parm_list = process_introduction_parm (parm_list, TREE_VEC_ELT (parms, n)); | |
1412 | parm_list = end_template_parm_list (parm_list); | |
1413 | for (int i = 0; i < TREE_VEC_LENGTH (parm_list); ++i) | |
1414 | if (TREE_VALUE (TREE_VEC_ELT (parm_list, i)) == error_mark_node) | |
1415 | { | |
1416 | end_template_decl (); | |
1417 | return error_mark_node; | |
1418 | } | |
1419 | ||
1420 | /* Build a concept check for our constraint. */ | |
1421 | tree check_args = make_tree_vec (TREE_VEC_LENGTH (parms)); | |
1422 | int n = 0; | |
1423 | for (; n < TREE_VEC_LENGTH (parm_list); ++n) | |
1424 | { | |
1425 | tree parm = TREE_VEC_ELT (parm_list, n); | |
1426 | TREE_VEC_ELT (check_args, n) = template_parm_to_arg (parm); | |
1427 | } | |
4e7739b2 | 1428 | SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n); |
971e17ff AS |
1429 | |
1430 | /* If the template expects more parameters we should be able | |
1431 | to use the defaults from our deduced concept. */ | |
1432 | for (; n < TREE_VEC_LENGTH (parms); ++n) | |
1433 | TREE_VEC_ELT (check_args, n) = TREE_VEC_ELT (parms, n); | |
1434 | ||
1435 | /* Associate the constraint. */ | |
1436 | tree check = build_concept_check (tmpl_decl, NULL_TREE, check_args); | |
f078dc7d | 1437 | tree constr = normalize_expression (check); |
971e17ff AS |
1438 | TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = constr; |
1439 | ||
1440 | return parm_list; | |
1441 | } | |
1442 | ||
1443 | ||
636b25c1 JM |
1444 | /* Given the predicate constraint T from a constrained-type-specifier, extract |
1445 | its TMPL and ARGS. FIXME why do we need two different forms of | |
1446 | constrained-type-specifier? */ | |
4fea442d JM |
1447 | |
1448 | void | |
1449 | placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args) | |
1450 | { | |
636b25c1 JM |
1451 | if (TREE_CODE (t) == TYPE_DECL) |
1452 | { | |
f078dc7d AS |
1453 | /* A constrained parameter. Build a constraint check |
1454 | based on the prototype parameter and then extract the | |
1455 | arguments from that. */ | |
1456 | tree proto = CONSTRAINED_PARM_PROTOTYPE (t); | |
1457 | tree check = finish_shorthand_constraint (proto, t); | |
1458 | placeholder_extract_concept_and_args (check, tmpl, args); | |
636b25c1 JM |
1459 | return; |
1460 | } | |
1461 | ||
f078dc7d | 1462 | if (TREE_CODE (t) == CHECK_CONSTR) |
4fea442d | 1463 | { |
f078dc7d AS |
1464 | tree decl = CHECK_CONSTR_CONCEPT (t); |
1465 | tmpl = DECL_TI_TEMPLATE (decl); | |
1466 | args = CHECK_CONSTR_ARGS (t); | |
1467 | return; | |
4fea442d | 1468 | } |
f078dc7d | 1469 | |
4fea442d JM |
1470 | gcc_unreachable (); |
1471 | } | |
1472 | ||
1473 | /* Returns true iff the placeholders C1 and C2 are equivalent. C1 | |
f078dc7d | 1474 | and C2 can be either CHECK_CONSTR or TEMPLATE_TYPE_PARM. */ |
4fea442d JM |
1475 | |
1476 | bool | |
1477 | equivalent_placeholder_constraints (tree c1, tree c2) | |
1478 | { | |
636b25c1 JM |
1479 | if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM) |
1480 | /* A constrained auto. */ | |
4fea442d | 1481 | c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1); |
636b25c1 | 1482 | if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM) |
4fea442d JM |
1483 | c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2); |
1484 | ||
1485 | if (c1 == c2) | |
1486 | return true; | |
1487 | if (!c1 || !c2) | |
1488 | return false; | |
f078dc7d AS |
1489 | if (c1 == error_mark_node || c2 == error_mark_node) |
1490 | /* We get here during satisfaction; when a deduction constraint | |
1491 | fails, substitution can produce an error_mark_node for the | |
1492 | placeholder constraints. */ | |
1493 | return false; | |
4fea442d JM |
1494 | |
1495 | tree t1, t2, a1, a2; | |
1496 | placeholder_extract_concept_and_args (c1, t1, a1); | |
1497 | placeholder_extract_concept_and_args (c2, t2, a2); | |
1498 | ||
1499 | if (t1 != t2) | |
1500 | return false; | |
636b25c1 | 1501 | |
f078dc7d AS |
1502 | int len1 = TREE_VEC_LENGTH (a1); |
1503 | int len2 = TREE_VEC_LENGTH (a2); | |
636b25c1 JM |
1504 | if (len1 != len2) |
1505 | return false; | |
1506 | ||
f078dc7d AS |
1507 | /* Skip the first argument so we don't infinitely recurse. |
1508 | Also, they may differ in template parameter index. */ | |
1509 | for (int i = 1; i < len1; ++i) | |
1510 | { | |
1511 | tree t1 = TREE_VEC_ELT (a1, i); | |
1512 | tree t2 = TREE_VEC_ELT (a2, i); | |
1513 | if (!template_args_equal (t1, t2)) | |
4fea442d | 1514 | return false; |
f078dc7d | 1515 | } |
4fea442d JM |
1516 | return true; |
1517 | } | |
1518 | ||
1519 | /* Return a hash value for the placeholder PRED_CONSTR C. */ | |
1520 | ||
1521 | hashval_t | |
1522 | hash_placeholder_constraint (tree c) | |
1523 | { | |
1524 | tree t, a; | |
1525 | placeholder_extract_concept_and_args (c, t, a); | |
1526 | ||
1527 | /* Like hash_tmpl_and_args, but skip the first argument. */ | |
1528 | hashval_t val = iterative_hash_object (DECL_UID (t), 0); | |
1529 | ||
1530 | for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i) | |
1531 | val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val); | |
1532 | ||
1533 | return val; | |
1534 | } | |
971e17ff AS |
1535 | |
1536 | /*--------------------------------------------------------------------------- | |
1537 | Constraint substitution | |
1538 | ---------------------------------------------------------------------------*/ | |
1539 | ||
1540 | /* The following functions implement substitution rules for constraints. | |
1541 | Substitution without checking constraints happens only in the | |
1542 | instantiation of class templates. For example: | |
1543 | ||
1544 | template<C1 T> struct S { | |
1545 | void f(T) requires C2<T>; | |
1546 | void g(T) requires T::value; | |
1547 | }; | |
1548 | ||
1549 | S<int> s; // error instantiating S<int>::g(T) | |
1550 | ||
1551 | When we instantiate S, we substitute into its member declarations, | |
1552 | including their constraints. However, those constraints are not | |
1553 | checked. Substituting int into C2<T> yields C2<int>, and substituting | |
1554 | into T::value yields a substitution failure, making the program | |
1555 | ill-formed. | |
1556 | ||
1557 | Note that we only ever substitute into the associated constraints | |
1558 | of a declaration. That is, substitution is defined only for predicate | |
1559 | constraints and conjunctions. */ | |
1560 | ||
1561 | /* Substitute into the predicate constraints. Returns error_mark_node | |
1562 | if the substitution into the expression fails. */ | |
1563 | tree | |
1564 | tsubst_predicate_constraint (tree t, tree args, | |
1565 | tsubst_flags_t complain, tree in_decl) | |
1566 | { | |
1567 | tree expr = PRED_CONSTR_EXPR (t); | |
1568 | ++processing_template_decl; | |
1569 | tree result = tsubst_expr (expr, args, complain, in_decl, false); | |
1570 | --processing_template_decl; | |
1571 | return build_nt (PRED_CONSTR, result); | |
1572 | } | |
1573 | ||
f078dc7d AS |
1574 | /* Substitute into a check constraint. */ |
1575 | ||
1576 | tree | |
1577 | tsubst_check_constraint (tree t, tree args, | |
1578 | tsubst_flags_t complain, tree in_decl) | |
1579 | { | |
1580 | tree decl = CHECK_CONSTR_CONCEPT (t); | |
1581 | tree tmpl = DECL_TI_TEMPLATE (decl); | |
1582 | tree targs = CHECK_CONSTR_ARGS (t); | |
1583 | ||
1584 | /* Substitute through by building an template-id expression | |
1585 | and then substituting into that. */ | |
e9888922 | 1586 | tree expr = build_nt (TEMPLATE_ID_EXPR, tmpl, targs); |
f078dc7d AS |
1587 | ++processing_template_decl; |
1588 | tree result = tsubst_expr (expr, args, complain, in_decl, false); | |
1589 | --processing_template_decl; | |
1590 | ||
1591 | if (result == error_mark_node) | |
1592 | return error_mark_node; | |
1593 | ||
1594 | /* Extract the results and rebuild the check constraint. */ | |
1595 | decl = DECL_TEMPLATE_RESULT (TREE_OPERAND (result, 0)); | |
1596 | args = TREE_OPERAND (result, 1); | |
1597 | ||
1598 | return build_nt (CHECK_CONSTR, decl, args); | |
1599 | } | |
1600 | ||
971e17ff AS |
1601 | /* Substitute into the conjunction of constraints. Returns |
1602 | error_mark_node if substitution into either operand fails. */ | |
f078dc7d | 1603 | |
971e17ff | 1604 | tree |
f078dc7d AS |
1605 | tsubst_logical_operator (tree t, tree args, |
1606 | tsubst_flags_t complain, tree in_decl) | |
971e17ff AS |
1607 | { |
1608 | tree t0 = TREE_OPERAND (t, 0); | |
1609 | tree r0 = tsubst_constraint (t0, args, complain, in_decl); | |
f078dc7d AS |
1610 | if (r0 == error_mark_node) |
1611 | return error_mark_node; | |
971e17ff AS |
1612 | tree t1 = TREE_OPERAND (t, 1); |
1613 | tree r1 = tsubst_constraint (t1, args, complain, in_decl); | |
f078dc7d AS |
1614 | if (r1 == error_mark_node) |
1615 | return error_mark_node; | |
1616 | return build_nt (TREE_CODE (t), r0, r1); | |
1617 | } | |
1618 | ||
1619 | namespace { | |
1620 | ||
1621 | /* Substitute ARGS into the expression constraint T. */ | |
1622 | ||
1623 | tree | |
1624 | tsubst_expr_constr (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
1625 | { | |
1626 | cp_unevaluated guard; | |
1627 | tree expr = EXPR_CONSTR_EXPR (t); | |
1628 | tree ret = tsubst_expr (expr, args, complain, in_decl, false); | |
1629 | if (ret == error_mark_node) | |
1630 | return error_mark_node; | |
1631 | return build_nt (EXPR_CONSTR, ret); | |
1632 | } | |
1633 | ||
1634 | /* Substitute ARGS into the type constraint T. */ | |
1635 | ||
1636 | tree | |
1637 | tsubst_type_constr (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
1638 | { | |
1639 | tree type = TYPE_CONSTR_TYPE (t); | |
1640 | tree ret = tsubst (type, args, complain, in_decl); | |
1641 | if (ret == error_mark_node) | |
1642 | return error_mark_node; | |
1643 | return build_nt (TYPE_CONSTR, ret); | |
1644 | } | |
1645 | ||
1646 | /* Substitute ARGS into the implicit conversion constraint T. */ | |
1647 | ||
1648 | tree | |
1649 | tsubst_implicit_conversion_constr (tree t, tree args, tsubst_flags_t complain, | |
1650 | tree in_decl) | |
1651 | { | |
1652 | cp_unevaluated guard; | |
1653 | tree expr = ICONV_CONSTR_EXPR (t); | |
1654 | tree type = ICONV_CONSTR_TYPE (t); | |
1655 | tree new_expr = tsubst_expr (expr, args, complain, in_decl, false); | |
1656 | if (new_expr == error_mark_node) | |
1657 | return error_mark_node; | |
1658 | tree new_type = tsubst (type, args, complain, in_decl); | |
1659 | if (new_type == error_mark_node) | |
1660 | return error_mark_node; | |
1661 | return build_nt (ICONV_CONSTR, new_expr, new_type); | |
1662 | } | |
1663 | ||
1664 | /* Substitute ARGS into the argument deduction constraint T. */ | |
1665 | ||
1666 | tree | |
1667 | tsubst_argument_deduction_constr (tree t, tree args, tsubst_flags_t complain, | |
1668 | tree in_decl) | |
1669 | { | |
1670 | cp_unevaluated guard; | |
1671 | tree expr = DEDUCT_CONSTR_EXPR (t); | |
1672 | tree pattern = DEDUCT_CONSTR_PATTERN (t); | |
1673 | tree autos = DEDUCT_CONSTR_PLACEHOLDER(t); | |
1674 | tree new_expr = tsubst_expr (expr, args, complain, in_decl, false); | |
1675 | if (new_expr == error_mark_node) | |
1676 | return error_mark_node; | |
1677 | /* It seems like substituting through the pattern will not affect the | |
1678 | placeholders. We should (?) be able to reuse the existing list | |
1679 | without any problems. If not, then we probably want to create a | |
1680 | new list of placeholders and then instantiate the pattern using | |
1681 | those. */ | |
1682 | tree new_pattern = tsubst (pattern, args, complain, in_decl); | |
1683 | if (new_pattern == error_mark_node) | |
1684 | return error_mark_node; | |
1685 | return build_nt (DEDUCT_CONSTR, new_expr, new_pattern, autos); | |
971e17ff AS |
1686 | } |
1687 | ||
f078dc7d AS |
1688 | /* Substitute ARGS into the exception constraint T. */ |
1689 | ||
971e17ff | 1690 | tree |
f078dc7d AS |
1691 | tsubst_exception_constr (tree t, tree args, tsubst_flags_t complain, |
1692 | tree in_decl) | |
971e17ff | 1693 | { |
f078dc7d AS |
1694 | cp_unevaluated guard; |
1695 | tree expr = EXCEPT_CONSTR_EXPR (t); | |
1696 | tree ret = tsubst_expr (expr, args, complain, in_decl, false); | |
1697 | if (ret == error_mark_node) | |
1698 | return error_mark_node; | |
1699 | return build_nt (EXCEPT_CONSTR, ret); | |
971e17ff AS |
1700 | } |
1701 | ||
971e17ff AS |
1702 | /* A subroutine of tsubst_constraint_variables. Register local |
1703 | specializations for each of parameter in PARMS and its | |
1704 | corresponding substituted constraint variable in VARS. | |
1705 | Returns VARS. */ | |
f078dc7d | 1706 | |
971e17ff AS |
1707 | tree |
1708 | declare_constraint_vars (tree parms, tree vars) | |
1709 | { | |
1710 | tree s = vars; | |
1711 | for (tree t = parms; t; t = DECL_CHAIN (t)) | |
1712 | { | |
1713 | if (DECL_PACK_P (t)) | |
1714 | { | |
1715 | tree pack = extract_fnparm_pack (t, &s); | |
1716 | register_local_specialization (pack, t); | |
1717 | } | |
1718 | else | |
1719 | { | |
1720 | register_local_specialization (s, t); | |
1721 | s = DECL_CHAIN (s); | |
1722 | } | |
1723 | } | |
1724 | return vars; | |
1725 | } | |
1726 | ||
1727 | /* A subroutine of tsubst_parameterized_constraint. Substitute ARGS | |
1728 | into the parameter list T, producing a sequence of constraint | |
1729 | variables, declared in the current scope. | |
1730 | ||
1731 | Note that the caller must establish a local specialization stack | |
1732 | prior to calling this function since this substitution will | |
1733 | declare the substituted parameters. */ | |
f078dc7d | 1734 | |
971e17ff AS |
1735 | tree |
1736 | tsubst_constraint_variables (tree t, tree args, | |
1737 | tsubst_flags_t complain, tree in_decl) | |
1738 | { | |
1739 | /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain | |
1740 | of PARM_DECLs. */ | |
1741 | int saved_unevaluated_operand = cp_unevaluated_operand; | |
1742 | cp_unevaluated_operand = 0; | |
1743 | tree vars = tsubst (t, args, complain, in_decl); | |
1744 | cp_unevaluated_operand = saved_unevaluated_operand; | |
1745 | if (vars == error_mark_node) | |
1746 | return error_mark_node; | |
1747 | return declare_constraint_vars (t, vars); | |
1748 | } | |
1749 | ||
f078dc7d AS |
1750 | /* Substitute ARGS into the parameterized constraint T. */ |
1751 | ||
1752 | tree | |
1753 | tsubst_parameterized_constraint (tree t, tree args, | |
1754 | tsubst_flags_t complain, tree in_decl) | |
1755 | { | |
1756 | local_specialization_stack stack; | |
1757 | tree vars = tsubst_constraint_variables (PARM_CONSTR_PARMS (t), | |
1758 | args, complain, in_decl); | |
1759 | if (vars == error_mark_node) | |
1760 | return error_mark_node; | |
1761 | tree expr = tsubst_constraint (PARM_CONSTR_OPERAND (t), args, | |
1762 | complain, in_decl); | |
1763 | if (expr == error_mark_node) | |
1764 | return error_mark_node; | |
1765 | return build_nt (PARM_CONSTR, vars, expr); | |
1766 | } | |
1767 | ||
971e17ff AS |
1768 | /* Substitute ARGS into the simple requirement T. Note that |
1769 | substitution may result in an ill-formed expression without | |
1770 | causing the program to be ill-formed. In such cases, the | |
1771 | requirement wraps an error_mark_node. */ | |
f078dc7d | 1772 | |
971e17ff AS |
1773 | inline tree |
1774 | tsubst_simple_requirement (tree t, tree args, | |
1775 | tsubst_flags_t complain, tree in_decl) | |
1776 | { | |
1777 | ++processing_template_decl; | |
1778 | tree expr = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl, false); | |
1779 | --processing_template_decl; | |
1780 | return finish_simple_requirement (expr); | |
1781 | } | |
1782 | ||
1783 | /* Substitute ARGS into the type requirement T. Note that | |
1784 | substitution may result in an ill-formed type without | |
1785 | causing the program to be ill-formed. In such cases, the | |
1786 | requirement wraps an error_mark_node. */ | |
1787 | ||
1788 | inline tree | |
1789 | tsubst_type_requirement (tree t, tree args, | |
1790 | tsubst_flags_t complain, tree in_decl) | |
1791 | { | |
1792 | ++processing_template_decl; | |
1793 | tree type = tsubst (TREE_OPERAND (t, 0), args, complain, in_decl); | |
1794 | --processing_template_decl; | |
1795 | return finish_type_requirement (type); | |
1796 | } | |
1797 | ||
1798 | /* Substitute args into the compound requirement T. If substituting | |
1799 | into either the expression or the type fails, the corresponding | |
1800 | operands in the resulting node will be error_mark_node. This | |
1801 | preserves a requirement for the purpose of partial ordering, but | |
1802 | it will never be satisfied. */ | |
1803 | ||
1804 | tree | |
1805 | tsubst_compound_requirement (tree t, tree args, | |
1806 | tsubst_flags_t complain, tree in_decl) | |
1807 | { | |
1808 | ++processing_template_decl; | |
1809 | tree expr = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl, false); | |
1810 | tree type = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl); | |
1811 | --processing_template_decl; | |
1812 | bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t); | |
1813 | return finish_compound_requirement (expr, type, noexcept_p); | |
1814 | } | |
1815 | ||
1816 | /* Substitute ARGS into the nested requirement T. */ | |
1817 | ||
1818 | tree | |
1819 | tsubst_nested_requirement (tree t, tree args, | |
1820 | tsubst_flags_t complain, tree in_decl) | |
1821 | { | |
1822 | ++processing_template_decl; | |
1823 | tree expr = tsubst_expr (TREE_OPERAND (t, 0), args, complain, in_decl, false); | |
1824 | --processing_template_decl; | |
1825 | return finish_nested_requirement (expr); | |
1826 | } | |
1827 | ||
f078dc7d AS |
1828 | /* Substitute ARGS into the requirement T. */ |
1829 | ||
971e17ff AS |
1830 | inline tree |
1831 | tsubst_requirement (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
1832 | { | |
1833 | switch (TREE_CODE (t)) | |
1834 | { | |
1835 | case SIMPLE_REQ: | |
1836 | return tsubst_simple_requirement (t, args, complain, in_decl); | |
1837 | case TYPE_REQ: | |
1838 | return tsubst_type_requirement (t, args, complain, in_decl); | |
1839 | case COMPOUND_REQ: | |
1840 | return tsubst_compound_requirement (t, args, complain, in_decl); | |
1841 | case NESTED_REQ: | |
1842 | return tsubst_nested_requirement (t, args, complain, in_decl); | |
1843 | default: | |
1844 | gcc_unreachable (); | |
1845 | } | |
1846 | return error_mark_node; | |
1847 | } | |
1848 | ||
1849 | /* Substitute ARGS into the list of requirements T. Note that | |
1850 | substitution failures here result in ill-formed programs. */ | |
1851 | ||
1852 | tree | |
1853 | tsubst_requirement_body (tree t, tree args, | |
1854 | tsubst_flags_t complain, tree in_decl) | |
1855 | { | |
1856 | tree r = NULL_TREE; | |
1857 | while (t) | |
1858 | { | |
1859 | tree e = tsubst_requirement (TREE_VALUE (t), args, complain, in_decl); | |
1860 | if (e == error_mark_node) | |
1861 | return error_mark_node; | |
1862 | r = tree_cons (NULL_TREE, e, r); | |
1863 | t = TREE_CHAIN (t); | |
1864 | } | |
f078dc7d AS |
1865 | /* Ensure that the order of constraints is the same as the original. */ |
1866 | return nreverse (r); | |
971e17ff AS |
1867 | } |
1868 | ||
1869 | } /* namespace */ | |
1870 | ||
1871 | /* Substitute ARGS into the requires expression T. Note that this | |
1872 | results in the re-declaration of local parameters when | |
1873 | substituting through the parameter list. If either substitution | |
1874 | fails, the program is ill-formed. */ | |
1875 | ||
1876 | tree | |
1877 | tsubst_requires_expr (tree t, tree args, | |
1878 | tsubst_flags_t complain, tree in_decl) | |
1879 | { | |
1880 | local_specialization_stack stack; | |
1881 | ||
1882 | tree parms = TREE_OPERAND (t, 0); | |
1883 | if (parms) | |
1884 | { | |
1885 | parms = tsubst_constraint_variables (parms, args, complain, in_decl); | |
1886 | if (parms == error_mark_node) | |
1887 | return error_mark_node; | |
1888 | } | |
1889 | ||
1890 | tree reqs = TREE_OPERAND (t, 1); | |
1891 | reqs = tsubst_requirement_body (reqs, args, complain, in_decl); | |
1892 | if (reqs == error_mark_node) | |
1893 | return error_mark_node; | |
1894 | ||
1895 | return finish_requires_expr (parms, reqs); | |
1896 | } | |
1897 | ||
1898 | /* Substitute ARGS into the constraint information CI, producing a new | |
1899 | constraint record. */ | |
f078dc7d | 1900 | |
971e17ff AS |
1901 | tree |
1902 | tsubst_constraint_info (tree t, tree args, | |
1903 | tsubst_flags_t complain, tree in_decl) | |
1904 | { | |
1905 | if (!t || t == error_mark_node || !check_constraint_info (t)) | |
1906 | return NULL_TREE; | |
1907 | ||
1908 | tree tmpl_constr = NULL_TREE; | |
1909 | if (tree r = CI_TEMPLATE_REQS (t)) | |
1910 | tmpl_constr = tsubst_constraint (r, args, complain, in_decl); | |
1911 | ||
1912 | tree decl_constr = NULL_TREE; | |
1913 | if (tree r = CI_DECLARATOR_REQS (t)) | |
1914 | decl_constr = tsubst_constraint (r, args, complain, in_decl); | |
1915 | ||
1916 | return build_constraints (tmpl_constr, decl_constr); | |
1917 | } | |
1918 | ||
f078dc7d AS |
1919 | /* Substitute ARGS into the constraint T. */ |
1920 | ||
1921 | tree | |
1922 | tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
1923 | { | |
47790631 | 1924 | if (t == NULL_TREE || t == error_mark_node) |
f078dc7d AS |
1925 | return t; |
1926 | switch (TREE_CODE (t)) | |
1927 | { | |
1928 | case PRED_CONSTR: | |
1929 | return tsubst_predicate_constraint (t, args, complain, in_decl); | |
1930 | case CHECK_CONSTR: | |
1931 | return tsubst_check_constraint (t, args, complain, in_decl); | |
1932 | case CONJ_CONSTR: | |
1933 | case DISJ_CONSTR: | |
1934 | return tsubst_logical_operator (t, args, complain, in_decl); | |
1935 | case PARM_CONSTR: | |
1936 | return tsubst_parameterized_constraint (t, args, complain, in_decl); | |
1937 | case EXPR_CONSTR: | |
1938 | return tsubst_expr_constr (t, args, complain, in_decl); | |
1939 | case TYPE_CONSTR: | |
1940 | return tsubst_type_constr (t, args, complain, in_decl); | |
1941 | case ICONV_CONSTR: | |
1942 | return tsubst_implicit_conversion_constr (t, args, complain, in_decl); | |
1943 | case DEDUCT_CONSTR: | |
1944 | return tsubst_argument_deduction_constr (t, args, complain, in_decl); | |
1945 | case EXCEPT_CONSTR: | |
1946 | return tsubst_exception_constr (t, args, complain, in_decl); | |
1947 | default: | |
1948 | gcc_unreachable (); | |
1949 | } | |
1950 | return error_mark_node; | |
1951 | } | |
971e17ff AS |
1952 | |
1953 | /*--------------------------------------------------------------------------- | |
1954 | Constraint satisfaction | |
1955 | ---------------------------------------------------------------------------*/ | |
1956 | ||
1957 | /* The following functions determine if a constraint, when | |
1958 | substituting template arguments, is satisfied. For convenience, | |
1959 | satisfaction reduces a constraint to either true or false (and | |
1960 | nothing else). */ | |
1961 | ||
1962 | namespace { | |
1963 | ||
1964 | tree satisfy_constraint_1 (tree, tree, tsubst_flags_t, tree); | |
1965 | ||
1966 | /* Check the constraint pack expansion. */ | |
1967 | ||
1968 | tree | |
1969 | satisfy_pack_expansion (tree t, tree args, | |
1970 | tsubst_flags_t complain, tree in_decl) | |
1971 | { | |
1972 | /* Get the vector of satisfaction results. | |
1973 | gen_elem_of_pack_expansion_instantiation will check that each element of | |
1974 | the expansion is satisfied. */ | |
1975 | tree exprs = tsubst_pack_expansion (t, args, complain, in_decl); | |
f078dc7d | 1976 | |
971e17ff AS |
1977 | if (exprs == error_mark_node) |
1978 | return boolean_false_node; | |
971e17ff | 1979 | |
f078dc7d AS |
1980 | /* TODO: It might be better to normalize each expanded term |
1981 | and evaluate them separately. That would provide better | |
1982 | opportunities for diagnostics. */ | |
1983 | for (int i = 0; i < TREE_VEC_LENGTH (exprs); ++i) | |
971e17ff AS |
1984 | if (TREE_VEC_ELT (exprs, i) != boolean_true_node) |
1985 | return boolean_false_node; | |
1986 | return boolean_true_node; | |
1987 | } | |
1988 | ||
1989 | /* A predicate constraint is satisfied if its expression evaluates | |
1990 | to true. If substitution into that node fails, the constraint | |
1991 | is not satisfied ([temp.constr.pred]). | |
1992 | ||
1993 | Note that a predicate constraint is a constraint expression | |
1994 | of type bool. If neither of those are true, the program is | |
1995 | ill-formed; they are not SFINAE'able errors. */ | |
1996 | ||
1997 | tree | |
1998 | satisfy_predicate_constraint (tree t, tree args, | |
1999 | tsubst_flags_t complain, tree in_decl) | |
2000 | { | |
f078dc7d | 2001 | tree expr = TREE_OPERAND (t, 0); |
971e17ff AS |
2002 | |
2003 | /* We should never have a naked pack expansion in a predicate constraint. */ | |
f078dc7d | 2004 | gcc_assert (TREE_CODE (expr) != EXPR_PACK_EXPANSION); |
971e17ff | 2005 | |
f078dc7d AS |
2006 | /* If substitution into the expression fails, the constraint |
2007 | is not satisfied. */ | |
2008 | expr = tsubst_expr (expr, args, complain, in_decl, false); | |
971e17ff AS |
2009 | if (expr == error_mark_node) |
2010 | return boolean_false_node; | |
2011 | ||
2012 | /* A predicate constraint shall have type bool. In some | |
2013 | cases, substitution gives us const-qualified bool, which | |
2014 | is also acceptable. */ | |
2015 | tree type = cv_unqualified (TREE_TYPE (expr)); | |
2016 | if (!same_type_p (type, boolean_type_node)) | |
2017 | { | |
6bdfada4 | 2018 | error_at (cp_expr_loc_or_loc (expr, input_location), |
971e17ff AS |
2019 | "constraint %qE does not have type %qT", |
2020 | expr, boolean_type_node); | |
2021 | return boolean_false_node; | |
2022 | } | |
2023 | ||
f078dc7d AS |
2024 | return cxx_constant_value (expr); |
2025 | } | |
2026 | ||
2027 | /* A concept check constraint like C<CARGS> is satisfied if substituting ARGS | |
2028 | into CARGS succeeds and C is satisfied for the resulting arguments. */ | |
2029 | ||
2030 | tree | |
2031 | satisfy_check_constraint (tree t, tree args, | |
2032 | tsubst_flags_t complain, tree in_decl) | |
2033 | { | |
2034 | tree decl = CHECK_CONSTR_CONCEPT (t); | |
2035 | tree tmpl = DECL_TI_TEMPLATE (decl); | |
2036 | tree cargs = CHECK_CONSTR_ARGS (t); | |
2037 | ||
2038 | /* Instantiate the concept check arguments. */ | |
2039 | tree targs = tsubst (cargs, args, tf_none, NULL_TREE); | |
2040 | if (targs == error_mark_node) | |
2041 | return boolean_false_node; | |
2042 | ||
2043 | /* Search for a previous value. */ | |
2044 | if (tree prev = lookup_concept_satisfaction (tmpl, targs)) | |
2045 | return prev; | |
2046 | ||
2047 | /* Expand the concept; failure here implies non-satisfaction. */ | |
2048 | tree def = expand_concept (decl, targs); | |
2049 | if (def == error_mark_node) | |
2050 | return memoize_concept_satisfaction (tmpl, args, boolean_false_node); | |
2051 | ||
2052 | /* Recursively satisfy the constraint. */ | |
2053 | tree result = satisfy_constraint_1 (def, targs, complain, in_decl); | |
2054 | return memoize_concept_satisfaction (tmpl, targs, result); | |
971e17ff AS |
2055 | } |
2056 | ||
2057 | /* Check an expression constraint. The constraint is satisfied if | |
2058 | substitution succeeds ([temp.constr.expr]). | |
2059 | ||
2060 | Note that the expression is unevaluated. */ | |
2061 | ||
2062 | tree | |
2063 | satisfy_expression_constraint (tree t, tree args, | |
2064 | tsubst_flags_t complain, tree in_decl) | |
2065 | { | |
2066 | cp_unevaluated guard; | |
2067 | deferring_access_check_sentinel deferring; | |
2068 | ||
2069 | tree expr = EXPR_CONSTR_EXPR (t); | |
2070 | tree check = tsubst_expr (expr, args, complain, in_decl, false); | |
2071 | if (check == error_mark_node) | |
2072 | return boolean_false_node; | |
2073 | if (!perform_deferred_access_checks (tf_none)) | |
2074 | return boolean_false_node; | |
971e17ff AS |
2075 | return boolean_true_node; |
2076 | } | |
2077 | ||
2078 | /* Check a type constraint. The constraint is satisfied if | |
2079 | substitution succeeds. */ | |
2080 | ||
2081 | inline tree | |
2082 | satisfy_type_constraint (tree t, tree args, | |
2083 | tsubst_flags_t complain, tree in_decl) | |
2084 | { | |
2085 | deferring_access_check_sentinel deferring; | |
2086 | tree type = TYPE_CONSTR_TYPE (t); | |
2087 | gcc_assert (TYPE_P (type) || type == error_mark_node); | |
2088 | tree check = tsubst (type, args, complain, in_decl); | |
2089 | if (error_operand_p (check)) | |
2090 | return boolean_false_node; | |
2091 | if (!perform_deferred_access_checks (complain)) | |
2092 | return boolean_false_node; | |
971e17ff AS |
2093 | return boolean_true_node; |
2094 | } | |
2095 | ||
2096 | /* Check an implicit conversion constraint. */ | |
2097 | ||
2098 | tree | |
2099 | satisfy_implicit_conversion_constraint (tree t, tree args, | |
2100 | tsubst_flags_t complain, tree in_decl) | |
2101 | { | |
2102 | /* Don't tsubst as if we're processing a template. If we try | |
2103 | to we can end up generating template-like expressions | |
2104 | (e.g., modop-exprs) that aren't properly typed. */ | |
2105 | tree expr = | |
2106 | tsubst_expr (ICONV_CONSTR_EXPR (t), args, complain, in_decl, false); | |
2107 | if (expr == error_mark_node) | |
2108 | return boolean_false_node; | |
2109 | ||
2110 | /* Get the transformed target type. */ | |
2111 | tree type = tsubst (ICONV_CONSTR_TYPE (t), args, complain, in_decl); | |
2112 | if (type == error_mark_node) | |
2113 | return boolean_false_node; | |
2114 | ||
2115 | /* Attempt the conversion as a direct initialization | |
2116 | of the form TYPE <unspecified> = EXPR. */ | |
2117 | tree conv = | |
2118 | perform_direct_initialization_if_possible (type, expr, false, complain); | |
7717e0f1 | 2119 | if (conv == NULL_TREE || conv == error_mark_node) |
971e17ff AS |
2120 | return boolean_false_node; |
2121 | else | |
2122 | return boolean_true_node; | |
2123 | } | |
2124 | ||
2125 | /* Check an argument deduction constraint. */ | |
2126 | ||
2127 | tree | |
2128 | satisfy_argument_deduction_constraint (tree t, tree args, | |
2129 | tsubst_flags_t complain, tree in_decl) | |
2130 | { | |
2131 | /* Substitute through the expression. */ | |
2132 | tree expr = DEDUCT_CONSTR_EXPR (t); | |
2133 | tree init = tsubst_expr (expr, args, complain, in_decl, false); | |
2134 | if (expr == error_mark_node) | |
2135 | return boolean_false_node; | |
2136 | ||
2137 | /* Perform auto or decltype(auto) deduction to get the result. */ | |
2138 | tree pattern = DEDUCT_CONSTR_PATTERN (t); | |
2139 | tree placeholder = DEDUCT_CONSTR_PLACEHOLDER (t); | |
2140 | tree constr = PLACEHOLDER_TYPE_CONSTRAINTS (placeholder); | |
17c6c56b | 2141 | tree type_canonical = TYPE_CANONICAL (placeholder); |
971e17ff AS |
2142 | PLACEHOLDER_TYPE_CONSTRAINTS (placeholder) |
2143 | = tsubst_constraint (constr, args, complain|tf_partial, in_decl); | |
17c6c56b | 2144 | TYPE_CANONICAL (placeholder) = NULL_TREE; |
971e17ff AS |
2145 | tree type = do_auto_deduction (pattern, init, placeholder, |
2146 | complain, adc_requirement); | |
2147 | PLACEHOLDER_TYPE_CONSTRAINTS (placeholder) = constr; | |
17c6c56b | 2148 | TYPE_CANONICAL (placeholder) = type_canonical; |
971e17ff AS |
2149 | if (type == error_mark_node) |
2150 | return boolean_false_node; | |
2151 | ||
2152 | return boolean_true_node; | |
2153 | } | |
2154 | ||
2155 | /* Check an exception constraint. An exception constraint for an | |
2156 | expression e is satisfied when noexcept(e) is true. */ | |
2157 | ||
2158 | tree | |
2159 | satisfy_exception_constraint (tree t, tree args, | |
2160 | tsubst_flags_t complain, tree in_decl) | |
2161 | { | |
2162 | tree expr = EXCEPT_CONSTR_EXPR (t); | |
2163 | tree check = tsubst_expr (expr, args, complain, in_decl, false); | |
2164 | if (check == error_mark_node) | |
2165 | return boolean_false_node; | |
2166 | ||
2167 | if (expr_noexcept_p (check, complain)) | |
2168 | return boolean_true_node; | |
2169 | else | |
2170 | return boolean_false_node; | |
2171 | } | |
2172 | ||
2173 | /* Check a parameterized constraint. */ | |
2174 | ||
2175 | tree | |
2176 | satisfy_parameterized_constraint (tree t, tree args, | |
2177 | tsubst_flags_t complain, tree in_decl) | |
2178 | { | |
2179 | local_specialization_stack stack; | |
2180 | tree parms = PARM_CONSTR_PARMS (t); | |
2181 | tree vars = tsubst_constraint_variables (parms, args, complain, in_decl); | |
2182 | if (vars == error_mark_node) | |
2183 | return boolean_false_node; | |
2184 | tree constr = PARM_CONSTR_OPERAND (t); | |
2185 | return satisfy_constraint_1 (constr, args, complain, in_decl); | |
2186 | } | |
2187 | ||
2188 | /* Check that the conjunction of constraints is satisfied. Note | |
2189 | that if left operand is not satisfied, the right operand | |
2190 | is not checked. | |
2191 | ||
2192 | FIXME: Check that this wouldn't result in a user-defined | |
2193 | operator. Note that this error is partially diagnosed in | |
2194 | satisfy_predicate_constraint. It would be nice to diagnose | |
2195 | the overload, but I don't think it's strictly necessary. */ | |
2196 | ||
2197 | tree | |
2198 | satisfy_conjunction (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
2199 | { | |
2200 | tree t0 = satisfy_constraint_1 (TREE_OPERAND (t, 0), args, complain, in_decl); | |
2201 | if (t0 == boolean_false_node) | |
f078dc7d AS |
2202 | return boolean_false_node; |
2203 | return satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl); | |
971e17ff AS |
2204 | } |
2205 | ||
2206 | /* Check that the disjunction of constraints is satisfied. Note | |
2207 | that if the left operand is satisfied, the right operand is not | |
2208 | checked. */ | |
2209 | ||
2210 | tree | |
2211 | satisfy_disjunction (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
2212 | { | |
2213 | tree t0 = satisfy_constraint_1 (TREE_OPERAND (t, 0), args, complain, in_decl); | |
2214 | if (t0 == boolean_true_node) | |
2215 | return boolean_true_node; | |
f078dc7d | 2216 | return satisfy_constraint_1 (TREE_OPERAND (t, 1), args, complain, in_decl); |
971e17ff AS |
2217 | } |
2218 | ||
2219 | /* Dispatch to an appropriate satisfaction routine depending on the | |
2220 | tree code of T. */ | |
2221 | ||
2222 | tree | |
2223 | satisfy_constraint_1 (tree t, tree args, tsubst_flags_t complain, tree in_decl) | |
2224 | { | |
2225 | gcc_assert (!processing_template_decl); | |
2226 | ||
2227 | if (!t) | |
2228 | return boolean_false_node; | |
2229 | ||
2230 | if (t == error_mark_node) | |
2231 | return boolean_false_node; | |
2232 | ||
2233 | switch (TREE_CODE (t)) | |
2234 | { | |
2235 | case PRED_CONSTR: | |
2236 | return satisfy_predicate_constraint (t, args, complain, in_decl); | |
2237 | ||
f078dc7d AS |
2238 | case CHECK_CONSTR: |
2239 | return satisfy_check_constraint (t, args, complain, in_decl); | |
2240 | ||
971e17ff AS |
2241 | case EXPR_CONSTR: |
2242 | return satisfy_expression_constraint (t, args, complain, in_decl); | |
2243 | ||
2244 | case TYPE_CONSTR: | |
2245 | return satisfy_type_constraint (t, args, complain, in_decl); | |
2246 | ||
2247 | case ICONV_CONSTR: | |
2248 | return satisfy_implicit_conversion_constraint (t, args, complain, in_decl); | |
2249 | ||
2250 | case DEDUCT_CONSTR: | |
2251 | return satisfy_argument_deduction_constraint (t, args, complain, in_decl); | |
2252 | ||
2253 | case EXCEPT_CONSTR: | |
2254 | return satisfy_exception_constraint (t, args, complain, in_decl); | |
2255 | ||
2256 | case PARM_CONSTR: | |
2257 | return satisfy_parameterized_constraint (t, args, complain, in_decl); | |
2258 | ||
2259 | case CONJ_CONSTR: | |
2260 | return satisfy_conjunction (t, args, complain, in_decl); | |
2261 | ||
2262 | case DISJ_CONSTR: | |
2263 | return satisfy_disjunction (t, args, complain, in_decl); | |
2264 | ||
2265 | case EXPR_PACK_EXPANSION: | |
2266 | return satisfy_pack_expansion (t, args, complain, in_decl); | |
2267 | ||
2268 | default: | |
2269 | gcc_unreachable (); | |
2270 | } | |
2271 | return boolean_false_node; | |
2272 | } | |
2273 | ||
2274 | /* Check that the constraint is satisfied, according to the rules | |
2275 | for that constraint. Note that each satisfy_* function returns | |
2276 | true or false, depending on whether it is satisfied or not. */ | |
2277 | ||
2278 | tree | |
2279 | satisfy_constraint (tree t, tree args) | |
2280 | { | |
f078dc7d AS |
2281 | auto_timevar time (TV_CONSTRAINT_SAT); |
2282 | ||
971e17ff | 2283 | /* Turn off template processing. Constraint satisfaction only applies |
f078dc7d AS |
2284 | to non-dependent terms, so we want to ensure full checking here. */ |
2285 | processing_template_decl_sentinel proc (true); | |
2286 | ||
971e17ff AS |
2287 | /* Avoid early exit in tsubst and tsubst_copy from null args; since earlier |
2288 | substitution was done with processing_template_decl forced on, there will | |
2289 | be expressions that still need semantic processing, possibly buried in | |
2290 | decltype or a template argument. */ | |
2291 | if (args == NULL_TREE) | |
2292 | args = make_tree_vec (1); | |
f078dc7d | 2293 | |
971e17ff AS |
2294 | return satisfy_constraint_1 (t, args, tf_none, NULL_TREE); |
2295 | } | |
2296 | ||
2297 | /* Check the associated constraints in CI against the given | |
2298 | ARGS, returning true when the constraints are satisfied | |
2299 | and false otherwise. */ | |
2300 | ||
2301 | tree | |
2302 | satisfy_associated_constraints (tree ci, tree args) | |
2303 | { | |
2304 | /* If there are no constraints then this is trivially satisfied. */ | |
2305 | if (!ci) | |
2306 | return boolean_true_node; | |
2307 | ||
2308 | /* If any arguments depend on template parameters, we can't | |
2309 | check constraints. */ | |
2310 | if (args && uses_template_parms (args)) | |
2311 | return boolean_true_node; | |
2312 | ||
f078dc7d AS |
2313 | /* Check if we've seen a previous result. */ |
2314 | if (tree prev = lookup_constraint_satisfaction (ci, args)) | |
2315 | return prev; | |
971e17ff | 2316 | |
f078dc7d AS |
2317 | /* Actually test for satisfaction. */ |
2318 | tree result = satisfy_constraint (CI_ASSOCIATED_CONSTRAINTS (ci), args); | |
2319 | return memoize_constraint_satisfaction (ci, args, result); | |
971e17ff AS |
2320 | } |
2321 | ||
2322 | } /* namespace */ | |
2323 | ||
2324 | /* Evaluate the given constraint, returning boolean_true_node | |
2325 | if the constraint is satisfied and boolean_false_node | |
2326 | otherwise. */ | |
2327 | ||
2328 | tree | |
2329 | evaluate_constraints (tree constr, tree args) | |
2330 | { | |
2331 | gcc_assert (constraint_p (constr)); | |
f078dc7d | 2332 | return satisfy_constraint (constr, args); |
971e17ff AS |
2333 | } |
2334 | ||
2335 | /* Evaluate the function concept FN by substituting its own args | |
2336 | into its definition and evaluating that as the result. Returns | |
2337 | boolean_true_node if the constraints are satisfied and | |
2338 | boolean_false_node otherwise. */ | |
2339 | ||
2340 | tree | |
2341 | evaluate_function_concept (tree fn, tree args) | |
2342 | { | |
f078dc7d | 2343 | tree constr = build_nt (CHECK_CONSTR, fn, args); |
971e17ff AS |
2344 | return satisfy_constraint (constr, args); |
2345 | } | |
2346 | ||
2347 | /* Evaluate the variable concept VAR by substituting its own args into | |
2348 | its initializer and checking the resulting constraint. Returns | |
2349 | boolean_true_node if the constraints are satisfied and | |
2350 | boolean_false_node otherwise. */ | |
2351 | ||
2352 | tree | |
f078dc7d | 2353 | evaluate_variable_concept (tree var, tree args) |
971e17ff | 2354 | { |
f078dc7d | 2355 | tree constr = build_nt (CHECK_CONSTR, var, args); |
971e17ff AS |
2356 | return satisfy_constraint (constr, args); |
2357 | } | |
2358 | ||
2359 | /* Evaluate the given expression as if it were a predicate | |
2360 | constraint. Returns boolean_true_node if the constraint | |
2361 | is satisfied and boolean_false_node otherwise. */ | |
2362 | ||
2363 | tree | |
2364 | evaluate_constraint_expression (tree expr, tree args) | |
2365 | { | |
f078dc7d | 2366 | tree constr = normalize_expression (expr); |
971e17ff AS |
2367 | return satisfy_constraint (constr, args); |
2368 | } | |
2369 | ||
2370 | /* Returns true if the DECL's constraints are satisfied. | |
2371 | This is used in cases where a declaration is formed but | |
2372 | before it is used (e.g., overload resolution). */ | |
2373 | ||
2374 | bool | |
2375 | constraints_satisfied_p (tree decl) | |
2376 | { | |
2377 | /* Get the constraints to check for satisfaction. This depends | |
2378 | on whether we're looking at a template specialization or not. */ | |
2379 | tree ci; | |
2380 | tree args = NULL_TREE; | |
2381 | if (tree ti = DECL_TEMPLATE_INFO (decl)) | |
2382 | { | |
2befd3f7 JM |
2383 | tree tmpl = TI_TEMPLATE (ti); |
2384 | ci = get_constraints (tmpl); | |
2385 | int depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); | |
2386 | args = get_innermost_template_args (TI_ARGS (ti), depth); | |
971e17ff AS |
2387 | } |
2388 | else | |
2389 | { | |
2390 | ci = get_constraints (decl); | |
2391 | } | |
2392 | ||
2393 | tree eval = satisfy_associated_constraints (ci, args); | |
2394 | return eval == boolean_true_node; | |
2395 | } | |
2396 | ||
2397 | /* Returns true if the constraints are satisfied by ARGS. | |
2398 | Here, T can be either a constraint or a constrained | |
2399 | declaration. */ | |
2400 | ||
2401 | bool | |
2402 | constraints_satisfied_p (tree t, tree args) | |
2403 | { | |
2404 | tree eval; | |
2405 | if (constraint_p (t)) | |
2406 | eval = evaluate_constraints (t, args); | |
2407 | else | |
2408 | eval = satisfy_associated_constraints (get_constraints (t), args); | |
2409 | return eval == boolean_true_node; | |
2410 | } | |
2411 | ||
2412 | namespace | |
2413 | { | |
2414 | ||
2415 | /* Normalize EXPR and determine if the resulting constraint is | |
2416 | satisfied by ARGS. Returns true if and only if the constraint | |
2417 | is satisfied. This is used extensively by diagnostics to | |
2418 | determine causes for failure. */ | |
2419 | ||
2420 | inline bool | |
2421 | constraint_expression_satisfied_p (tree expr, tree args) | |
2422 | { | |
2423 | return evaluate_constraint_expression (expr, args) == boolean_true_node; | |
2424 | } | |
2425 | ||
2426 | } /* namespace */ | |
2427 | ||
971e17ff AS |
2428 | /*--------------------------------------------------------------------------- |
2429 | Semantic analysis of requires-expressions | |
2430 | ---------------------------------------------------------------------------*/ | |
2431 | ||
2432 | /* Finish a requires expression for the given PARMS (possibly | |
2433 | null) and the non-empty sequence of requirements. */ | |
2434 | tree | |
2435 | finish_requires_expr (tree parms, tree reqs) | |
2436 | { | |
2437 | /* Modify the declared parameters by removing their context | |
2438 | so they don't refer to the enclosing scope and explicitly | |
2439 | indicating that they are constraint variables. */ | |
2440 | for (tree parm = parms; parm; parm = DECL_CHAIN (parm)) | |
2441 | { | |
2442 | DECL_CONTEXT (parm) = NULL_TREE; | |
2443 | CONSTRAINT_VAR_P (parm) = true; | |
2444 | } | |
2445 | ||
2446 | /* Build the node. */ | |
2447 | tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs); | |
2448 | TREE_SIDE_EFFECTS (r) = false; | |
2449 | TREE_CONSTANT (r) = true; | |
2450 | return r; | |
2451 | } | |
2452 | ||
2453 | /* Construct a requirement for the validity of EXPR. */ | |
2454 | tree | |
2455 | finish_simple_requirement (tree expr) | |
2456 | { | |
2457 | return build_nt (SIMPLE_REQ, expr); | |
2458 | } | |
2459 | ||
2460 | /* Construct a requirement for the validity of TYPE. */ | |
2461 | tree | |
2462 | finish_type_requirement (tree type) | |
2463 | { | |
2464 | return build_nt (TYPE_REQ, type); | |
2465 | } | |
2466 | ||
2467 | /* Construct a requirement for the validity of EXPR, along with | |
2468 | its properties. if TYPE is non-null, then it specifies either | |
2469 | an implicit conversion or argument deduction constraint, | |
2470 | depending on whether any placeholders occur in the type name. | |
2471 | NOEXCEPT_P is true iff the noexcept keyword was specified. */ | |
2472 | tree | |
2473 | finish_compound_requirement (tree expr, tree type, bool noexcept_p) | |
2474 | { | |
2475 | tree req = build_nt (COMPOUND_REQ, expr, type); | |
2476 | COMPOUND_REQ_NOEXCEPT_P (req) = noexcept_p; | |
2477 | return req; | |
2478 | } | |
2479 | ||
2480 | /* Finish a nested requirement. */ | |
2481 | tree | |
2482 | finish_nested_requirement (tree expr) | |
2483 | { | |
2484 | return build_nt (NESTED_REQ, expr); | |
2485 | } | |
2486 | ||
2487 | // Check that FN satisfies the structural requirements of a | |
2488 | // function concept definition. | |
2489 | tree | |
2490 | check_function_concept (tree fn) | |
2491 | { | |
2492 | // Check that the function is comprised of only a single | |
2493 | // return statement. | |
2494 | tree body = DECL_SAVED_TREE (fn); | |
2495 | if (TREE_CODE (body) == BIND_EXPR) | |
2496 | body = BIND_EXPR_BODY (body); | |
2497 | ||
2498 | // Sometimes a function call results in the creation of clean up | |
2499 | // points. Allow these to be preserved in the body of the | |
2500 | // constraint, as we might actually need them for some constexpr | |
2501 | // evaluations. | |
2502 | if (TREE_CODE (body) == CLEANUP_POINT_EXPR) | |
2503 | body = TREE_OPERAND (body, 0); | |
2504 | ||
2505 | /* Check that the definition is written correctly. */ | |
2506 | if (TREE_CODE (body) != RETURN_EXPR) | |
2507 | { | |
2508 | location_t loc = DECL_SOURCE_LOCATION (fn); | |
2509 | if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body)) | |
4d612bfd JM |
2510 | { |
2511 | if (seen_error ()) | |
2512 | /* The definition was probably erroneous, not empty. */; | |
2513 | else | |
2514 | error_at (loc, "definition of concept %qD is empty", fn); | |
2515 | } | |
971e17ff AS |
2516 | else |
2517 | error_at (loc, "definition of concept %qD has multiple statements", fn); | |
2518 | } | |
2519 | ||
2520 | return NULL_TREE; | |
2521 | } | |
2522 | ||
2523 | ||
2524 | // Check that a constrained friend declaration function declaration, | |
2525 | // FN, is admissible. This is the case only when the declaration depends | |
2526 | // on template parameters and does not declare a specialization. | |
2527 | void | |
2528 | check_constrained_friend (tree fn, tree reqs) | |
2529 | { | |
2530 | if (fn == error_mark_node) | |
2531 | return; | |
2532 | gcc_assert (TREE_CODE (fn) == FUNCTION_DECL); | |
2533 | ||
2534 | // If there are not constraints, this cannot be an error. | |
2535 | if (!reqs) | |
2536 | return; | |
2537 | ||
2538 | // Constrained friend functions that don't depend on template | |
2539 | // arguments are effectively meaningless. | |
2540 | if (!uses_template_parms (TREE_TYPE (fn))) | |
2541 | { | |
2542 | error_at (location_of (fn), | |
2543 | "constrained friend does not depend on template parameters"); | |
2544 | return; | |
2545 | } | |
2546 | } | |
2547 | ||
2548 | /*--------------------------------------------------------------------------- | |
2549 | Equivalence of constraints | |
2550 | ---------------------------------------------------------------------------*/ | |
2551 | ||
2552 | /* Returns true when A and B are equivalent constraints. */ | |
2553 | bool | |
2554 | equivalent_constraints (tree a, tree b) | |
2555 | { | |
2556 | gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO); | |
2557 | gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO); | |
2558 | return cp_tree_equal (a, b); | |
2559 | } | |
2560 | ||
2561 | /* Returns true if the template declarations A and B have equivalent | |
2562 | constraints. This is the case when A's constraints subsume B's and | |
2563 | when B's also constrain A's. */ | |
2564 | bool | |
2565 | equivalently_constrained (tree d1, tree d2) | |
2566 | { | |
2567 | gcc_assert (TREE_CODE (d1) == TREE_CODE (d2)); | |
2568 | return equivalent_constraints (get_constraints (d1), get_constraints (d2)); | |
2569 | } | |
2570 | ||
2571 | /*--------------------------------------------------------------------------- | |
2572 | Partial ordering of constraints | |
2573 | ---------------------------------------------------------------------------*/ | |
2574 | ||
2575 | /* Returns true when the the constraints in A subsume those in B. */ | |
f078dc7d | 2576 | |
971e17ff AS |
2577 | bool |
2578 | subsumes_constraints (tree a, tree b) | |
2579 | { | |
2580 | gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO); | |
2581 | gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO); | |
2582 | return subsumes (a, b); | |
2583 | } | |
2584 | ||
aabdb831 JM |
2585 | /* Returns true when the the constraints in A subsume those in B, but |
2586 | the constraints in B do not subsume the constraints in A. */ | |
2587 | ||
2588 | bool | |
2589 | strictly_subsumes (tree a, tree b) | |
2590 | { | |
2591 | return subsumes (a, b) && !subsumes (b, a); | |
2592 | } | |
2593 | ||
971e17ff AS |
2594 | /* Determines which of the declarations, A or B, is more constrained. |
2595 | That is, which declaration's constraints subsume but are not subsumed | |
2596 | by the other's? | |
2597 | ||
2598 | Returns 1 if A is more constrained than B, -1 if B is more constrained | |
2599 | than A, and 0 otherwise. */ | |
f078dc7d | 2600 | |
971e17ff AS |
2601 | int |
2602 | more_constrained (tree d1, tree d2) | |
2603 | { | |
2604 | tree c1 = get_constraints (d1); | |
2605 | tree c2 = get_constraints (d2); | |
2606 | int winner = 0; | |
2607 | if (subsumes_constraints (c1, c2)) | |
2608 | ++winner; | |
2609 | if (subsumes_constraints (c2, c1)) | |
2610 | --winner; | |
2611 | return winner; | |
2612 | } | |
2613 | ||
2614 | /* Returns true if D1 is at least as constrained as D2. That is, the | |
2615 | associated constraints of D1 subsume those of D2, or both declarations | |
2616 | are unconstrained. */ | |
f078dc7d | 2617 | |
971e17ff AS |
2618 | bool |
2619 | at_least_as_constrained (tree d1, tree d2) | |
2620 | { | |
2621 | tree c1 = get_constraints (d1); | |
2622 | tree c2 = get_constraints (d2); | |
2623 | return subsumes_constraints (c1, c2); | |
2624 | } | |
2625 | ||
2626 | ||
2627 | /*--------------------------------------------------------------------------- | |
2628 | Constraint diagnostics | |
f078dc7d AS |
2629 | |
2630 | FIXME: Normalize expressions into constraints before evaluating them. | |
2631 | This should be the general pattern for all such diagnostics. | |
971e17ff AS |
2632 | ---------------------------------------------------------------------------*/ |
2633 | ||
f078dc7d | 2634 | /* The number of detailed constraint failures. */ |
971e17ff | 2635 | |
f078dc7d | 2636 | int constraint_errors = 0; |
971e17ff | 2637 | |
f078dc7d AS |
2638 | /* Do not generate errors after diagnosing this number of constraint |
2639 | failures. | |
971e17ff | 2640 | |
f078dc7d AS |
2641 | FIXME: This is a really arbitrary number. Provide better control of |
2642 | constraint diagnostics with a command line option. */ | |
971e17ff | 2643 | |
f078dc7d | 2644 | int constraint_thresh = 20; |
971e17ff | 2645 | |
f078dc7d AS |
2646 | |
2647 | /* Returns true if we should elide the diagnostic for a constraint failure. | |
2648 | This is the case when the number of errors has exceeded the pre-configured | |
2649 | threshold. */ | |
2650 | ||
2651 | inline bool | |
2652 | elide_constraint_failure_p () | |
2653 | { | |
2654 | bool ret = constraint_thresh <= constraint_errors; | |
2655 | ++constraint_errors; | |
2656 | return ret; | |
2657 | } | |
2658 | ||
2659 | /* Returns the number of undiagnosed errors. */ | |
2660 | ||
2661 | inline int | |
2662 | undiagnosed_constraint_failures () | |
971e17ff | 2663 | { |
f078dc7d | 2664 | return constraint_errors - constraint_thresh; |
971e17ff AS |
2665 | } |
2666 | ||
f078dc7d AS |
2667 | /* The diagnosis of constraints performs a combination of normalization |
2668 | and satisfaction testing. We recursively walk through the conjunction or | |
2669 | disjunction of associated constraints, testing each sub-constraint in | |
2670 | turn. */ | |
2671 | ||
2672 | namespace { | |
2673 | ||
2674 | void diagnose_constraint (location_t, tree, tree, tree); | |
2675 | ||
2676 | /* Emit a specific diagnostics for a failed trait. */ | |
2677 | ||
971e17ff | 2678 | void |
f078dc7d | 2679 | diagnose_trait_expression (location_t loc, tree, tree cur, tree args) |
971e17ff | 2680 | { |
f078dc7d AS |
2681 | if (constraint_expression_satisfied_p (cur, args)) |
2682 | return; | |
2683 | if (elide_constraint_failure_p()) | |
971e17ff AS |
2684 | return; |
2685 | ||
f078dc7d | 2686 | tree expr = PRED_CONSTR_EXPR (cur); |
971e17ff | 2687 | ++processing_template_decl; |
f078dc7d | 2688 | expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false); |
971e17ff AS |
2689 | --processing_template_decl; |
2690 | ||
2691 | tree t1 = TRAIT_EXPR_TYPE1 (expr); | |
2692 | tree t2 = TRAIT_EXPR_TYPE2 (expr); | |
f078dc7d | 2693 | switch (TRAIT_EXPR_KIND (expr)) |
971e17ff AS |
2694 | { |
2695 | case CPTK_HAS_NOTHROW_ASSIGN: | |
2696 | inform (loc, " %qT is not nothrow copy assignable", t1); | |
2697 | break; | |
2698 | case CPTK_HAS_NOTHROW_CONSTRUCTOR: | |
2699 | inform (loc, " %qT is not nothrow default constructible", t1); | |
2700 | break; | |
2701 | case CPTK_HAS_NOTHROW_COPY: | |
2702 | inform (loc, " %qT is not nothrow copy constructible", t1); | |
2703 | break; | |
2704 | case CPTK_HAS_TRIVIAL_ASSIGN: | |
2705 | inform (loc, " %qT is not trivially copy assignable", t1); | |
2706 | break; | |
2707 | case CPTK_HAS_TRIVIAL_CONSTRUCTOR: | |
2708 | inform (loc, " %qT is not trivially default constructible", t1); | |
2709 | break; | |
2710 | case CPTK_HAS_TRIVIAL_COPY: | |
2711 | inform (loc, " %qT is not trivially copy constructible", t1); | |
2712 | break; | |
2713 | case CPTK_HAS_TRIVIAL_DESTRUCTOR: | |
2714 | inform (loc, " %qT is not trivially destructible", t1); | |
2715 | break; | |
2716 | case CPTK_HAS_VIRTUAL_DESTRUCTOR: | |
2717 | inform (loc, " %qT does not have a virtual destructor", t1); | |
2718 | break; | |
2719 | case CPTK_IS_ABSTRACT: | |
2720 | inform (loc, " %qT is not an abstract class", t1); | |
2721 | break; | |
2722 | case CPTK_IS_BASE_OF: | |
2723 | inform (loc, " %qT is not a base of %qT", t1, t2); | |
2724 | break; | |
2725 | case CPTK_IS_CLASS: | |
2726 | inform (loc, " %qT is not a class", t1); | |
2727 | break; | |
2728 | case CPTK_IS_EMPTY: | |
2729 | inform (loc, " %qT is not an empty class", t1); | |
2730 | break; | |
2731 | case CPTK_IS_ENUM: | |
2732 | inform (loc, " %qT is not an enum", t1); | |
2733 | break; | |
2734 | case CPTK_IS_FINAL: | |
2735 | inform (loc, " %qT is not a final class", t1); | |
2736 | break; | |
2737 | case CPTK_IS_LITERAL_TYPE: | |
2738 | inform (loc, " %qT is not a literal type", t1); | |
2739 | break; | |
2740 | case CPTK_IS_POD: | |
2741 | inform (loc, " %qT is not a POD type", t1); | |
2742 | break; | |
2743 | case CPTK_IS_POLYMORPHIC: | |
2744 | inform (loc, " %qT is not a polymorphic type", t1); | |
2745 | break; | |
2746 | case CPTK_IS_SAME_AS: | |
2747 | inform (loc, " %qT is not the same as %qT", t1, t2); | |
2748 | break; | |
2749 | case CPTK_IS_STD_LAYOUT: | |
2750 | inform (loc, " %qT is not an standard layout type", t1); | |
2751 | break; | |
2752 | case CPTK_IS_TRIVIAL: | |
2753 | inform (loc, " %qT is not a trivial type", t1); | |
2754 | break; | |
2755 | case CPTK_IS_UNION: | |
2756 | inform (loc, " %qT is not a union", t1); | |
2757 | break; | |
2758 | default: | |
2759 | gcc_unreachable (); | |
2760 | } | |
2761 | } | |
2762 | ||
f078dc7d | 2763 | /* Diagnose the expression of a predicate constraint. */ |
971e17ff | 2764 | |
971e17ff | 2765 | void |
f078dc7d | 2766 | diagnose_other_expression (location_t loc, tree, tree cur, tree args) |
971e17ff | 2767 | { |
f078dc7d | 2768 | if (constraint_expression_satisfied_p (cur, args)) |
971e17ff | 2769 | return; |
f078dc7d | 2770 | if (elide_constraint_failure_p()) |
971e17ff | 2771 | return; |
f078dc7d AS |
2772 | inform (loc, "%qE evaluated to false", cur); |
2773 | } | |
971e17ff | 2774 | |
f078dc7d | 2775 | /* Do our best to infer meaning from predicates. */ |
971e17ff | 2776 | |
f078dc7d AS |
2777 | inline void |
2778 | diagnose_predicate_constraint (location_t loc, tree orig, tree cur, tree args) | |
2779 | { | |
2780 | if (TREE_CODE (PRED_CONSTR_EXPR (cur)) == TRAIT_EXPR) | |
2781 | diagnose_trait_expression (loc, orig, cur, args); | |
971e17ff | 2782 | else |
f078dc7d | 2783 | diagnose_other_expression (loc, orig, cur, args); |
971e17ff AS |
2784 | } |
2785 | ||
f078dc7d | 2786 | /* Diagnose a failed pack expansion, possibly containing constraints. */ |
971e17ff | 2787 | |
971e17ff | 2788 | void |
f078dc7d | 2789 | diagnose_pack_expansion (location_t loc, tree, tree cur, tree args) |
971e17ff | 2790 | { |
f078dc7d | 2791 | if (constraint_expression_satisfied_p (cur, args)) |
971e17ff | 2792 | return; |
f078dc7d | 2793 | if (elide_constraint_failure_p()) |
971e17ff AS |
2794 | return; |
2795 | ||
2796 | /* Make sure that we don't have naked packs that we don't expect. */ | |
f078dc7d | 2797 | if (!same_type_p (TREE_TYPE (cur), boolean_type_node)) |
971e17ff | 2798 | { |
f078dc7d | 2799 | inform (loc, "invalid pack expansion in constraint %qE", cur); |
971e17ff AS |
2800 | return; |
2801 | } | |
2802 | ||
f078dc7d | 2803 | inform (loc, "in the expansion of %qE", cur); |
971e17ff AS |
2804 | |
2805 | /* Get the vector of expanded arguments. Note that n must not | |
2806 | be 0 since this constraint is not satisfied. */ | |
2807 | ++processing_template_decl; | |
f078dc7d | 2808 | tree exprs = tsubst_pack_expansion (cur, args, tf_none, NULL_TREE); |
971e17ff AS |
2809 | --processing_template_decl; |
2810 | if (exprs == error_mark_node) | |
2811 | { | |
2812 | /* TODO: This error message could be better. */ | |
2813 | inform (loc, " substitution failure occurred during expansion"); | |
2814 | return; | |
2815 | } | |
2816 | ||
2817 | /* Check each expanded constraint separately. */ | |
2818 | int n = TREE_VEC_LENGTH (exprs); | |
2819 | for (int i = 0; i < n; ++i) | |
2820 | { | |
2821 | tree expr = TREE_VEC_ELT (exprs, i); | |
2822 | if (!constraint_expression_satisfied_p (expr, args)) | |
2823 | inform (loc, " %qE was not satisfied", expr); | |
2824 | } | |
2825 | } | |
2826 | ||
f078dc7d AS |
2827 | /* Diagnose a potentially unsatisfied concept check constraint DECL<CARGS>. |
2828 | Parameters are as for diagnose_constraint. */ | |
2829 | ||
971e17ff | 2830 | void |
f078dc7d | 2831 | diagnose_check_constraint (location_t loc, tree orig, tree cur, tree args) |
971e17ff | 2832 | { |
f078dc7d | 2833 | if (constraints_satisfied_p (cur, args)) |
971e17ff | 2834 | return; |
f078dc7d AS |
2835 | |
2836 | tree decl = CHECK_CONSTR_CONCEPT (cur); | |
2837 | tree cargs = CHECK_CONSTR_ARGS (cur); | |
2838 | tree tmpl = DECL_TI_TEMPLATE (decl); | |
2839 | tree check = build_nt (CHECK_CONSTR, decl, cargs); | |
2840 | ||
2841 | /* Instantiate the concept check arguments. */ | |
2842 | tree targs = tsubst (cargs, args, tf_none, NULL_TREE); | |
2843 | if (targs == error_mark_node) | |
2844 | { | |
2845 | if (elide_constraint_failure_p ()) | |
2846 | return; | |
2847 | inform (loc, "invalid use of the concept %qE", check); | |
2848 | tsubst (cargs, args, tf_warning_or_error, NULL_TREE); | |
2849 | return; | |
2850 | } | |
2851 | ||
2852 | tree sub = build_tree_list (tmpl, targs); | |
2853 | /* Update to the expanded definitions. */ | |
2854 | cur = expand_concept (decl, targs); | |
2855 | if (cur == error_mark_node) | |
2856 | { | |
2857 | if (elide_constraint_failure_p ()) | |
2858 | return; | |
0f05d905 | 2859 | inform (loc, "in the expansion of concept %<%E %S%>", check, sub); |
f078dc7d AS |
2860 | cur = get_concept_definition (decl); |
2861 | tsubst_expr (cur, targs, tf_warning_or_error, NULL_TREE, false); | |
2862 | return; | |
2863 | } | |
2864 | ||
2865 | orig = get_concept_definition (CHECK_CONSTR_CONCEPT (orig)); | |
2866 | orig = normalize_expression (orig); | |
2867 | ||
2868 | location_t dloc = DECL_SOURCE_LOCATION (decl); | |
2869 | inform (dloc, "within %qS", sub); | |
2870 | diagnose_constraint (dloc, orig, cur, targs); | |
971e17ff AS |
2871 | } |
2872 | ||
f078dc7d AS |
2873 | /* Diagnose a potentially unsatisfied conjunction or disjunction. Parameters |
2874 | are as for diagnose_constraint. */ | |
2875 | ||
971e17ff | 2876 | void |
f078dc7d | 2877 | diagnose_logical_constraint (location_t loc, tree orig, tree cur, tree args) |
971e17ff | 2878 | { |
f078dc7d AS |
2879 | tree t0 = TREE_OPERAND (cur, 0); |
2880 | tree t1 = TREE_OPERAND (cur, 1); | |
2881 | if (!constraints_satisfied_p (t0, args)) | |
2882 | diagnose_constraint (loc, TREE_OPERAND (orig, 0), t0, args); | |
2883 | else if (TREE_CODE (orig) == TRUTH_ORIF_EXPR) | |
2884 | return; | |
2885 | if (!constraints_satisfied_p (t1, args)) | |
2886 | diagnose_constraint (loc, TREE_OPERAND (orig, 1), t1, args); | |
2887 | } | |
971e17ff | 2888 | |
f078dc7d | 2889 | /* Diagnose a potential expression constraint failure. */ |
971e17ff | 2890 | |
f078dc7d AS |
2891 | void |
2892 | diagnose_expression_constraint (location_t loc, tree orig, tree cur, tree args) | |
2893 | { | |
2894 | if (constraints_satisfied_p (cur, args)) | |
2895 | return; | |
2896 | if (elide_constraint_failure_p()) | |
2897 | return; | |
971e17ff | 2898 | |
f078dc7d AS |
2899 | tree expr = EXPR_CONSTR_EXPR (orig); |
2900 | inform (loc, "the required expression %qE would be ill-formed", expr); | |
971e17ff | 2901 | |
f078dc7d AS |
2902 | // TODO: We should have a flag that controls this substitution. |
2903 | // I'm finding it very useful for resolving concept check errors. | |
971e17ff | 2904 | |
f078dc7d AS |
2905 | // inform (input_location, "==== BEGIN DUMP ===="); |
2906 | // tsubst_expr (EXPR_CONSTR_EXPR (orig), args, tf_warning_or_error, NULL_TREE, false); | |
2907 | // inform (input_location, "==== END DUMP ===="); | |
2908 | } | |
971e17ff | 2909 | |
f078dc7d | 2910 | /* Diagnose a potentially failed type constraint. */ |
971e17ff | 2911 | |
f078dc7d AS |
2912 | void |
2913 | diagnose_type_constraint (location_t loc, tree orig, tree cur, tree args) | |
2914 | { | |
2915 | if (constraints_satisfied_p (cur, args)) | |
2916 | return; | |
2917 | if (elide_constraint_failure_p()) | |
2918 | return; | |
2919 | ||
2920 | tree type = TYPE_CONSTR_TYPE (orig); | |
2921 | inform (loc, "the required type %qT would be ill-formed", type); | |
2922 | } | |
2923 | ||
2924 | /* Diagnose a potentially unsatisfied conversion constraint. */ | |
2925 | ||
2926 | void | |
2927 | diagnose_implicit_conversion_constraint (location_t loc, tree orig, tree cur, | |
2928 | tree args) | |
2929 | { | |
2930 | if (constraints_satisfied_p (cur, args)) | |
2931 | return; | |
2932 | ||
2933 | /* The expression and type will previously have been substituted into, | |
2934 | and therefore may already be an error. Also, we will have already | |
2935 | diagnosed substitution failures into an expression since this must be | |
2936 | part of a compound requirement. */ | |
2937 | tree expr = ICONV_CONSTR_EXPR (cur); | |
2938 | if (error_operand_p (expr)) | |
2939 | return; | |
2940 | ||
2941 | /* Don't elide a previously diagnosed failure. */ | |
2942 | if (elide_constraint_failure_p()) | |
2943 | return; | |
2944 | ||
2945 | tree type = ICONV_CONSTR_TYPE (cur); | |
2946 | if (error_operand_p (type)) | |
2947 | { | |
2948 | inform (loc, "substitution into type %qT failed", | |
2949 | ICONV_CONSTR_TYPE (orig)); | |
2950 | return; | |
971e17ff | 2951 | } |
f078dc7d AS |
2952 | |
2953 | inform(loc, "%qE is not implicitly convertible to %qT", expr, type); | |
971e17ff AS |
2954 | } |
2955 | ||
f078dc7d AS |
2956 | /* Diagnose an argument deduction constraint. */ |
2957 | ||
2958 | void | |
2959 | diagnose_argument_deduction_constraint (location_t loc, tree orig, tree cur, | |
2960 | tree args) | |
2961 | { | |
2962 | if (constraints_satisfied_p (cur, args)) | |
2963 | return; | |
2964 | ||
2965 | /* The expression and type will previously have been substituted into, | |
2966 | and therefore may already be an error. Also, we will have already | |
2967 | diagnosed substution failures into an expression since this must be | |
2968 | part of a compound requirement. */ | |
2969 | tree expr = DEDUCT_CONSTR_EXPR (cur); | |
2970 | if (error_operand_p (expr)) | |
2971 | return; | |
2972 | ||
2973 | /* Don't elide a previously diagnosed failure. */ | |
2974 | if (elide_constraint_failure_p ()) | |
2975 | return; | |
2976 | ||
2977 | tree pattern = DEDUCT_CONSTR_PATTERN (cur); | |
2978 | if (error_operand_p (pattern)) | |
2979 | { | |
2980 | inform (loc, "substitution into type %qT failed", | |
2981 | DEDUCT_CONSTR_PATTERN (orig)); | |
2982 | return; | |
2983 | } | |
2984 | ||
2985 | inform (loc, "unable to deduce placeholder type %qT from %qE", | |
2986 | pattern, expr); | |
2987 | } | |
2988 | ||
2989 | /* Diagnose an exception constraint. */ | |
2990 | ||
2991 | void | |
2992 | diagnose_exception_constraint (location_t loc, tree orig, tree cur, tree args) | |
971e17ff | 2993 | { |
f078dc7d AS |
2994 | if (constraints_satisfied_p (cur, args)) |
2995 | return; | |
2996 | if (elide_constraint_failure_p ()) | |
2997 | return; | |
2998 | ||
2999 | /* Rebuild a noexcept expression. */ | |
3000 | tree expr = EXCEPT_CONSTR_EXPR (cur); | |
3001 | if (error_operand_p (expr)) | |
3002 | return; | |
3003 | ||
3004 | inform (loc, "%qE evaluated to false", EXCEPT_CONSTR_EXPR (orig)); | |
971e17ff AS |
3005 | } |
3006 | ||
f078dc7d AS |
3007 | /* Diagnose a potentially unsatisfied parameterized constraint. */ |
3008 | ||
3009 | void | |
3010 | diagnose_parameterized_constraint (location_t loc, tree orig, tree cur, | |
3011 | tree args) | |
971e17ff | 3012 | { |
f078dc7d AS |
3013 | if (constraints_satisfied_p (cur, args)) |
3014 | return; | |
3015 | ||
3016 | local_specialization_stack stack; | |
3017 | tree parms = PARM_CONSTR_PARMS (cur); | |
3018 | tree vars = tsubst_constraint_variables (parms, args, tf_warning_or_error, | |
3019 | NULL_TREE); | |
3020 | if (vars == error_mark_node) | |
3021 | { | |
3022 | if (elide_constraint_failure_p ()) | |
3023 | return; | |
3024 | ||
3025 | /* TODO: Check which variable failed and use orig to diagnose | |
3026 | that substitution error. */ | |
3027 | inform (loc, "failed to instantiate constraint variables"); | |
3028 | return; | |
3029 | } | |
3030 | ||
3031 | /* TODO: It would be better write these in a list. */ | |
3032 | while (vars) | |
3033 | { | |
3034 | inform (loc, " with %q#D", vars); | |
3035 | vars = TREE_CHAIN (vars); | |
3036 | } | |
3037 | orig = PARM_CONSTR_OPERAND (orig); | |
3038 | cur = PARM_CONSTR_OPERAND (cur); | |
3039 | return diagnose_constraint (loc, orig, cur, args); | |
971e17ff AS |
3040 | } |
3041 | ||
f078dc7d AS |
3042 | /* Diagnose the constraint CUR for the given ARGS. This is only ever invoked |
3043 | on the associated constraints, so we can only have conjunctions of | |
3044 | predicate constraints. The ORIGinal (dependent) constructs follow | |
3045 | the current constraints to enable better diagnostics. Note that ORIG | |
3046 | and CUR must be the same kinds of node, except when CUR is an error. */ | |
3047 | ||
971e17ff | 3048 | void |
f078dc7d | 3049 | diagnose_constraint (location_t loc, tree orig, tree cur, tree args) |
971e17ff | 3050 | { |
f078dc7d | 3051 | switch (TREE_CODE (cur)) |
971e17ff | 3052 | { |
f078dc7d AS |
3053 | case EXPR_CONSTR: |
3054 | diagnose_expression_constraint (loc, orig, cur, args); | |
3055 | break; | |
3056 | ||
3057 | case TYPE_CONSTR: | |
3058 | diagnose_type_constraint (loc, orig, cur, args); | |
3059 | break; | |
3060 | ||
3061 | case ICONV_CONSTR: | |
3062 | diagnose_implicit_conversion_constraint (loc, orig, cur, args); | |
3063 | break; | |
3064 | ||
3065 | case DEDUCT_CONSTR: | |
3066 | diagnose_argument_deduction_constraint (loc, orig, cur, args); | |
3067 | break; | |
3068 | ||
3069 | case EXCEPT_CONSTR: | |
3070 | diagnose_exception_constraint (loc, orig, cur, args); | |
3071 | break; | |
3072 | ||
971e17ff | 3073 | case CONJ_CONSTR: |
f078dc7d AS |
3074 | case DISJ_CONSTR: |
3075 | diagnose_logical_constraint (loc, orig, cur, args); | |
971e17ff AS |
3076 | break; |
3077 | ||
3078 | case PRED_CONSTR: | |
f078dc7d AS |
3079 | diagnose_predicate_constraint (loc, orig, cur, args); |
3080 | break; | |
3081 | ||
3082 | case PARM_CONSTR: | |
3083 | diagnose_parameterized_constraint (loc, orig, cur, args); | |
3084 | break; | |
3085 | ||
3086 | case CHECK_CONSTR: | |
3087 | diagnose_check_constraint (loc, orig, cur, args); | |
3088 | break; | |
3089 | ||
3090 | case EXPR_PACK_EXPANSION: | |
3091 | diagnose_pack_expansion (loc, orig, cur, args); | |
3092 | break; | |
3093 | ||
3094 | case ERROR_MARK: | |
3095 | /* TODO: Can we improve the diagnostic with the original? */ | |
3096 | inform (input_location, "ill-formed constraint"); | |
971e17ff AS |
3097 | break; |
3098 | ||
3099 | default: | |
3100 | gcc_unreachable (); | |
3101 | break; | |
3102 | } | |
3103 | } | |
3104 | ||
3105 | /* Diagnose the reason(s) why ARGS do not satisfy the constraints | |
3106 | of declaration DECL. */ | |
3107 | ||
3108 | void | |
3109 | diagnose_declaration_constraints (location_t loc, tree decl, tree args) | |
3110 | { | |
3111 | inform (loc, " constraints not satisfied"); | |
3112 | ||
3113 | /* Constraints are attached to the template. */ | |
3114 | if (tree ti = DECL_TEMPLATE_INFO (decl)) | |
3115 | { | |
3116 | decl = TI_TEMPLATE (ti); | |
3117 | if (!args) | |
3118 | args = TI_ARGS (ti); | |
3119 | } | |
3120 | ||
971e17ff | 3121 | /* Recursively diagnose the associated constraints. */ |
f078dc7d AS |
3122 | tree ci = get_constraints (decl); |
3123 | tree t = CI_ASSOCIATED_CONSTRAINTS (ci); | |
3124 | diagnose_constraint (loc, t, t, args); | |
971e17ff AS |
3125 | } |
3126 | ||
3127 | } // namespace | |
3128 | ||
3129 | /* Emit diagnostics detailing the failure ARGS to satisfy the | |
3130 | constraints of T. Here, T can be either a constraint | |
3131 | or a declaration. */ | |
3132 | ||
3133 | void | |
3134 | diagnose_constraints (location_t loc, tree t, tree args) | |
3135 | { | |
f078dc7d AS |
3136 | constraint_errors = 0; |
3137 | ||
971e17ff | 3138 | if (constraint_p (t)) |
f078dc7d AS |
3139 | diagnose_constraint (loc, t, t, args); |
3140 | else if (DECL_P (t)) | |
971e17ff | 3141 | diagnose_declaration_constraints (loc, t, args); |
f078dc7d AS |
3142 | else |
3143 | gcc_unreachable (); | |
3144 | ||
3145 | /* Note the number of elided failures. */ | |
3146 | int n = undiagnosed_constraint_failures (); | |
3147 | if (n > 0) | |
3148 | inform (loc, "... and %d more constraint errors not shown", n); | |
971e17ff | 3149 | } |