Line data Source code
1 : /* Perform the semantic phase of parsing, i.e., the process of
2 : building tree structure, checking semantic consistency, and
3 : building RTL. These routines are used both during actual parsing
4 : and during the instantiation of template functions.
5 :
6 : Copyright (C) 1998-2026 Free Software Foundation, Inc.
7 : Written by Mark Mitchell (mmitchell@usa.net) based on code found
8 : formerly in parse.y and pt.cc.
9 :
10 : This file is part of GCC.
11 :
12 : GCC is free software; you can redistribute it and/or modify it
13 : under the terms of the GNU General Public License as published by
14 : the Free Software Foundation; either version 3, or (at your option)
15 : any later version.
16 :
17 : GCC is distributed in the hope that it will be useful, but
18 : WITHOUT ANY WARRANTY; without even the implied warranty of
19 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 : General Public License for more details.
21 :
22 : You should have received a copy of the GNU General Public License
23 : along with GCC; see the file COPYING3. If not see
24 : <http://www.gnu.org/licenses/>. */
25 :
26 : #include "config.h"
27 : #include "system.h"
28 : #include "coretypes.h"
29 : #include "target.h"
30 : #include "bitmap.h"
31 : #include "cp-tree.h"
32 : #include "stringpool.h"
33 : #include "cgraph.h"
34 : #include "stmt.h"
35 : #include "varasm.h"
36 : #include "stor-layout.h"
37 : #include "c-family/c-objc.h"
38 : #include "tree-inline.h"
39 : #include "intl.h"
40 : #include "tree-iterator.h"
41 : #include "omp-general.h"
42 : #include "convert.h"
43 : #include "stringpool.h"
44 : #include "attribs.h"
45 : #include "gomp-constants.h"
46 : #include "predict.h"
47 : #include "memmodel.h"
48 : #include "gimplify.h"
49 : #include "contracts.h"
50 : #include "c-family/c-pragma.h"
51 :
52 : /* There routines provide a modular interface to perform many parsing
53 : operations. They may therefore be used during actual parsing, or
54 : during template instantiation, which may be regarded as a
55 : degenerate form of parsing. */
56 :
57 : static tree finalize_nrv_r (tree *, int *, void *);
58 :
59 : /* Used for OpenMP non-static data member privatization. */
60 :
61 : static hash_map<tree, tree> *omp_private_member_map;
62 : static vec<tree> omp_private_member_vec;
63 : static bool omp_private_member_ignore_next;
64 :
65 :
66 : /* Deferred Access Checking Overview
67 : ---------------------------------
68 :
69 : Most C++ expressions and declarations require access checking
70 : to be performed during parsing. However, in several cases,
71 : this has to be treated differently.
72 :
73 : For member declarations, access checking has to be deferred
74 : until more information about the declaration is known. For
75 : example:
76 :
77 : class A {
78 : typedef int X;
79 : public:
80 : X f();
81 : };
82 :
83 : A::X A::f();
84 : A::X g();
85 :
86 : When we are parsing the function return type `A::X', we don't
87 : really know if this is allowed until we parse the function name.
88 :
89 : Furthermore, some contexts require that access checking is
90 : never performed at all. These include class heads, and template
91 : instantiations.
92 :
93 : Typical use of access checking functions is described here:
94 :
95 : 1. When we enter a context that requires certain access checking
96 : mode, the function `push_deferring_access_checks' is called with
97 : DEFERRING argument specifying the desired mode. Access checking
98 : may be performed immediately (dk_no_deferred), deferred
99 : (dk_deferred), or not performed (dk_no_check).
100 :
101 : 2. When a declaration such as a type, or a variable, is encountered,
102 : the function `perform_or_defer_access_check' is called. It
103 : maintains a vector of all deferred checks.
104 :
105 : 3. The global `current_class_type' or `current_function_decl' is then
106 : setup by the parser. `enforce_access' relies on these information
107 : to check access.
108 :
109 : 4. Upon exiting the context mentioned in step 1,
110 : `perform_deferred_access_checks' is called to check all declaration
111 : stored in the vector. `pop_deferring_access_checks' is then
112 : called to restore the previous access checking mode.
113 :
114 : In case of parsing error, we simply call `pop_deferring_access_checks'
115 : without `perform_deferred_access_checks'. */
116 :
117 : struct GTY(()) deferred_access {
118 : /* A vector representing name-lookups for which we have deferred
119 : checking access controls. We cannot check the accessibility of
120 : names used in a decl-specifier-seq until we know what is being
121 : declared because code like:
122 :
123 : class A {
124 : class B {};
125 : B* f();
126 : }
127 :
128 : A::B* A::f() { return 0; }
129 :
130 : is valid, even though `A::B' is not generally accessible. */
131 : vec<deferred_access_check, va_gc> *deferred_access_checks;
132 :
133 : /* The current mode of access checks. */
134 : enum deferring_kind deferring_access_checks_kind;
135 : };
136 :
137 : /* Data for deferred access checking. */
138 : static GTY(()) vec<deferred_access, va_gc> *deferred_access_stack;
139 : static GTY(()) unsigned deferred_access_no_check;
140 :
141 : /* Save the current deferred access states and start deferred
142 : access checking iff DEFER_P is true. */
143 :
144 : void
145 22942269259 : push_deferring_access_checks (deferring_kind deferring)
146 : {
147 : /* For context like template instantiation, access checking
148 : disabling applies to all nested context. */
149 22942269259 : if (deferred_access_no_check || deferring == dk_no_check)
150 292046229 : deferred_access_no_check++;
151 : else
152 : {
153 22650223030 : deferred_access e = {NULL, deferring};
154 22650223030 : vec_safe_push (deferred_access_stack, e);
155 : }
156 22942269259 : }
157 :
158 : /* Save the current deferred access states and start deferred access
159 : checking, continuing the set of deferred checks in CHECKS. */
160 :
161 : void
162 421870769 : reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
163 : {
164 421870769 : push_deferring_access_checks (dk_deferred);
165 421870769 : if (!deferred_access_no_check)
166 415218298 : deferred_access_stack->last().deferred_access_checks = checks;
167 421870769 : }
168 :
169 : /* Resume deferring access checks again after we stopped doing
170 : this previously. */
171 :
172 : void
173 174268147 : resume_deferring_access_checks (void)
174 : {
175 174268147 : if (!deferred_access_no_check)
176 174247879 : deferred_access_stack->last().deferring_access_checks_kind = dk_deferred;
177 174268147 : }
178 :
179 : /* Stop deferring access checks. */
180 :
181 : void
182 489064101 : stop_deferring_access_checks (void)
183 : {
184 489064101 : if (!deferred_access_no_check)
185 489003956 : deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred;
186 489064101 : }
187 :
188 : /* Discard the current deferred access checks and restore the
189 : previous states. */
190 :
191 : void
192 14289721010 : pop_deferring_access_checks (void)
193 : {
194 14289721010 : if (deferred_access_no_check)
195 223633546 : deferred_access_no_check--;
196 : else
197 14066087464 : deferred_access_stack->pop ();
198 14289721010 : }
199 :
200 : /* Returns a TREE_LIST representing the deferred checks.
201 : The TREE_PURPOSE of each node is the type through which the
202 : access occurred; the TREE_VALUE is the declaration named.
203 : */
204 :
205 : vec<deferred_access_check, va_gc> *
206 1291137365 : get_deferred_access_checks (void)
207 : {
208 1291137365 : if (deferred_access_no_check)
209 : return NULL;
210 : else
211 1277946868 : return (deferred_access_stack->last().deferred_access_checks);
212 : }
213 :
214 : /* Take current deferred checks and combine with the
215 : previous states if we also defer checks previously.
216 : Otherwise perform checks now. */
217 :
218 : void
219 8652414172 : pop_to_parent_deferring_access_checks (void)
220 : {
221 8652414172 : if (deferred_access_no_check)
222 68412677 : deferred_access_no_check--;
223 : else
224 : {
225 8584001495 : vec<deferred_access_check, va_gc> *checks;
226 8584001495 : deferred_access *ptr;
227 :
228 8584001495 : checks = (deferred_access_stack->last ().deferred_access_checks);
229 :
230 8584001495 : deferred_access_stack->pop ();
231 8584001495 : ptr = &deferred_access_stack->last ();
232 8584001495 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
233 : {
234 : /* Check access. */
235 548340778 : perform_access_checks (checks, tf_warning_or_error);
236 : }
237 : else
238 : {
239 : /* Merge with parent. */
240 : int i, j;
241 : deferred_access_check *chk, *probe;
242 :
243 8230073621 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
244 : {
245 105801309 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe)
246 : {
247 9520141 : if (probe->binfo == chk->binfo &&
248 7570364 : probe->decl == chk->decl &&
249 926042 : probe->diag_decl == chk->diag_decl)
250 925284 : goto found;
251 : }
252 : /* Insert into parent's checks. */
253 96281168 : vec_safe_push (ptr->deferred_access_checks, *chk);
254 97206452 : found:;
255 : }
256 : }
257 : }
258 8652414172 : }
259 :
260 : /* Called from enforce_access. A class has attempted (but failed) to access
261 : DECL. It is already established that a baseclass of that class,
262 : PARENT_BINFO, has private access to DECL. Examine certain special cases
263 : to find a decl that accurately describes the source of the problem. If
264 : none of the special cases apply, simply return DECL as the source of the
265 : problem. */
266 :
267 : static tree
268 182 : get_class_access_diagnostic_decl (tree parent_binfo, tree decl)
269 : {
270 : /* When a class is denied access to a decl in a baseclass, most of the
271 : time it is because the decl itself was declared as private at the point
272 : of declaration.
273 :
274 : However, in C++, there are (at least) two situations in which a decl
275 : can be private even though it was not originally defined as such.
276 : These two situations only apply if a baseclass had private access to
277 : DECL (this function is only called if that is the case). */
278 :
279 : /* We should first check whether the reason the parent had private access
280 : to DECL was simply because DECL was created and declared as private in
281 : the parent. If it was, then DECL is definitively the source of the
282 : problem. */
283 182 : if (SAME_BINFO_TYPE_P (context_for_name_lookup (decl),
284 : BINFO_TYPE (parent_binfo)))
285 : return decl;
286 :
287 : /* 1. If the "using" keyword is used to inherit DECL within the parent,
288 : this may cause DECL to be private, so we should return the using
289 : statement as the source of the problem.
290 :
291 : Scan the fields of PARENT_BINFO and see if there are any using decls. If
292 : there are, see if they inherit DECL. If they do, that's where DECL must
293 : have been declared private. */
294 :
295 66 : for (tree parent_field = TYPE_FIELDS (BINFO_TYPE (parent_binfo));
296 326 : parent_field;
297 260 : parent_field = DECL_CHAIN (parent_field))
298 : /* Not necessary, but also check TREE_PRIVATE for the sake of
299 : eliminating obviously non-relevant using decls. */
300 278 : if (TREE_CODE (parent_field) == USING_DECL
301 81 : && TREE_PRIVATE (parent_field))
302 : {
303 78 : tree decl_stripped = strip_using_decl (parent_field);
304 :
305 : /* The using statement might be overloaded. If so, we need to
306 : check all of the overloads. */
307 180 : for (ovl_iterator iter (decl_stripped); iter; ++iter)
308 : /* If equal, the using statement inherits DECL, and so is the
309 : source of the access failure, so return it. */
310 99 : if (*iter == decl)
311 18 : return parent_field;
312 : }
313 :
314 : /* 2. If DECL was privately inherited by the parent class, then DECL will
315 : be inaccessible, even though it may originally have been accessible to
316 : deriving classes. In that case, the fault lies with the parent, since it
317 : used a private inheritance, so we return the parent as the source of the
318 : problem.
319 :
320 : Since this is the last check, we just assume it's true. At worst, it
321 : will simply point to the class that failed to give access, which is
322 : technically true. */
323 48 : return TYPE_NAME (BINFO_TYPE (parent_binfo));
324 : }
325 :
326 : /* If the current scope isn't allowed to access DECL along
327 : BASETYPE_PATH, give an error, or if we're parsing a function or class
328 : template, defer the access check to be performed at instantiation time.
329 : The most derived class in BASETYPE_PATH is the one used to qualify DECL.
330 : DIAG_DECL is the declaration to use in the error diagnostic. */
331 :
332 : static bool
333 544212274 : enforce_access (tree basetype_path, tree decl, tree diag_decl,
334 : tsubst_flags_t complain, access_failure_info *afi = NULL)
335 : {
336 544212274 : gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
337 :
338 544212274 : if (flag_new_inheriting_ctors
339 688421220 : && DECL_INHERITED_CTOR (decl))
340 : {
341 : /* 7.3.3/18: The additional constructors are accessible if they would be
342 : accessible when used to construct an object of the corresponding base
343 : class. */
344 75602 : decl = strip_inheriting_ctors (decl);
345 75602 : basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl),
346 : ba_any, NULL, complain);
347 : }
348 :
349 544212274 : tree cs = current_scope ();
350 544212274 : if (in_template_context
351 544212274 : && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
352 40230529 : if (tree template_info = get_template_info (cs))
353 : {
354 : /* When parsing a function or class template, we in general need to
355 : defer access checks until template instantiation time, since a friend
356 : declaration may grant access only to a particular specialization of
357 : the template. */
358 :
359 39997010 : if (accessible_p (basetype_path, decl, /*consider_local_p=*/true))
360 : /* But if the member is deemed accessible at parse time, then we can
361 : assume it'll be accessible at instantiation time. */
362 : return true;
363 :
364 : /* Access of a dependent decl should be rechecked after tsubst'ing
365 : into the user of the decl, rather than explicitly deferring the
366 : check here. */
367 135 : gcc_assert (!uses_template_parms (decl));
368 135 : if (TREE_CODE (decl) == FIELD_DECL)
369 6 : gcc_assert (!uses_template_parms (DECL_CONTEXT (decl)));
370 :
371 : /* Defer this access check until instantiation time. */
372 135 : deferred_access_check access_check;
373 135 : access_check.binfo = basetype_path;
374 135 : access_check.decl = decl;
375 135 : access_check.diag_decl = diag_decl;
376 135 : access_check.loc = input_location;
377 135 : vec_safe_push (TI_DEFERRED_ACCESS_CHECKS (template_info), access_check);
378 135 : return true;
379 : }
380 :
381 504215264 : if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true))
382 : {
383 21455 : if (flag_new_inheriting_ctors)
384 21425 : diag_decl = strip_inheriting_ctors (diag_decl);
385 21455 : if (complain & tf_error)
386 : {
387 1151 : access_kind access_failure_reason = ak_none;
388 :
389 : /* By default, using the decl as the source of the problem will
390 : usually give correct results. */
391 1151 : tree diag_location = diag_decl;
392 :
393 : /* However, if a parent of BASETYPE_PATH had private access to decl,
394 : then it actually might be the case that the source of the problem
395 : is not DECL. */
396 1151 : tree parent_binfo = get_parent_with_private_access (decl,
397 : basetype_path);
398 :
399 : /* So if a parent did have private access, then we need to do
400 : special checks to obtain the best diagnostic location decl. */
401 1151 : if (parent_binfo != NULL_TREE)
402 : {
403 182 : diag_location = get_class_access_diagnostic_decl (parent_binfo,
404 : diag_decl);
405 :
406 : /* We also at this point know that the reason access failed was
407 : because decl was private. */
408 182 : access_failure_reason = ak_private;
409 : }
410 :
411 : /* Finally, generate an error message. */
412 1151 : complain_about_access (decl, diag_decl, diag_location, true,
413 : access_failure_reason);
414 : }
415 21455 : if (afi)
416 412 : afi->record_access_failure (basetype_path, decl, diag_decl);
417 21455 : return false;
418 : }
419 :
420 : return true;
421 : }
422 :
423 : /* Perform the access checks in CHECKS. The TREE_PURPOSE of each node
424 : is the BINFO indicating the qualifying scope used to access the
425 : DECL node stored in the TREE_VALUE of the node. If CHECKS is empty
426 : or we aren't in SFINAE context or all the checks succeed return TRUE,
427 : otherwise FALSE. */
428 :
429 : bool
430 1108413161 : perform_access_checks (vec<deferred_access_check, va_gc> *checks,
431 : tsubst_flags_t complain)
432 : {
433 1108413161 : int i;
434 1108413161 : deferred_access_check *chk;
435 1108413161 : location_t loc = input_location;
436 1108413161 : bool ok = true;
437 :
438 1108413161 : if (!checks)
439 : return true;
440 :
441 131245741 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
442 : {
443 73082395 : input_location = chk->loc;
444 73082395 : ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain);
445 : }
446 :
447 58163346 : input_location = loc;
448 58163346 : return (complain & tf_error) ? true : ok;
449 : }
450 :
451 : /* Perform the deferred access checks.
452 :
453 : After performing the checks, we still have to keep the list
454 : `deferred_access_stack->deferred_access_checks' since we may want
455 : to check access for them again later in a different context.
456 : For example:
457 :
458 : class A {
459 : typedef int X;
460 : static X a;
461 : };
462 : A::X A::a, x; // No error for `A::a', error for `x'
463 :
464 : We have to perform deferred access of `A::X', first with `A::a',
465 : next with `x'. Return value like perform_access_checks above. */
466 :
467 : bool
468 289877932 : perform_deferred_access_checks (tsubst_flags_t complain)
469 : {
470 289877932 : return perform_access_checks (get_deferred_access_checks (), complain);
471 : }
472 :
473 : /* Defer checking the accessibility of DECL, when looked up in
474 : BINFO. DIAG_DECL is the declaration to use to print diagnostics.
475 : Return value like perform_access_checks above.
476 : If non-NULL, report failures to AFI. */
477 :
478 : bool
479 760367055 : perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
480 : tsubst_flags_t complain,
481 : access_failure_info *afi)
482 : {
483 760367055 : int i;
484 760367055 : deferred_access *ptr;
485 760367055 : deferred_access_check *chk;
486 :
487 : /* Exit if we are in a context that no access checking is performed. */
488 760367055 : if (deferred_access_no_check)
489 : return true;
490 :
491 736775780 : gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
492 :
493 736775780 : ptr = &deferred_access_stack->last ();
494 :
495 : /* If we are not supposed to defer access checks, just check now. */
496 736775780 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
497 : {
498 471129879 : bool ok = enforce_access (binfo, decl, diag_decl, complain, afi);
499 684173732 : return (complain & tf_error) ? true : ok;
500 : }
501 :
502 : /* See if we are already going to perform this check. */
503 321519310 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk)
504 : {
505 74151213 : if (chk->decl == decl && chk->binfo == binfo &&
506 18278517 : chk->diag_decl == diag_decl)
507 : {
508 : return true;
509 : }
510 : }
511 : /* If not, record the check. */
512 247368097 : deferred_access_check new_access = {binfo, decl, diag_decl, input_location};
513 247368097 : vec_safe_push (ptr->deferred_access_checks, new_access);
514 :
515 247368097 : return true;
516 : }
517 :
518 : /* Returns nonzero if the current statement is a full expression,
519 : i.e. temporaries created during that statement should be destroyed
520 : at the end of the statement. */
521 :
522 : int
523 1601197622 : stmts_are_full_exprs_p (void)
524 : {
525 1601197622 : return current_stmt_tree ()->stmts_are_full_exprs_p;
526 : }
527 :
528 : /* T is a statement. Add it to the statement-tree. This is the C++
529 : version. The C/ObjC frontends have a slightly different version of
530 : this function. */
531 :
532 : tree
533 1327180414 : add_stmt (tree t)
534 : {
535 1327180414 : enum tree_code code = TREE_CODE (t);
536 :
537 1327180414 : if (EXPR_P (t) && code != LABEL_EXPR)
538 : {
539 1275893063 : if (!EXPR_HAS_LOCATION (t))
540 192605969 : SET_EXPR_LOCATION (t, input_location);
541 :
542 : /* When we expand a statement-tree, we must know whether or not the
543 : statements are full-expressions. We record that fact here. */
544 1275893063 : if (STATEMENT_CODE_P (TREE_CODE (t)))
545 340039264 : STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
546 : }
547 :
548 1327180414 : if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
549 8432976 : STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
550 :
551 : /* Add T to the statement-tree. Non-side-effect statements need to be
552 : recorded during statement expressions. */
553 1327180414 : gcc_checking_assert (!stmt_list_stack->is_empty ());
554 1327180414 : append_to_statement_list_force (t, &cur_stmt_list);
555 :
556 1327180414 : return t;
557 : }
558 :
559 : /* Returns the stmt_tree to which statements are currently being added. */
560 :
561 : stmt_tree
562 8003328216 : current_stmt_tree (void)
563 : {
564 8003328216 : return (cfun
565 7961462900 : ? &cfun->language->base.x_stmt_tree
566 8003328216 : : &scope_chain->x_stmt_tree);
567 : }
568 :
569 : /* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */
570 :
571 : static tree
572 640676 : maybe_cleanup_point_expr (tree expr)
573 : {
574 640676 : if (!processing_template_decl && stmts_are_full_exprs_p ())
575 626783 : expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
576 640676 : return expr;
577 : }
578 :
579 : /* Like maybe_cleanup_point_expr except have the type of the new expression be
580 : void so we don't need to create a temporary variable to hold the inner
581 : expression. The reason why we do this is because the original type might be
582 : an aggregate and we cannot create a temporary variable for that type. */
583 :
584 : tree
585 337336972 : maybe_cleanup_point_expr_void (tree expr)
586 : {
587 337336972 : if (!processing_template_decl && stmts_are_full_exprs_p ())
588 131166215 : expr = fold_build_cleanup_point_expr (void_type_node, expr);
589 337336972 : return expr;
590 : }
591 :
592 :
593 :
594 : /* Create a declaration statement for the declaration given by the DECL. */
595 :
596 : void
597 110895544 : add_decl_expr (tree decl)
598 : {
599 110895544 : tree r = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
600 110895544 : if (DECL_INITIAL (decl)
601 110895544 : || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
602 20302353 : r = maybe_cleanup_point_expr_void (r);
603 110895544 : add_stmt (r);
604 110895544 : }
605 :
606 : /* Set EXPR_LOCATION on one cleanup T to LOC. */
607 :
608 : static void
609 6103859 : set_one_cleanup_loc (tree t, location_t loc)
610 : {
611 6103859 : if (!t)
612 : return;
613 :
614 6103859 : if (TREE_CODE (t) != POSTCONDITION_STMT)
615 6103859 : protected_set_expr_location (t, loc);
616 :
617 : /* Avoid locus differences for C++ cdtor calls depending on whether
618 : cdtor_returns_this: a conversion to void is added to discard the return
619 : value, and this conversion ends up carrying the location, and when it
620 : gets discarded, the location is lost. So hold it in the call as well. */
621 6103859 : if (TREE_CODE (t) == NOP_EXPR
622 0 : && TREE_TYPE (t) == void_type_node
623 6103859 : && TREE_CODE (TREE_OPERAND (t, 0)) == CALL_EXPR)
624 0 : protected_set_expr_location (TREE_OPERAND (t, 0), loc);
625 : }
626 :
627 : /* Set EXPR_LOCATION of the cleanups of any CLEANUP_STMT in STMTS to LOC. */
628 :
629 : static void
630 1241569671 : set_cleanup_locs (tree stmts, location_t loc)
631 : {
632 1247673530 : if (TREE_CODE (stmts) == CLEANUP_STMT)
633 : {
634 6103859 : set_one_cleanup_loc (CLEANUP_EXPR (stmts), loc);
635 6103859 : set_cleanup_locs (CLEANUP_BODY (stmts), loc);
636 : }
637 1241569671 : else if (TREE_CODE (stmts) == STATEMENT_LIST)
638 1090264192 : for (tree stmt : tsi_range (stmts))
639 846759557 : set_cleanup_locs (stmt, loc);
640 1241569671 : }
641 :
642 : /* True iff the innermost block scope is a try block. */
643 :
644 : static bool
645 394810114 : at_try_scope ()
646 : {
647 394810114 : cp_binding_level *b = current_binding_level;
648 394810504 : while (b && b->kind == sk_cleanup)
649 390 : b = b->level_chain;
650 394810114 : return b && b->kind == sk_try;
651 : }
652 :
653 : /* Finish a scope. */
654 :
655 : tree
656 394810114 : do_poplevel (tree stmt_list)
657 : {
658 394810114 : tree block = NULL;
659 :
660 394810114 : bool was_try = at_try_scope ();
661 :
662 394810114 : if (stmts_are_full_exprs_p ())
663 394749740 : block = poplevel (kept_level_p (), 1, 0);
664 :
665 : /* This needs to come after poplevel merges sk_cleanup statement_lists. */
666 394810114 : maybe_splice_retval_cleanup (stmt_list, was_try);
667 :
668 394810114 : stmt_list = pop_stmt_list (stmt_list);
669 :
670 : /* input_location is the last token of the scope, usually a }. */
671 394810114 : set_cleanup_locs (stmt_list, input_location);
672 :
673 394810114 : if (!processing_template_decl)
674 : {
675 144525446 : stmt_list = c_build_bind_expr (input_location, block, stmt_list);
676 : /* ??? See c_end_compound_stmt re statement expressions. */
677 : }
678 :
679 394810114 : return stmt_list;
680 : }
681 :
682 : /* Begin a new scope. */
683 :
684 : tree
685 394774115 : do_pushlevel (scope_kind sk)
686 : {
687 394774115 : tree ret = push_stmt_list ();
688 394774115 : if (stmts_are_full_exprs_p ())
689 394749800 : begin_scope (sk, NULL);
690 394774115 : return ret;
691 : }
692 :
693 : /* Queue a cleanup. CLEANUP is an expression/statement to be executed
694 : when the current scope is exited. EH_ONLY is true when this is not
695 : meant to apply to normal control flow transfer. DECL is the VAR_DECL
696 : being cleaned up, if any, or null for temporaries or subobjects. */
697 :
698 : void
699 6103760 : push_cleanup (tree decl, tree cleanup, bool eh_only)
700 : {
701 6103760 : tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
702 6103760 : CLEANUP_EH_ONLY (stmt) = eh_only;
703 6103760 : add_stmt (stmt);
704 6103760 : CLEANUP_BODY (stmt) = push_stmt_list ();
705 6103760 : }
706 :
707 : /* Simple infinite loop tracking for -Wreturn-type. We keep a stack of all
708 : the current loops, represented by 'NULL_TREE' if we've seen a possible
709 : exit, and 'error_mark_node' if not. This is currently used only to
710 : suppress the warning about a function with no return statements, and
711 : therefore we don't bother noting returns as possible exits. We also
712 : don't bother with gotos. */
713 :
714 : static void
715 18098022 : begin_maybe_infinite_loop (tree cond)
716 : {
717 : /* Only track this while parsing a function, not during instantiation. */
718 18098022 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
719 3288159 : && !processing_template_decl))
720 : return;
721 14809317 : bool maybe_infinite = true;
722 14809317 : if (cond)
723 : {
724 14506699 : cond = fold_non_dependent_expr (cond);
725 14506699 : maybe_infinite = integer_nonzerop (cond);
726 : }
727 29316016 : vec_safe_push (cp_function_chain->infinite_loops,
728 14809317 : maybe_infinite ? error_mark_node : NULL_TREE);
729 :
730 : }
731 :
732 : /* A break is a possible exit for the current loop. */
733 :
734 : void
735 1471929 : break_maybe_infinite_loop (void)
736 : {
737 1471929 : if (!cfun)
738 : return;
739 1471929 : cp_function_chain->infinite_loops->last() = NULL_TREE;
740 : }
741 :
742 : /* If we reach the end of the loop without seeing a possible exit, we have
743 : an infinite loop. */
744 :
745 : static void
746 18098022 : end_maybe_infinite_loop (tree cond)
747 : {
748 18098022 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
749 3288159 : && !processing_template_decl))
750 : return;
751 14809317 : tree current = cp_function_chain->infinite_loops->pop();
752 14809317 : if (current != NULL_TREE)
753 : {
754 4733343 : cond = fold_non_dependent_expr (cond);
755 4733343 : if (integer_nonzerop (cond))
756 298925 : current_function_infinite_loop = 1;
757 : }
758 : }
759 :
760 : /* Begin a conditional that might contain a declaration. When generating
761 : normal code, we want the declaration to appear before the statement
762 : containing the conditional. When generating template code, we want the
763 : conditional to be rendered as the raw DECL_EXPR. */
764 :
765 : static void
766 95271685 : begin_cond (tree *cond_p)
767 : {
768 95271685 : if (processing_template_decl)
769 59125049 : *cond_p = push_stmt_list ();
770 95271685 : }
771 :
772 : /* Finish such a conditional. */
773 :
774 : static void
775 95271685 : finish_cond (tree *cond_p, tree expr)
776 : {
777 95271685 : if (processing_template_decl)
778 : {
779 59125049 : tree cond = pop_stmt_list (*cond_p);
780 :
781 59125049 : if (expr == NULL_TREE)
782 : /* Empty condition in 'for'. */
783 282661 : gcc_assert (empty_expr_stmt_p (cond));
784 58842388 : else if (check_for_bare_parameter_packs (expr))
785 0 : expr = error_mark_node;
786 58842388 : else if (!empty_expr_stmt_p (cond))
787 892104 : expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
788 : }
789 95271685 : *cond_p = expr;
790 95271685 : }
791 :
792 : /* If loop condition specifies a conditional with a declaration,
793 : such as
794 : while (A x = 42) { }
795 : for (; A x = 42;) { }
796 : move the *BODY_P statements as a BIND_EXPR into {FOR,WHILE}_COND_PREP
797 : and if there are any CLEANUP_STMT at the end, remember their count in
798 : {FOR,WHILE}_COND_CLEANUP.
799 : genericize_c_loop will then handle it appropriately. In particular,
800 : the {FOR,WHILE}_COND, {FOR,WHILE}_BODY, if used continue label and
801 : FOR_EXPR will be appended into the {FOR,WHILE}_COND_PREP BIND_EXPR,
802 : but it can't be done too early because only the actual body should
803 : bind BREAK_STMT and CONTINUE_STMT to the inner loop.
804 : The statement list for *BODY will be empty if the conditional did
805 : not declare anything. */
806 :
807 : static void
808 12338967 : adjust_loop_decl_cond (tree *body_p, tree *prep_p, tree *cleanup_p)
809 : {
810 12338967 : if (!TREE_SIDE_EFFECTS (*body_p))
811 12329611 : return;
812 :
813 9356 : gcc_assert (!processing_template_decl);
814 9356 : *prep_p = *body_p;
815 9356 : if (*prep_p != cur_stmt_list)
816 : {
817 : /* There can be just one CLEANUP_STMT, or there could be multiple
818 : nested CLEANUP_STMTs, e.g. for structured bindings used as
819 : condition. */
820 97 : gcc_assert (stmt_list_stack->length () > 1);
821 97 : for (unsigned i = stmt_list_stack->length () - 2; ; --i)
822 : {
823 109 : tree t = (*stmt_list_stack)[i];
824 109 : tree_stmt_iterator last = tsi_last (t);
825 218 : gcc_assert (tsi_one_before_end_p (last)
826 : && TREE_CODE (tsi_stmt (last)) == CLEANUP_STMT
827 : && (CLEANUP_BODY (tsi_stmt (last))
828 : == (*stmt_list_stack)[i + 1])
829 : && !CLEANUP_EH_ONLY (tsi_stmt (last)));
830 109 : if (t == *prep_p)
831 : {
832 97 : *cleanup_p = build_int_cst (long_unsigned_type_node,
833 97 : stmt_list_stack->length () - 1 - i);
834 97 : break;
835 : }
836 12 : gcc_assert (i >= 1);
837 12 : }
838 : }
839 9356 : current_binding_level->keep = true;
840 9356 : tree_stmt_iterator iter = tsi_last (cur_stmt_list);
841 : /* Temporarily store in {FOR,WHILE}_BODY the last statement of
842 : the innnermost statement list or NULL if it has no statement.
843 : This is used in finish_loop_cond_prep to find out the splitting
844 : point and then {FOR,WHILE}_BODY will be changed to the actual
845 : body. */
846 9356 : if (tsi_end_p (iter))
847 91 : *body_p = NULL_TREE;
848 : else
849 9265 : *body_p = tsi_stmt (iter);
850 : }
851 :
852 : /* Finalize {FOR,WHILE}_{BODY,COND_PREP} after the loop body.
853 : The above function initialized *BODY_P to the last statement
854 : in *PREP_P at that point.
855 : Call do_poplevel on *PREP_P and move everything after that
856 : former last statement into *BODY_P. genericize_c_loop
857 : will later put those parts back together.
858 : CLEANUP is {FOR,WHILE}_COND_CLEANUP. */
859 :
860 : static void
861 9356 : finish_loop_cond_prep (tree *body_p, tree *prep_p, tree cleanup)
862 : {
863 9356 : *prep_p = do_poplevel (*prep_p);
864 9356 : gcc_assert (TREE_CODE (*prep_p) == BIND_EXPR);
865 9356 : if (BIND_EXPR_BODY (*prep_p) == *body_p)
866 : {
867 18 : gcc_assert (cleanup == NULL_TREE);
868 18 : *body_p = build_empty_stmt (input_location);
869 109 : return;
870 : }
871 9338 : tree stmt_list = BIND_EXPR_BODY (*prep_p);
872 9338 : gcc_assert (TREE_CODE (stmt_list) == STATEMENT_LIST);
873 9338 : if (cleanup)
874 : {
875 97 : tree_stmt_iterator iter = tsi_last (stmt_list);
876 97 : gcc_assert (TREE_CODE (tsi_stmt (iter)) == CLEANUP_STMT);
877 109 : for (unsigned depth = tree_to_uhwi (cleanup); depth > 1; --depth)
878 : {
879 12 : gcc_assert (TREE_CODE (CLEANUP_BODY (tsi_stmt (iter)))
880 : == STATEMENT_LIST);
881 12 : iter = tsi_last (CLEANUP_BODY (tsi_stmt (iter)));
882 12 : gcc_assert (TREE_CODE (tsi_stmt (iter)) == CLEANUP_STMT);
883 : }
884 97 : if (*body_p == NULL_TREE)
885 : {
886 91 : *body_p = CLEANUP_BODY (tsi_stmt (iter));
887 91 : CLEANUP_BODY (tsi_stmt (iter)) = build_empty_stmt (input_location);
888 91 : return;
889 : }
890 6 : stmt_list = CLEANUP_BODY (tsi_stmt (iter));
891 : }
892 9247 : tree_stmt_iterator iter = tsi_start (stmt_list);
893 9443 : while (tsi_stmt (iter) != *body_p)
894 196 : tsi_next (&iter);
895 9247 : *body_p = tsi_split_stmt_list (input_location, iter);
896 : }
897 :
898 : /* Finish a goto-statement. */
899 :
900 : tree
901 2710 : finish_goto_stmt (tree destination)
902 : {
903 2710 : if (identifier_p (destination))
904 2573 : destination = lookup_label (destination);
905 :
906 : /* We warn about unused labels with -Wunused. That means we have to
907 : mark the used labels as used. */
908 2710 : if (TREE_CODE (destination) == LABEL_DECL)
909 2573 : TREE_USED (destination) = 1;
910 : else
911 : {
912 137 : destination = mark_rvalue_use (destination);
913 137 : if (!processing_template_decl)
914 : {
915 117 : destination = cp_convert (ptr_type_node, destination,
916 : tf_warning_or_error);
917 117 : if (error_operand_p (destination))
918 : return NULL_TREE;
919 108 : destination
920 108 : = fold_build_cleanup_point_expr (TREE_TYPE (destination),
921 : destination);
922 : }
923 : }
924 :
925 2701 : add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
926 :
927 2701 : tree stmt = build_stmt (input_location, GOTO_EXPR, destination);
928 2701 : check_goto (&TREE_OPERAND (stmt, 0));
929 :
930 2701 : return add_stmt (stmt);
931 : }
932 :
933 : /* Returns true if T corresponds to an assignment operator expression. */
934 :
935 : static bool
936 841833 : is_assignment_op_expr_p (tree t)
937 : {
938 841833 : if (t == NULL_TREE)
939 : return false;
940 :
941 841833 : if (TREE_CODE (t) == MODIFY_EXPR
942 841833 : || (TREE_CODE (t) == MODOP_EXPR
943 330 : && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR))
944 : return true;
945 :
946 841146 : tree call = extract_call_expr (t);
947 841146 : if (call == NULL_TREE
948 126335 : || call == error_mark_node
949 967481 : || !CALL_EXPR_OPERATOR_SYNTAX (call))
950 : return false;
951 :
952 4393 : tree fndecl = cp_get_callee_fndecl_nofold (call);
953 4393 : return fndecl != NULL_TREE
954 4365 : && DECL_ASSIGNMENT_OPERATOR_P (fndecl)
955 4444 : && DECL_OVERLOADED_OPERATOR_IS (fndecl, NOP_EXPR);
956 : }
957 :
958 : /* Return true if TYPE is a class type that is convertible to
959 : and assignable from bool. */
960 :
961 : static GTY((deletable)) hash_map<tree, bool> *boolish_class_type_p_cache;
962 :
963 : static bool
964 60 : boolish_class_type_p (tree type)
965 : {
966 60 : type = TYPE_MAIN_VARIANT (type);
967 60 : if (!CLASS_TYPE_P (type) || !COMPLETE_TYPE_P (type))
968 : return false;
969 :
970 78 : if (bool *r = hash_map_safe_get (boolish_class_type_p_cache, type))
971 27 : return *r;
972 :
973 18 : tree ops;
974 18 : bool has_bool_assignment = false;
975 18 : bool has_bool_conversion = false;
976 :
977 18 : ops = lookup_fnfields (type, assign_op_identifier, /*protect=*/0, tf_none);
978 55 : for (tree op : ovl_range (BASELINK_FUNCTIONS (ops)))
979 : {
980 29 : op = STRIP_TEMPLATE (op);
981 29 : if (TREE_CODE (op) != FUNCTION_DECL)
982 0 : continue;
983 29 : tree parm = DECL_CHAIN (DECL_ARGUMENTS (op));
984 29 : tree parm_type = non_reference (TREE_TYPE (parm));
985 29 : if (TREE_CODE (parm_type) == BOOLEAN_TYPE)
986 : {
987 : has_bool_assignment = true;
988 : break;
989 : }
990 : }
991 :
992 18 : if (has_bool_assignment)
993 : {
994 3 : ops = lookup_conversions (type);
995 3 : for (; ops; ops = TREE_CHAIN (ops))
996 : {
997 3 : tree op = TREE_VALUE (ops);
998 3 : if (!DECL_NONCONVERTING_P (op)
999 3 : && TREE_CODE (DECL_CONV_FN_TYPE (op)) == BOOLEAN_TYPE)
1000 : {
1001 : has_bool_conversion = true;
1002 : break;
1003 : }
1004 : }
1005 : }
1006 :
1007 18 : bool boolish = has_bool_assignment && has_bool_conversion;
1008 18 : hash_map_safe_put<true> (boolish_class_type_p_cache, type, boolish);
1009 18 : return boolish;
1010 : }
1011 :
1012 :
1013 : /* Maybe warn about an unparenthesized 'a = b' (appearing in a
1014 : boolean context where 'a == b' might have been intended).
1015 : NESTED_P is true if T is the RHS of another assignment. */
1016 :
1017 : void
1018 104331223 : maybe_warn_unparenthesized_assignment (tree t, bool nested_p,
1019 : tsubst_flags_t complain)
1020 : {
1021 104331223 : tree type = TREE_TYPE (t);
1022 104331223 : t = STRIP_REFERENCE_REF (t);
1023 :
1024 104331223 : if ((complain & tf_warning)
1025 104272536 : && warn_parentheses
1026 841833 : && is_assignment_op_expr_p (t)
1027 : /* A parenthesized expression would've had this warning
1028 : suppressed by finish_parenthesized_expr. */
1029 738 : && !warning_suppressed_p (t, OPT_Wparentheses)
1030 : /* In c = a = b, don't warn if a has type bool or bool-like class. */
1031 104331576 : && (!nested_p
1032 182 : || (TREE_CODE (type) != BOOLEAN_TYPE
1033 60 : && !boolish_class_type_p (type))))
1034 : {
1035 219 : warning_at (cp_expr_loc_or_input_loc (t), OPT_Wparentheses,
1036 : "suggest parentheses around assignment used as truth value");
1037 219 : suppress_warning (t, OPT_Wparentheses);
1038 : }
1039 104331223 : }
1040 :
1041 : /* Helper class for saving/restoring ANNOTATE_EXPRs. For a tree node t, users
1042 : can construct one of these like so:
1043 :
1044 : annotate_saver s (&t);
1045 :
1046 : and t will be updated to have any annotations removed. The user can then
1047 : transform t, and later restore the ANNOTATE_EXPRs with:
1048 :
1049 : t = s.restore (t).
1050 :
1051 : The intent is to ensure that any ANNOTATE_EXPRs remain the outermost
1052 : expressions following any operations on t. */
1053 :
1054 : class annotate_saver {
1055 : /* The chain of saved annotations, if there were any. Otherwise null. */
1056 : tree m_annotations;
1057 :
1058 : /* If M_ANNOTATIONS is non-null, then M_INNER points to TREE_OPERAND (A, 0)
1059 : for the innermost annotation A. */
1060 : tree *m_inner;
1061 :
1062 : public:
1063 : annotate_saver (tree *);
1064 : tree restore (tree);
1065 : };
1066 :
1067 : /* If *COND is an ANNOTATE_EXPR, walk through the chain of annotations, and set
1068 : *COND equal to the first non-ANNOTATE_EXPR (saving a pointer to the
1069 : original chain of annotations for later use in restore). */
1070 :
1071 62307374 : annotate_saver::annotate_saver (tree *cond) : m_annotations (nullptr)
1072 : {
1073 62307374 : tree *t = cond;
1074 62317213 : while (TREE_CODE (*t) == ANNOTATE_EXPR)
1075 9839 : t = &TREE_OPERAND (*t, 0);
1076 :
1077 62307374 : if (t != cond)
1078 : {
1079 9836 : m_annotations = *cond;
1080 9836 : *cond = *t;
1081 9836 : m_inner = t;
1082 : }
1083 62307374 : }
1084 :
1085 : /* If we didn't strip any annotations on construction, return NEW_INNER
1086 : unmodified. Otherwise, wrap the saved annotations around NEW_INNER (updating
1087 : the types and flags of the annotations if needed) and return the resulting
1088 : expression. */
1089 :
1090 : tree
1091 62307374 : annotate_saver::restore (tree new_inner)
1092 : {
1093 62307374 : if (!m_annotations)
1094 : return new_inner;
1095 :
1096 : /* If the type of the inner expression changed, we need to update the types
1097 : of all the ANNOTATE_EXPRs. We may need to update the flags too, but we
1098 : assume they only change if the type of the inner expression changes.
1099 : The flag update logic assumes that the other operands to the
1100 : ANNOTATE_EXPRs are always INTEGER_CSTs. */
1101 9836 : if (TREE_TYPE (new_inner) != TREE_TYPE (*m_inner))
1102 : {
1103 6 : const bool new_readonly
1104 6 : = TREE_READONLY (new_inner) || CONSTANT_CLASS_P (new_inner);
1105 :
1106 12 : for (tree c = m_annotations; c != *m_inner; c = TREE_OPERAND (c, 0))
1107 : {
1108 6 : gcc_checking_assert (TREE_CODE (c) == ANNOTATE_EXPR
1109 : && TREE_CODE (TREE_OPERAND (c, 1)) == INTEGER_CST
1110 : && TREE_CODE (TREE_OPERAND (c, 2)) == INTEGER_CST);
1111 6 : TREE_TYPE (c) = TREE_TYPE (new_inner);
1112 6 : TREE_SIDE_EFFECTS (c) = TREE_SIDE_EFFECTS (new_inner);
1113 6 : TREE_READONLY (c) = new_readonly;
1114 : }
1115 : }
1116 :
1117 9836 : *m_inner = new_inner;
1118 9836 : return m_annotations;
1119 : }
1120 :
1121 : /* COND is the condition-expression for an if, while, etc.,
1122 : statement. Convert it to a boolean value, if appropriate.
1123 : In addition, verify sequence points if -Wsequence-point is enabled. */
1124 :
1125 : tree
1126 99811107 : maybe_convert_cond (tree cond)
1127 : {
1128 : /* Empty conditions remain empty. */
1129 99811107 : if (!cond)
1130 : return NULL_TREE;
1131 :
1132 : /* Wait until we instantiate templates before doing conversion. */
1133 99453412 : if (type_dependent_expression_p (cond))
1134 37146038 : return cond;
1135 :
1136 : /* Strip any ANNOTATE_EXPRs from COND. */
1137 62307374 : annotate_saver annotations (&cond);
1138 :
1139 : /* For structured binding used in condition, the conversion needs to be
1140 : evaluated before the individual variables are initialized in the
1141 : std::tuple_{size,elemenet} case. cp_finish_decomp saved the conversion
1142 : result in a TARGET_EXPR, pick it up from there. */
1143 545195 : if (DECL_DECOMPOSITION_P (cond)
1144 218 : && DECL_DECOMP_IS_BASE (cond)
1145 218 : && DECL_DECOMP_BASE (cond)
1146 62307589 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1147 56 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1148 :
1149 62307374 : if (warn_sequence_point && !processing_template_decl)
1150 316780 : verify_sequence_points (cond);
1151 :
1152 62307374 : maybe_warn_unparenthesized_assignment (cond, /*nested_p=*/false,
1153 : tf_warning_or_error);
1154 :
1155 : /* Do the conversion. */
1156 62307374 : cond = convert_from_reference (cond);
1157 62307374 : cond = condition_conversion (cond);
1158 :
1159 : /* Restore any ANNOTATE_EXPRs around COND. */
1160 62307374 : return annotations.restore (cond);
1161 : }
1162 :
1163 : /* Finish an expression-statement, whose EXPRESSION is as indicated. */
1164 :
1165 : tree
1166 179333254 : finish_expr_stmt (tree expr)
1167 : {
1168 179333254 : tree r = NULL_TREE;
1169 179333254 : location_t loc = EXPR_LOCATION (expr);
1170 :
1171 178846106 : if (expr != NULL_TREE)
1172 : {
1173 : /* If we ran into a problem, make sure we complained. */
1174 179333093 : gcc_assert (expr != error_mark_node || seen_error ());
1175 :
1176 179333093 : if (!processing_template_decl)
1177 : {
1178 78736992 : if (warn_sequence_point)
1179 793719 : verify_sequence_points (expr);
1180 78736992 : expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1181 : }
1182 100596101 : else if (!type_dependent_expression_p (expr))
1183 21880982 : convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1184 :
1185 179333090 : if (check_for_bare_parameter_packs (expr))
1186 24 : expr = error_mark_node;
1187 :
1188 : /* Simplification of inner statement expressions, compound exprs,
1189 : etc can result in us already having an EXPR_STMT or other statement
1190 : tree. Don't wrap them in EXPR_STMT. */
1191 179333090 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
1192 : {
1193 179332911 : if (TREE_CODE (expr) != EXPR_STMT
1194 176265082 : && !STATEMENT_CLASS_P (expr)
1195 176260931 : && TREE_CODE (expr) != STATEMENT_LIST)
1196 175828208 : expr = build_stmt (loc, EXPR_STMT, expr);
1197 179332911 : expr = maybe_cleanup_point_expr_void (expr);
1198 : }
1199 :
1200 179333090 : r = add_stmt (expr);
1201 : }
1202 :
1203 179333251 : return r;
1204 : }
1205 :
1206 :
1207 : /* Begin an if-statement. Returns a newly created IF_STMT if
1208 : appropriate. */
1209 :
1210 : tree
1211 81915916 : begin_if_stmt (void)
1212 : {
1213 81915916 : tree r, scope;
1214 81915916 : scope = do_pushlevel (sk_cond);
1215 81915916 : r = build_stmt (input_location, IF_STMT, NULL_TREE,
1216 : NULL_TREE, NULL_TREE, scope);
1217 81915916 : current_binding_level->this_entity = r;
1218 81915916 : begin_cond (&IF_COND (r));
1219 81915916 : return r;
1220 : }
1221 :
1222 : /* Returns true if FN, a CALL_EXPR, is a call to
1223 : std::is_constant_evaluated or __builtin_is_constant_evaluated. */
1224 :
1225 : static bool
1226 242344 : is_std_constant_evaluated_p (tree fn)
1227 : {
1228 : /* std::is_constant_evaluated takes no arguments. */
1229 242344 : if (call_expr_nargs (fn) != 0)
1230 : return false;
1231 :
1232 85409 : tree fndecl = cp_get_callee_fndecl_nofold (fn);
1233 85409 : if (fndecl == NULL_TREE)
1234 : return false;
1235 :
1236 26334 : if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
1237 : BUILT_IN_FRONTEND))
1238 : return true;
1239 :
1240 26311 : if (!decl_in_std_namespace_p (fndecl))
1241 : return false;
1242 :
1243 11358 : tree name = DECL_NAME (fndecl);
1244 11358 : return name && id_equal (name, "is_constant_evaluated");
1245 : }
1246 :
1247 : /* Callback function for maybe_warn_for_constant_evaluated that looks
1248 : for calls to std::is_constant_evaluated in TP. */
1249 :
1250 : static tree
1251 4483778 : find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
1252 : {
1253 4483778 : tree t = *tp;
1254 :
1255 4483778 : if (TYPE_P (t) || TREE_CONSTANT (t))
1256 : {
1257 790887 : *walk_subtrees = false;
1258 790887 : return NULL_TREE;
1259 : }
1260 :
1261 3692891 : switch (TREE_CODE (t))
1262 : {
1263 242344 : case CALL_EXPR:
1264 242344 : if (is_std_constant_evaluated_p (t))
1265 : return t;
1266 : break;
1267 6 : case EXPR_STMT:
1268 : /* Don't warn in statement expressions. */
1269 6 : *walk_subtrees = false;
1270 6 : return NULL_TREE;
1271 : default:
1272 : break;
1273 : }
1274 :
1275 : return NULL_TREE;
1276 : }
1277 :
1278 : /* In certain contexts, std::is_constant_evaluated() is always true (for
1279 : instance, in a consteval function or in a constexpr if), or always false
1280 : (e.g., in a non-constexpr non-consteval function) so give the user a clue. */
1281 :
1282 : static void
1283 81997656 : maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if,
1284 : bool trivial_infinite)
1285 : {
1286 81997656 : if (!warn_tautological_compare)
1287 : return;
1288 :
1289 : /* Suppress warning for std::is_constant_evaluated if the conditional
1290 : comes from a macro. */
1291 1367334 : if (from_macro_expansion_at (EXPR_LOCATION (cond)))
1292 : return;
1293 :
1294 574044 : cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r,
1295 : NULL);
1296 574044 : if (cond)
1297 : {
1298 2234 : if (constexpr_if)
1299 34 : warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
1300 : "%<std::is_constant_evaluated%> always evaluates to "
1301 : "true in %<if constexpr%>");
1302 2200 : else if (trivial_infinite)
1303 : {
1304 8 : auto_diagnostic_group d;
1305 8 : if (warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
1306 : "%<std::is_constant_evaluated%> evaluates to "
1307 : "true when checking if trivially empty iteration "
1308 : "statement is trivial infinite loop")
1309 8 : && !maybe_constexpr_fn (current_function_decl))
1310 8 : inform (EXPR_LOCATION (cond),
1311 : "and evaluates to false when actually evaluating "
1312 : "the condition in non-%<constexpr%> function");
1313 8 : }
1314 2192 : else if (!maybe_constexpr_fn (current_function_decl))
1315 38 : warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
1316 : "%<std::is_constant_evaluated%> always evaluates to "
1317 : "false in a non-%<constexpr%> function");
1318 4308 : else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1319 3 : warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare,
1320 : "%<std::is_constant_evaluated%> always evaluates to "
1321 : "true in a %<consteval%> function");
1322 : }
1323 : }
1324 :
1325 : /* Process the COND of an if-statement, which may be given by
1326 : IF_STMT. */
1327 :
1328 : tree
1329 81915916 : finish_if_stmt_cond (tree orig_cond, tree if_stmt)
1330 : {
1331 81915916 : tree cond = maybe_convert_cond (orig_cond);
1332 81915916 : maybe_warn_for_constant_evaluated (cond, IF_STMT_CONSTEXPR_P (if_stmt),
1333 : /*trivial_infinite=*/false);
1334 81915916 : if (IF_STMT_CONSTEXPR_P (if_stmt)
1335 18801725 : && !type_dependent_expression_p (cond)
1336 14036779 : && require_constant_expression (cond)
1337 14036750 : && !instantiation_dependent_expression_p (cond)
1338 : /* Wait until instantiation time, since only then COND has been
1339 : converted to bool. */
1340 91573951 : && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
1341 : {
1342 9658035 : cond = instantiate_non_dependent_expr (cond);
1343 9658035 : cond = cxx_constant_value (cond);
1344 : }
1345 72257881 : else if (processing_template_decl)
1346 48983792 : cond = orig_cond;
1347 81915916 : finish_cond (&IF_COND (if_stmt), cond);
1348 81915916 : add_stmt (if_stmt);
1349 81915916 : THEN_CLAUSE (if_stmt) = push_stmt_list ();
1350 81915916 : return cond;
1351 : }
1352 :
1353 : /* Finish the then-clause of an if-statement, which may be given by
1354 : IF_STMT. */
1355 :
1356 : tree
1357 81886471 : finish_then_clause (tree if_stmt)
1358 : {
1359 81886471 : THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
1360 81886471 : return if_stmt;
1361 : }
1362 :
1363 : /* Begin the else-clause of an if-statement. */
1364 :
1365 : void
1366 30046777 : begin_else_clause (tree if_stmt)
1367 : {
1368 30046777 : ELSE_CLAUSE (if_stmt) = push_stmt_list ();
1369 30046777 : }
1370 :
1371 : /* Finish the else-clause of an if-statement, which may be given by
1372 : IF_STMT. */
1373 :
1374 : void
1375 30046739 : finish_else_clause (tree if_stmt)
1376 : {
1377 30046739 : ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
1378 30046739 : }
1379 :
1380 : /* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as
1381 : read. */
1382 :
1383 : static tree
1384 905383640 : maybe_mark_exp_read_r (tree *tp, int *, void *)
1385 : {
1386 905383640 : tree t = *tp;
1387 905383640 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
1388 54476910 : mark_exp_read (t);
1389 905383640 : return NULL_TREE;
1390 : }
1391 :
1392 : /* Finish an if-statement. */
1393 :
1394 : void
1395 81886471 : finish_if_stmt (tree if_stmt)
1396 : {
1397 81886471 : tree scope = IF_SCOPE (if_stmt);
1398 81886471 : IF_SCOPE (if_stmt) = NULL;
1399 81886471 : if (IF_STMT_CONSTEXPR_P (if_stmt))
1400 : {
1401 : /* Prevent various -Wunused warnings. We might not instantiate
1402 : either of these branches, so we would not mark the variables
1403 : used in that branch as read. */
1404 18772280 : cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt),
1405 : maybe_mark_exp_read_r, NULL);
1406 18772280 : cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt),
1407 : maybe_mark_exp_read_r, NULL);
1408 : }
1409 81886471 : add_stmt (do_poplevel (scope));
1410 81886471 : }
1411 :
1412 : /* Determine if iteration statement with *CONDP condition and
1413 : loop BODY is trivially empty iteration statement or even
1414 : trivial infinite loop. In the latter case for -ffinite-loops
1415 : add ANNOTATE_EXPR to mark the loop as maybe validly infinite.
1416 : Also, emit -Wtautological-compare warning for std::is_constant_evaluated ()
1417 : calls in the condition when needed. */
1418 :
1419 : static void
1420 17534208 : finish_loop_cond (tree *condp, tree body)
1421 : {
1422 17534208 : if (TREE_CODE (*condp) == INTEGER_CST)
1423 : return;
1424 12731237 : bool trivially_empty = expr_first (body) == NULL_TREE;
1425 12731237 : bool trivial_infinite = false;
1426 12731237 : if (trivially_empty)
1427 : {
1428 94749 : tree c = fold_non_dependent_expr (*condp, tf_none,
1429 : /*manifestly_const_eval=*/true);
1430 94749 : trivial_infinite = c && integer_nonzerop (c);
1431 : }
1432 12731237 : if (warn_tautological_compare)
1433 : {
1434 81920 : tree cond = *condp;
1435 82275 : while (TREE_CODE (cond) == ANNOTATE_EXPR)
1436 355 : cond = TREE_OPERAND (cond, 0);
1437 81920 : if (trivial_infinite
1438 81984 : && !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1439 64 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1440 : /*trivial_infinite=*/true);
1441 81856 : else if (!trivially_empty
1442 347 : || !processing_template_decl
1443 82216 : || DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1444 81676 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1445 : /*trivial_infinite=*/false);
1446 : }
1447 12731237 : if (trivial_infinite && flag_finite_loops && !processing_template_decl)
1448 64 : *condp = build3 (ANNOTATE_EXPR, TREE_TYPE (*condp), *condp,
1449 : build_int_cst (integer_type_node,
1450 : annot_expr_maybe_infinite_kind),
1451 : integer_zero_node);
1452 : }
1453 :
1454 : /* Begin a while-statement. Returns a newly created WHILE_STMT if
1455 : appropriate. */
1456 :
1457 : tree
1458 4862857 : begin_while_stmt (void)
1459 : {
1460 4862857 : tree r;
1461 4862857 : r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1462 : NULL_TREE, NULL_TREE);
1463 4862857 : add_stmt (r);
1464 4862857 : WHILE_BODY (r) = do_pushlevel (sk_block);
1465 4862857 : begin_cond (&WHILE_COND (r));
1466 4862857 : return r;
1467 : }
1468 :
1469 : /* Process the COND of a while-statement, which may be given by
1470 : WHILE_STMT. */
1471 :
1472 : void
1473 4862857 : finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
1474 : tree unroll, bool novector)
1475 : {
1476 4862857 : cond = maybe_convert_cond (cond);
1477 4862857 : finish_cond (&WHILE_COND (while_stmt), cond);
1478 4862857 : begin_maybe_infinite_loop (cond);
1479 4862857 : if (ivdep && cond != error_mark_node)
1480 24 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1481 12 : TREE_TYPE (WHILE_COND (while_stmt)),
1482 12 : WHILE_COND (while_stmt),
1483 : build_int_cst (integer_type_node,
1484 : annot_expr_ivdep_kind),
1485 : integer_zero_node);
1486 4862857 : if (unroll && cond != error_mark_node)
1487 25524 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1488 12762 : TREE_TYPE (WHILE_COND (while_stmt)),
1489 12762 : WHILE_COND (while_stmt),
1490 : build_int_cst (integer_type_node,
1491 : annot_expr_unroll_kind),
1492 : unroll);
1493 4862857 : if (novector && cond != error_mark_node)
1494 42 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1495 21 : TREE_TYPE (WHILE_COND (while_stmt)),
1496 21 : WHILE_COND (while_stmt),
1497 : build_int_cst (integer_type_node,
1498 : annot_expr_no_vector_kind),
1499 : integer_zero_node);
1500 4862857 : adjust_loop_decl_cond (&WHILE_BODY (while_stmt),
1501 : &WHILE_COND_PREP (while_stmt),
1502 : &WHILE_COND_CLEANUP (while_stmt));
1503 4862857 : }
1504 :
1505 : /* Finish a while-statement, which may be given by WHILE_STMT. */
1506 :
1507 : void
1508 4862857 : finish_while_stmt (tree while_stmt)
1509 : {
1510 4862857 : end_maybe_infinite_loop (boolean_true_node);
1511 4862857 : if (WHILE_COND_PREP (while_stmt))
1512 9182 : finish_loop_cond_prep (&WHILE_BODY (while_stmt),
1513 : &WHILE_COND_PREP (while_stmt),
1514 9182 : WHILE_COND_CLEANUP (while_stmt));
1515 : else
1516 4853675 : WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
1517 4862857 : finish_loop_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
1518 4862857 : }
1519 :
1520 : /* Begin a do-statement. Returns a newly created DO_STMT if
1521 : appropriate. */
1522 :
1523 : tree
1524 5552936 : begin_do_stmt (void)
1525 : {
1526 5552936 : tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE,
1527 : NULL_TREE);
1528 5552936 : begin_maybe_infinite_loop (boolean_true_node);
1529 5552936 : add_stmt (r);
1530 5552936 : DO_BODY (r) = push_stmt_list ();
1531 5552936 : return r;
1532 : }
1533 :
1534 : /* Finish the body of a do-statement, which may be given by DO_STMT. */
1535 :
1536 : void
1537 5552936 : finish_do_body (tree do_stmt)
1538 : {
1539 5552936 : tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
1540 :
1541 5552936 : if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body))
1542 515668 : body = STATEMENT_LIST_TAIL (body)->stmt;
1543 :
1544 5552936 : if (IS_EMPTY_STMT (body))
1545 30 : warning (OPT_Wempty_body,
1546 : "suggest explicit braces around empty body in %<do%> statement");
1547 5552936 : }
1548 :
1549 : /* Finish a do-statement, which may be given by DO_STMT, and whose
1550 : COND is as indicated. */
1551 :
1552 : void
1553 5552936 : finish_do_stmt (tree cond, tree do_stmt, bool ivdep, tree unroll,
1554 : bool novector)
1555 : {
1556 5552936 : cond = maybe_convert_cond (cond);
1557 5552936 : end_maybe_infinite_loop (cond);
1558 : /* Unlike other iteration statements, the condition may not contain
1559 : a declaration, so we don't call finish_cond which checks for
1560 : unexpanded parameter packs. */
1561 5552936 : if (check_for_bare_parameter_packs (cond))
1562 3 : cond = error_mark_node;
1563 5552936 : if (ivdep && cond != error_mark_node)
1564 3 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
1565 : build_int_cst (integer_type_node, annot_expr_ivdep_kind),
1566 : integer_zero_node);
1567 5552936 : if (unroll && cond != error_mark_node)
1568 9 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
1569 : build_int_cst (integer_type_node, annot_expr_unroll_kind),
1570 : unroll);
1571 5552936 : if (novector && cond != error_mark_node)
1572 0 : cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
1573 : build_int_cst (integer_type_node, annot_expr_no_vector_kind),
1574 : integer_zero_node);
1575 5552936 : DO_COND (do_stmt) = cond;
1576 5552936 : tree do_body = DO_BODY (do_stmt);
1577 5552906 : if (CONVERT_EXPR_P (do_body)
1578 30 : && integer_zerop (TREE_OPERAND (do_body, 0))
1579 5552966 : && VOID_TYPE_P (TREE_TYPE (do_body)))
1580 : do_body = NULL_TREE;
1581 5552936 : finish_loop_cond (&DO_COND (do_stmt), do_body);
1582 5552936 : }
1583 :
1584 : /* Finish a return-statement. The EXPRESSION returned, if any, is as
1585 : indicated. */
1586 :
1587 : tree
1588 130587481 : finish_return_stmt (tree expr)
1589 : {
1590 130587481 : tree r;
1591 130587481 : bool no_warning;
1592 130587481 : bool dangling;
1593 :
1594 130587481 : expr = check_return_expr (expr, &no_warning, &dangling);
1595 :
1596 130587481 : if (error_operand_p (expr)
1597 130587481 : || (flag_openmp && !check_omp_return ()))
1598 : {
1599 : /* Suppress -Wreturn-type for this function. */
1600 1236 : if (warn_return_type)
1601 1230 : suppress_warning (current_function_decl, OPT_Wreturn_type);
1602 1236 : return error_mark_node;
1603 : }
1604 :
1605 130586245 : if (!processing_template_decl)
1606 : {
1607 50846841 : if (warn_sequence_point)
1608 1008218 : verify_sequence_points (expr);
1609 : }
1610 :
1611 130586245 : r = build_stmt (input_location, RETURN_EXPR, expr);
1612 130586245 : RETURN_EXPR_LOCAL_ADDR_P (r) = dangling;
1613 130586245 : if (no_warning)
1614 33 : suppress_warning (r, OPT_Wreturn_type);
1615 130586245 : r = maybe_cleanup_point_expr_void (r);
1616 130586245 : r = add_stmt (r);
1617 :
1618 130586245 : return r;
1619 : }
1620 :
1621 : /* Begin the scope of a for-statement or a range-for-statement.
1622 : Both the returned trees are to be used in a call to
1623 : begin_for_stmt or begin_range_for_stmt. */
1624 :
1625 : tree
1626 7682229 : begin_for_scope (tree *init)
1627 : {
1628 7682229 : tree scope = do_pushlevel (sk_for);
1629 :
1630 7682229 : if (processing_template_decl)
1631 5877571 : *init = push_stmt_list ();
1632 : else
1633 1804658 : *init = NULL_TREE;
1634 :
1635 7682229 : return scope;
1636 : }
1637 :
1638 : /* Begin a for-statement. Returns a new FOR_STMT.
1639 : SCOPE and INIT should be the return of begin_for_scope,
1640 : or both NULL_TREE */
1641 :
1642 : tree
1643 7476110 : begin_for_stmt (tree scope, tree init)
1644 : {
1645 7476110 : tree r;
1646 :
1647 7476110 : r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE,
1648 : NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE,
1649 : NULL_TREE, NULL_TREE);
1650 :
1651 7476110 : if (scope == NULL_TREE)
1652 : {
1653 1564143 : gcc_assert (!init);
1654 1564143 : scope = begin_for_scope (&init);
1655 : }
1656 :
1657 7476110 : FOR_INIT_STMT (r) = init;
1658 7476110 : FOR_SCOPE (r) = scope;
1659 :
1660 7476110 : return r;
1661 : }
1662 :
1663 : /* Finish the init-statement of a for-statement, which may be
1664 : given by FOR_STMT. */
1665 :
1666 : void
1667 7476110 : finish_init_stmt (tree for_stmt)
1668 : {
1669 7476110 : if (processing_template_decl)
1670 5671452 : FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
1671 7476110 : add_stmt (for_stmt);
1672 7476110 : FOR_BODY (for_stmt) = do_pushlevel (sk_block);
1673 7476110 : begin_cond (&FOR_COND (for_stmt));
1674 7476110 : }
1675 :
1676 : /* Finish the COND of a for-statement, which may be given by
1677 : FOR_STMT. */
1678 :
1679 : void
1680 7476110 : finish_for_cond (tree cond, tree for_stmt, bool ivdep, tree unroll,
1681 : bool novector)
1682 : {
1683 7476110 : cond = maybe_convert_cond (cond);
1684 7476110 : finish_cond (&FOR_COND (for_stmt), cond);
1685 7476110 : begin_maybe_infinite_loop (cond);
1686 7476110 : if (ivdep && cond != error_mark_node)
1687 68 : FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
1688 34 : TREE_TYPE (FOR_COND (for_stmt)),
1689 34 : FOR_COND (for_stmt),
1690 : build_int_cst (integer_type_node,
1691 : annot_expr_ivdep_kind),
1692 : integer_zero_node);
1693 7476110 : if (unroll && cond != error_mark_node)
1694 408 : FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
1695 204 : TREE_TYPE (FOR_COND (for_stmt)),
1696 204 : FOR_COND (for_stmt),
1697 : build_int_cst (integer_type_node,
1698 : annot_expr_unroll_kind),
1699 : unroll);
1700 7476110 : if (novector && cond && cond != error_mark_node)
1701 268 : FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR,
1702 134 : TREE_TYPE (FOR_COND (for_stmt)),
1703 134 : FOR_COND (for_stmt),
1704 : build_int_cst (integer_type_node,
1705 : annot_expr_no_vector_kind),
1706 : integer_zero_node);
1707 7476110 : adjust_loop_decl_cond (&FOR_BODY (for_stmt), &FOR_COND_PREP (for_stmt),
1708 : &FOR_COND_CLEANUP (for_stmt));
1709 7476110 : }
1710 :
1711 : /* Finish the increment-EXPRESSION in a for-statement, which may be
1712 : given by FOR_STMT. */
1713 :
1714 : void
1715 7464005 : finish_for_expr (tree expr, tree for_stmt)
1716 : {
1717 7464005 : if (!expr)
1718 : return;
1719 : /* If EXPR is an overloaded function, issue an error; there is no
1720 : context available to use to perform overload resolution. */
1721 7021778 : if (type_unknown_p (expr))
1722 : {
1723 6 : cxx_incomplete_type_error (expr, TREE_TYPE (expr));
1724 6 : expr = error_mark_node;
1725 : }
1726 7021778 : if (!processing_template_decl)
1727 : {
1728 1735544 : if (warn_sequence_point)
1729 14504 : verify_sequence_points (expr);
1730 1735544 : expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
1731 : tf_warning_or_error);
1732 : }
1733 5286234 : else if (!type_dependent_expression_p (expr))
1734 1903203 : convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error);
1735 7021778 : expr = maybe_cleanup_point_expr_void (expr);
1736 7021778 : if (check_for_bare_parameter_packs (expr))
1737 0 : expr = error_mark_node;
1738 7021778 : FOR_EXPR (for_stmt) = expr;
1739 : }
1740 :
1741 : /* During parsing of the body, range for uses "__for_{range,begin,end} "
1742 : decl names to make those unaccessible by code in the body.
1743 : Find those decls and store into RANGE_FOR_DECL array, so that they
1744 : can be changed later to ones with underscore instead of space, so that
1745 : it can be inspected in the debugger. */
1746 :
1747 : void
1748 7682342 : find_range_for_decls (tree range_for_decl[3])
1749 : {
1750 7682342 : gcc_assert (CPTI_FOR_BEGIN__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 1
1751 : && CPTI_FOR_END__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 2
1752 : && CPTI_FOR_RANGE_IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 3
1753 : && CPTI_FOR_BEGIN_IDENTIFIER == CPTI_FOR_BEGIN__IDENTIFIER + 3
1754 : && CPTI_FOR_END_IDENTIFIER == CPTI_FOR_END__IDENTIFIER + 3);
1755 30729368 : for (int i = 0; i < 3; i++)
1756 : {
1757 23047026 : tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i];
1758 23047026 : if (IDENTIFIER_BINDING (id)
1759 23047026 : && IDENTIFIER_BINDING (id)->scope == current_binding_level)
1760 : {
1761 330970 : range_for_decl[i] = IDENTIFIER_BINDING (id)->value;
1762 330970 : gcc_assert (VAR_P (range_for_decl[i])
1763 : && DECL_ARTIFICIAL (range_for_decl[i]));
1764 : }
1765 : }
1766 7682342 : }
1767 :
1768 : /* Finish the body of a for-statement, which may be given by
1769 : FOR_STMT. The increment-EXPR for the loop must be
1770 : provided.
1771 : It can also finish RANGE_FOR_STMT. */
1772 :
1773 : void
1774 7682229 : finish_for_stmt (tree for_stmt)
1775 : {
1776 7682229 : end_maybe_infinite_loop (boolean_true_node);
1777 :
1778 7682229 : if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
1779 206119 : RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
1780 : else
1781 : {
1782 7476110 : if (FOR_COND_PREP (for_stmt))
1783 174 : finish_loop_cond_prep (&FOR_BODY (for_stmt),
1784 : &FOR_COND_PREP (for_stmt),
1785 174 : FOR_COND_CLEANUP (for_stmt));
1786 : else
1787 7475936 : FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
1788 7476110 : if (FOR_COND (for_stmt))
1789 7118415 : finish_loop_cond (&FOR_COND (for_stmt),
1790 7118415 : FOR_EXPR (for_stmt) ? integer_one_node
1791 135775 : : FOR_BODY (for_stmt));
1792 : }
1793 :
1794 : /* Pop the scope for the body of the loop. */
1795 7682229 : tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
1796 7682229 : ? &RANGE_FOR_SCOPE (for_stmt)
1797 7476110 : : &FOR_SCOPE (for_stmt));
1798 7682229 : tree scope = *scope_ptr;
1799 7682229 : *scope_ptr = NULL;
1800 :
1801 : /* During parsing of the body, range for uses "__for_{range,begin,end} "
1802 : decl names to make those unaccessible by code in the body.
1803 : Change it to ones with underscore instead of space, so that it can
1804 : be inspected in the debugger. */
1805 7682229 : tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
1806 7682229 : find_range_for_decls (range_for_decl);
1807 :
1808 7682229 : add_stmt (do_poplevel (scope));
1809 :
1810 : /* If we're being called from build_vec_init, don't mess with the names of
1811 : the variables for an enclosing range-for. */
1812 7682229 : if (!stmts_are_full_exprs_p ())
1813 12105 : return;
1814 :
1815 30680496 : for (int i = 0; i < 3; i++)
1816 23010372 : if (range_for_decl[i])
1817 330854 : DECL_NAME (range_for_decl[i])
1818 330854 : = cp_global_trees[CPTI_FOR_RANGE_IDENTIFIER + i];
1819 : }
1820 :
1821 : /* Begin a range-for-statement. Returns a new RANGE_FOR_STMT.
1822 : SCOPE and INIT should be the return of begin_for_scope,
1823 : or both NULL_TREE .
1824 : To finish it call finish_for_stmt(). */
1825 :
1826 : tree
1827 206119 : begin_range_for_stmt (tree scope, tree init)
1828 : {
1829 206119 : begin_maybe_infinite_loop (boolean_false_node);
1830 :
1831 206119 : tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE,
1832 : NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
1833 :
1834 206119 : if (scope == NULL_TREE)
1835 : {
1836 240 : gcc_assert (!init);
1837 240 : scope = begin_for_scope (&init);
1838 : }
1839 :
1840 : /* Since C++20, RANGE_FOR_STMTs can use the init tree, so save it. */
1841 206119 : RANGE_FOR_INIT_STMT (r) = init;
1842 206119 : RANGE_FOR_SCOPE (r) = scope;
1843 :
1844 206119 : return r;
1845 : }
1846 :
1847 : /* Finish the head of a range-based for statement, which may
1848 : be given by RANGE_FOR_STMT. DECL must be the declaration
1849 : and EXPR must be the loop expression. */
1850 :
1851 : void
1852 206119 : finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
1853 : {
1854 206119 : if (processing_template_decl)
1855 412238 : RANGE_FOR_INIT_STMT (range_for_stmt)
1856 412238 : = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt));
1857 206119 : RANGE_FOR_DECL (range_for_stmt) = decl;
1858 206119 : RANGE_FOR_EXPR (range_for_stmt) = expr;
1859 206119 : add_stmt (range_for_stmt);
1860 206119 : RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
1861 206119 : }
1862 :
1863 : /* Begin the scope of an expansion-statement. */
1864 :
1865 : tree
1866 1140 : begin_template_for_scope (tree *init)
1867 : {
1868 1140 : tree scope = do_pushlevel (sk_template_for);
1869 :
1870 1140 : if (processing_template_decl)
1871 354 : *init = push_stmt_list ();
1872 : else
1873 786 : *init = NULL_TREE;
1874 :
1875 1140 : return scope;
1876 : }
1877 :
1878 : /* Finish a break-statement. */
1879 :
1880 : tree
1881 5674436 : finish_break_stmt (void)
1882 : {
1883 : /* In switch statements break is sometimes stylistically used after
1884 : a return statement. This can lead to spurious warnings about
1885 : control reaching the end of a non-void function when it is
1886 : inlined. Note that we are calling block_may_fallthru with
1887 : language specific tree nodes; this works because
1888 : block_may_fallthru returns true when given something it does not
1889 : understand. */
1890 5674436 : if (!block_may_fallthru (cur_stmt_list))
1891 711 : return void_node;
1892 5673725 : note_break_stmt ();
1893 5673725 : return add_stmt (build_stmt (input_location, BREAK_STMT, NULL_TREE));
1894 : }
1895 :
1896 : /* Finish a continue-statement. */
1897 :
1898 : tree
1899 223225 : finish_continue_stmt (void)
1900 : {
1901 223225 : return add_stmt (build_stmt (input_location, CONTINUE_STMT, NULL_TREE));
1902 : }
1903 :
1904 : /* Begin a switch-statement. Returns a new SWITCH_STMT if
1905 : appropriate. */
1906 :
1907 : tree
1908 1016802 : begin_switch_stmt (void)
1909 : {
1910 1016802 : tree r, scope;
1911 :
1912 1016802 : scope = do_pushlevel (sk_cond);
1913 1016802 : r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1914 : scope, NULL_TREE);
1915 :
1916 1016802 : begin_cond (&SWITCH_STMT_COND (r));
1917 :
1918 1016802 : return r;
1919 : }
1920 :
1921 : /* Finish the cond of a switch-statement. */
1922 :
1923 : void
1924 1016802 : finish_switch_cond (tree cond, tree switch_stmt)
1925 : {
1926 1016802 : tree orig_type = NULL;
1927 :
1928 1016802 : if (!processing_template_decl)
1929 : {
1930 : /* Convert the condition to an integer or enumeration type. */
1931 611419 : tree orig_cond = cond;
1932 : /* For structured binding used in condition, the conversion needs to be
1933 : evaluated before the individual variables are initialized in the
1934 : std::tuple_{size,elemenet} case. cp_finish_decomp saved the
1935 : conversion result in a TARGET_EXPR, pick it up from there. */
1936 122 : if (DECL_DECOMPOSITION_P (cond)
1937 57 : && DECL_DECOMP_IS_BASE (cond)
1938 57 : && DECL_DECOMP_BASE (cond)
1939 611473 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1940 18 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1941 611419 : cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
1942 611419 : if (cond == NULL_TREE)
1943 : {
1944 42 : error_at (cp_expr_loc_or_input_loc (orig_cond),
1945 : "switch quantity not an integer");
1946 27 : cond = error_mark_node;
1947 : }
1948 : /* We want unlowered type here to handle enum bit-fields. */
1949 611419 : orig_type = unlowered_expr_type (cond);
1950 611419 : if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
1951 263436 : orig_type = TREE_TYPE (cond);
1952 611419 : if (cond != error_mark_node)
1953 : {
1954 : /* [stmt.switch]
1955 :
1956 : Integral promotions are performed. */
1957 611386 : cond = perform_integral_promotions (cond);
1958 611386 : cond = maybe_cleanup_point_expr (cond);
1959 : }
1960 : }
1961 1016802 : if (check_for_bare_parameter_packs (cond))
1962 0 : cond = error_mark_node;
1963 1016802 : else if (!processing_template_decl && warn_sequence_point)
1964 2729 : verify_sequence_points (cond);
1965 :
1966 1016802 : finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
1967 1016802 : SWITCH_STMT_TYPE (switch_stmt) = orig_type;
1968 1016802 : add_stmt (switch_stmt);
1969 1016802 : push_switch (switch_stmt);
1970 1016802 : SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
1971 1016802 : }
1972 :
1973 : /* Finish the body of a switch-statement, which may be given by
1974 : SWITCH_STMT. The COND to switch on is indicated. */
1975 :
1976 : void
1977 1016802 : finish_switch_stmt (tree switch_stmt)
1978 : {
1979 1016802 : tree scope;
1980 :
1981 2033604 : SWITCH_STMT_BODY (switch_stmt) =
1982 1016802 : pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
1983 1016802 : pop_switch ();
1984 :
1985 1016802 : scope = SWITCH_STMT_SCOPE (switch_stmt);
1986 1016802 : SWITCH_STMT_SCOPE (switch_stmt) = NULL;
1987 1016802 : add_stmt (do_poplevel (scope));
1988 1016802 : }
1989 :
1990 : /* Begin a try-block. Returns a newly-created TRY_BLOCK if
1991 : appropriate. */
1992 :
1993 : tree
1994 1124737 : begin_try_block (void)
1995 : {
1996 1124737 : tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
1997 1124737 : add_stmt (r);
1998 1124737 : TRY_STMTS (r) = push_stmt_list ();
1999 1124737 : return r;
2000 : }
2001 :
2002 : /* Likewise, for a function-try-block. The block returned in
2003 : *COMPOUND_STMT is an artificial outer scope, containing the
2004 : function-try-block. */
2005 :
2006 : tree
2007 330 : begin_function_try_block (tree *compound_stmt)
2008 : {
2009 330 : tree r;
2010 : /* This outer scope does not exist in the C++ standard, but we need
2011 : a place to put __FUNCTION__ and similar variables. */
2012 330 : *compound_stmt = begin_compound_stmt (0);
2013 330 : current_binding_level->artificial = 1;
2014 330 : r = begin_try_block ();
2015 330 : FN_TRY_BLOCK_P (r) = 1;
2016 330 : return r;
2017 : }
2018 :
2019 : /* Finish a try-block, which may be given by TRY_BLOCK. */
2020 :
2021 : void
2022 1124737 : finish_try_block (tree try_block)
2023 : {
2024 1124737 : TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
2025 1124737 : TRY_HANDLERS (try_block) = push_stmt_list ();
2026 1124737 : }
2027 :
2028 : /* Finish the body of a cleanup try-block, which may be given by
2029 : TRY_BLOCK. */
2030 :
2031 : void
2032 0 : finish_cleanup_try_block (tree try_block)
2033 : {
2034 0 : TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
2035 0 : }
2036 :
2037 : /* Finish an implicitly generated try-block, with a cleanup is given
2038 : by CLEANUP. */
2039 :
2040 : void
2041 0 : finish_cleanup (tree cleanup, tree try_block)
2042 : {
2043 0 : TRY_HANDLERS (try_block) = cleanup;
2044 0 : CLEANUP_P (try_block) = 1;
2045 0 : }
2046 :
2047 : /* Likewise, for a function-try-block. */
2048 :
2049 : void
2050 330 : finish_function_try_block (tree try_block)
2051 : {
2052 330 : finish_try_block (try_block);
2053 : /* FIXME : something queer about CTOR_INITIALIZER somehow following
2054 : the try block, but moving it inside. */
2055 330 : in_function_try_handler = 1;
2056 330 : }
2057 :
2058 : /* Finish a handler-sequence for a try-block, which may be given by
2059 : TRY_BLOCK. */
2060 :
2061 : void
2062 1124737 : finish_handler_sequence (tree try_block)
2063 : {
2064 1124737 : TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
2065 1124737 : check_handlers (TRY_HANDLERS (try_block));
2066 1124737 : }
2067 :
2068 : /* Finish the handler-seq for a function-try-block, given by
2069 : TRY_BLOCK. COMPOUND_STMT is the outer block created by
2070 : begin_function_try_block. */
2071 :
2072 : void
2073 330 : finish_function_handler_sequence (tree try_block, tree compound_stmt)
2074 : {
2075 330 : in_function_try_handler = 0;
2076 330 : finish_handler_sequence (try_block);
2077 330 : finish_compound_stmt (compound_stmt);
2078 330 : }
2079 :
2080 : /* Begin a handler. Returns a HANDLER if appropriate. */
2081 :
2082 : tree
2083 1567991 : begin_handler (void)
2084 : {
2085 1567991 : tree r;
2086 :
2087 1567991 : r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
2088 1567991 : add_stmt (r);
2089 :
2090 : /* Create a binding level for the eh_info and the exception object
2091 : cleanup. */
2092 1567991 : HANDLER_BODY (r) = do_pushlevel (sk_catch);
2093 :
2094 1567991 : return r;
2095 : }
2096 :
2097 : /* Finish the handler-parameters for a handler, which may be given by
2098 : HANDLER. DECL is the declaration for the catch parameter, or NULL
2099 : if this is a `catch (...)' clause. */
2100 :
2101 : void
2102 1567991 : finish_handler_parms (tree decl, tree handler)
2103 : {
2104 1567991 : tree type = NULL_TREE;
2105 1567991 : if (processing_template_decl)
2106 : {
2107 1430719 : if (decl)
2108 : {
2109 466225 : decl = pushdecl (decl);
2110 466225 : decl = push_template_decl (decl);
2111 466225 : HANDLER_PARMS (handler) = decl;
2112 466225 : type = TREE_TYPE (decl);
2113 : }
2114 : }
2115 : else
2116 : {
2117 137272 : type = expand_start_catch_block (decl);
2118 137272 : if (warn_catch_value
2119 2070 : && type != NULL_TREE
2120 709 : && type != error_mark_node
2121 137981 : && !TYPE_REF_P (TREE_TYPE (decl)))
2122 : {
2123 210 : tree orig_type = TREE_TYPE (decl);
2124 210 : if (CLASS_TYPE_P (orig_type))
2125 : {
2126 96 : if (TYPE_POLYMORPHIC_P (orig_type))
2127 48 : warning_at (DECL_SOURCE_LOCATION (decl),
2128 48 : OPT_Wcatch_value_,
2129 : "catching polymorphic type %q#T by value",
2130 : orig_type);
2131 48 : else if (warn_catch_value > 1)
2132 36 : warning_at (DECL_SOURCE_LOCATION (decl),
2133 36 : OPT_Wcatch_value_,
2134 : "catching type %q#T by value", orig_type);
2135 : }
2136 114 : else if (warn_catch_value > 2)
2137 54 : warning_at (DECL_SOURCE_LOCATION (decl),
2138 54 : OPT_Wcatch_value_,
2139 : "catching non-reference type %q#T", orig_type);
2140 : }
2141 : }
2142 1567991 : HANDLER_TYPE (handler) = type;
2143 1567991 : }
2144 :
2145 : /* Finish a handler, which may be given by HANDLER. The BLOCKs are
2146 : the return value from the matching call to finish_handler_parms. */
2147 :
2148 : void
2149 1567991 : finish_handler (tree handler)
2150 : {
2151 1567991 : if (!processing_template_decl)
2152 137272 : expand_end_catch_block ();
2153 1567991 : HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
2154 1567991 : }
2155 :
2156 : /* Begin a compound statement. FLAGS contains some bits that control the
2157 : behavior and context. If BCS_NO_SCOPE is set, the compound statement
2158 : does not define a scope. If BCS_FN_BODY is set, this is the outermost
2159 : block of a function. If BCS_TRY_BLOCK is set, this is the block
2160 : created on behalf of a TRY statement. Returns a token to be passed to
2161 : finish_compound_stmt. */
2162 :
2163 : tree
2164 297791495 : begin_compound_stmt (unsigned int flags)
2165 : {
2166 297791495 : tree r;
2167 :
2168 297791495 : if (flags & BCS_NO_SCOPE)
2169 : {
2170 7812812 : r = push_stmt_list ();
2171 7812812 : STATEMENT_LIST_NO_SCOPE (r) = 1;
2172 :
2173 : /* Normally, we try hard to keep the BLOCK for a statement-expression.
2174 : But, if it's a statement-expression with a scopeless block, there's
2175 : nothing to keep, and we don't want to accidentally keep a block
2176 : *inside* the scopeless block. */
2177 7812812 : keep_next_level (false);
2178 : }
2179 : else
2180 : {
2181 289978683 : scope_kind sk = sk_block;
2182 289978683 : if (flags & BCS_TRY_BLOCK)
2183 : sk = sk_try;
2184 288854064 : else if (flags & BCS_TRANSACTION)
2185 : sk = sk_transaction;
2186 288853829 : else if (flags & BCS_STMT_EXPR)
2187 29082 : sk = sk_stmt_expr;
2188 289978683 : r = do_pushlevel (sk);
2189 : }
2190 :
2191 : /* When processing a template, we need to remember where the braces were,
2192 : so that we can set up identical scopes when instantiating the template
2193 : later. BIND_EXPR is a handy candidate for this.
2194 : Note that do_poplevel won't create a BIND_EXPR itself here (and thus
2195 : result in nested BIND_EXPRs), since we don't build BLOCK nodes when
2196 : processing templates. */
2197 297791495 : if (processing_template_decl)
2198 : {
2199 183639728 : r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
2200 183639728 : BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
2201 183639728 : BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
2202 183639728 : TREE_SIDE_EFFECTS (r) = 1;
2203 : }
2204 :
2205 297791495 : return r;
2206 : }
2207 :
2208 : /* Finish a compound-statement, which is given by STMT. */
2209 :
2210 : void
2211 297791456 : finish_compound_stmt (tree stmt)
2212 : {
2213 297791456 : if (TREE_CODE (stmt) == BIND_EXPR)
2214 : {
2215 183639728 : tree body = do_poplevel (BIND_EXPR_BODY (stmt));
2216 : /* If the STATEMENT_LIST is empty and this BIND_EXPR isn't special,
2217 : discard the BIND_EXPR so it can be merged with the containing
2218 : STATEMENT_LIST. */
2219 183639728 : if (TREE_CODE (body) == STATEMENT_LIST
2220 168217455 : && STATEMENT_LIST_HEAD (body) == NULL
2221 11250235 : && !BIND_EXPR_BODY_BLOCK (stmt)
2222 194394189 : && !BIND_EXPR_TRY_BLOCK (stmt))
2223 : stmt = body;
2224 : else
2225 172885364 : BIND_EXPR_BODY (stmt) = body;
2226 : }
2227 114151728 : else if (STATEMENT_LIST_NO_SCOPE (stmt))
2228 7776753 : stmt = pop_stmt_list (stmt);
2229 : else
2230 : {
2231 : /* Destroy any ObjC "super" receivers that may have been
2232 : created. */
2233 106374975 : objc_clear_super_receiver ();
2234 :
2235 106374975 : stmt = do_poplevel (stmt);
2236 : }
2237 :
2238 : /* ??? See c_end_compound_stmt wrt statement expressions. */
2239 297791456 : add_stmt (stmt);
2240 297791456 : }
2241 :
2242 : /* Finish an asm string literal, which can be a string literal
2243 : or parenthesized constant expression. Extract the string literal
2244 : from the latter. */
2245 :
2246 : tree
2247 52991 : finish_asm_string_expression (location_t loc, tree string)
2248 : {
2249 52991 : if (string == error_mark_node
2250 52978 : || TREE_CODE (string) == STRING_CST
2251 883 : || processing_template_decl)
2252 : return string;
2253 576 : string = cxx_constant_value (string, tf_error);
2254 576 : if (TREE_CODE (string) == STRING_CST)
2255 10 : string = build1_loc (loc, PAREN_EXPR, TREE_TYPE (string),
2256 : string);
2257 576 : cexpr_str cstr (string);
2258 576 : if (!cstr.type_check (loc))
2259 171 : return error_mark_node;
2260 405 : if (!cstr.extract (loc, string))
2261 62 : string = error_mark_node;
2262 405 : return string;
2263 576 : }
2264 :
2265 : /* Finish an asm-statement, whose components are a STRING, some
2266 : OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some
2267 : LABELS. Also note whether the asm-statement should be
2268 : considered volatile, and whether it is asm inline. TOPLEV_P
2269 : is true if finishing namespace scope extended asm. */
2270 :
2271 : tree
2272 25139 : finish_asm_stmt (location_t loc, int volatile_p, tree string,
2273 : tree output_operands, tree input_operands, tree clobbers,
2274 : tree labels, bool inline_p, bool toplev_p)
2275 : {
2276 25139 : tree r;
2277 25139 : tree t;
2278 25139 : int ninputs = list_length (input_operands);
2279 25139 : int noutputs = list_length (output_operands);
2280 :
2281 25139 : if (!processing_template_decl)
2282 : {
2283 12486 : const char *constraint;
2284 12486 : const char **oconstraints;
2285 12486 : bool allows_mem, allows_reg, is_inout;
2286 12486 : tree operand;
2287 12486 : int i;
2288 :
2289 12486 : oconstraints = XALLOCAVEC (const char *, noutputs);
2290 :
2291 24870 : string = finish_asm_string_expression (cp_expr_loc_or_loc (string, loc),
2292 : string);
2293 12486 : if (string == error_mark_node)
2294 109 : return error_mark_node;
2295 37176 : for (int i = 0; i < 2; ++i)
2296 84038 : for (t = i ? input_operands : output_operands; t; t = TREE_CHAIN (t))
2297 : {
2298 34470 : tree s = TREE_VALUE (TREE_PURPOSE (t));
2299 68922 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2300 34470 : if (s == error_mark_node)
2301 : return error_mark_node;
2302 34440 : TREE_VALUE (TREE_PURPOSE (t)) = s;
2303 : }
2304 17812 : for (t = clobbers; t; t = TREE_CHAIN (t))
2305 : {
2306 5435 : tree s = TREE_VALUE (t);
2307 10864 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2308 5435 : TREE_VALUE (t) = s;
2309 : }
2310 :
2311 12377 : string = resolve_asm_operand_names (string, output_operands,
2312 : input_operands, labels);
2313 :
2314 30346 : for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
2315 : {
2316 17969 : operand = TREE_VALUE (t);
2317 :
2318 : /* ??? Really, this should not be here. Users should be using a
2319 : proper lvalue, dammit. But there's a long history of using
2320 : casts in the output operands. In cases like longlong.h, this
2321 : becomes a primitive form of typechecking -- if the cast can be
2322 : removed, then the output operand had a type of the proper width;
2323 : otherwise we'll get an error. Gross, but ... */
2324 17969 : STRIP_NOPS (operand);
2325 :
2326 17969 : operand = mark_lvalue_use (operand);
2327 :
2328 17969 : if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
2329 9 : operand = error_mark_node;
2330 :
2331 17969 : if (operand != error_mark_node
2332 17969 : && (TREE_READONLY (operand)
2333 17954 : || CP_TYPE_CONST_P (TREE_TYPE (operand))
2334 : /* Functions are not modifiable, even though they are
2335 : lvalues. */
2336 17954 : || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (operand))
2337 : /* If it's an aggregate and any field is const, then it is
2338 : effectively const. */
2339 17954 : || (CLASS_TYPE_P (TREE_TYPE (operand))
2340 32 : && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
2341 6 : cxx_readonly_error (loc, operand, lv_asm);
2342 :
2343 : tree *op = &operand;
2344 17976 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2345 7 : op = &TREE_OPERAND (*op, 1);
2346 17969 : switch (TREE_CODE (*op))
2347 : {
2348 30 : case PREINCREMENT_EXPR:
2349 30 : case PREDECREMENT_EXPR:
2350 30 : case MODIFY_EXPR:
2351 30 : *op = genericize_compound_lvalue (*op);
2352 30 : op = &TREE_OPERAND (*op, 1);
2353 30 : break;
2354 : default:
2355 : break;
2356 : }
2357 :
2358 17969 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2359 17969 : oconstraints[i] = constraint;
2360 :
2361 17969 : if (parse_output_constraint (&constraint, i, ninputs, noutputs,
2362 : &allows_mem, &allows_reg, &is_inout,
2363 : nullptr))
2364 : {
2365 : /* If the operand is going to end up in memory,
2366 : mark it addressable. */
2367 17960 : if (!allows_reg && !cxx_mark_addressable (*op))
2368 0 : operand = error_mark_node;
2369 17960 : if (allows_reg && toplev_p)
2370 : {
2371 3 : error_at (loc, "constraint allows registers outside of "
2372 : "a function");
2373 3 : operand = error_mark_node;
2374 : }
2375 : }
2376 : else
2377 9 : operand = error_mark_node;
2378 :
2379 306 : if (toplev_p && operand != error_mark_node)
2380 : {
2381 21 : if (TREE_SIDE_EFFECTS (operand))
2382 : {
2383 0 : error_at (loc, "side-effects in output operand outside "
2384 : "of a function");
2385 0 : operand = error_mark_node;
2386 : }
2387 : else
2388 : {
2389 21 : tree addr
2390 21 : = cp_build_addr_expr (operand, tf_warning_or_error);
2391 21 : if (addr == error_mark_node)
2392 0 : operand = error_mark_node;
2393 : else
2394 : {
2395 21 : addr = maybe_constant_value (addr);
2396 21 : if (!initializer_constant_valid_p (addr,
2397 21 : TREE_TYPE (addr)))
2398 : {
2399 3 : error_at (loc, "output operand outside of a "
2400 : "function is not constant");
2401 3 : operand = error_mark_node;
2402 : }
2403 : else
2404 18 : operand = build_fold_indirect_ref (addr);
2405 : }
2406 : }
2407 : }
2408 17948 : else if (operand != error_mark_node && strstr (constraint, "-"))
2409 : {
2410 3 : error_at (loc, "%<-%> modifier used inside of a function");
2411 3 : operand = error_mark_node;
2412 : }
2413 :
2414 17969 : TREE_VALUE (t) = operand;
2415 : }
2416 :
2417 28843 : for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
2418 : {
2419 16466 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2420 16466 : bool constraint_parsed
2421 16466 : = parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
2422 : oconstraints, &allows_mem, &allows_reg,
2423 : nullptr);
2424 : /* If the operand is going to end up in memory, don't call
2425 : decay_conversion. */
2426 16466 : if (constraint_parsed && !allows_reg && allows_mem)
2427 166 : operand = mark_lvalue_use (TREE_VALUE (t));
2428 : else
2429 16300 : operand = decay_conversion (TREE_VALUE (t), tf_warning_or_error);
2430 :
2431 : /* If the type of the operand hasn't been determined (e.g.,
2432 : because it involves an overloaded function), then issue
2433 : an error message. There's no context available to
2434 : resolve the overloading. */
2435 16466 : if (TREE_TYPE (operand) == unknown_type_node)
2436 : {
2437 3 : error_at (loc,
2438 : "type of %<asm%> operand %qE could not be determined",
2439 3 : TREE_VALUE (t));
2440 3 : operand = error_mark_node;
2441 : }
2442 :
2443 16466 : if (constraint_parsed)
2444 : {
2445 : /* If the operand is going to end up in memory,
2446 : mark it addressable. */
2447 16445 : if (!allows_reg && allows_mem)
2448 : {
2449 : /* Strip the nops as we allow this case. FIXME, this really
2450 : should be rejected or made deprecated. */
2451 166 : STRIP_NOPS (operand);
2452 :
2453 166 : tree *op = &operand;
2454 173 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2455 7 : op = &TREE_OPERAND (*op, 1);
2456 166 : switch (TREE_CODE (*op))
2457 : {
2458 27 : case PREINCREMENT_EXPR:
2459 27 : case PREDECREMENT_EXPR:
2460 27 : case MODIFY_EXPR:
2461 27 : *op = genericize_compound_lvalue (*op);
2462 27 : op = &TREE_OPERAND (*op, 1);
2463 27 : break;
2464 : default:
2465 : break;
2466 : }
2467 :
2468 166 : if (!cxx_mark_addressable (*op))
2469 0 : operand = error_mark_node;
2470 : }
2471 16279 : else if (!allows_reg && !allows_mem)
2472 : {
2473 : /* If constraint allows neither register nor memory,
2474 : try harder to get a constant. */
2475 474 : tree constop = maybe_constant_value (operand);
2476 474 : if (TREE_CONSTANT (constop))
2477 447 : operand = constop;
2478 : }
2479 16445 : if (allows_reg && toplev_p)
2480 : {
2481 3 : error_at (loc, "constraint allows registers outside of "
2482 : "a function");
2483 3 : operand = error_mark_node;
2484 : }
2485 16445 : if (constraint[0] == ':' && operand != error_mark_node)
2486 : {
2487 48 : tree t = operand;
2488 48 : STRIP_NOPS (t);
2489 48 : if (TREE_CODE (t) != ADDR_EXPR
2490 48 : || !(TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
2491 30 : || (VAR_P (TREE_OPERAND (t, 0))
2492 24 : && is_global_var (TREE_OPERAND (t, 0)))))
2493 : {
2494 15 : error_at (loc, "%<:%> constraint operand is not address "
2495 : "of a function or non-automatic variable");
2496 15 : operand = error_mark_node;
2497 : }
2498 33 : else if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
2499 12 : suppress_warning (TREE_OPERAND (t, 0), OPT_Wunused);
2500 : }
2501 : }
2502 : else
2503 21 : operand = error_mark_node;
2504 :
2505 16466 : if (toplev_p && operand != error_mark_node)
2506 : {
2507 117 : if (TREE_SIDE_EFFECTS (operand))
2508 : {
2509 6 : error_at (loc, "side-effects in input operand outside "
2510 : "of a function");
2511 6 : operand = error_mark_node;
2512 : }
2513 111 : else if (allows_mem && lvalue_or_else (operand, lv_asm, tf_none))
2514 : {
2515 21 : tree addr = cp_build_addr_expr (operand, tf_warning_or_error);
2516 21 : if (addr == error_mark_node)
2517 0 : operand = error_mark_node;
2518 : else
2519 : {
2520 21 : addr = maybe_constant_value (addr);
2521 21 : if (!initializer_constant_valid_p (addr,
2522 21 : TREE_TYPE (addr)))
2523 : {
2524 3 : error_at (loc, "input operand outside of a "
2525 : "function is not constant");
2526 3 : operand = error_mark_node;
2527 : }
2528 : else
2529 18 : operand = build_fold_indirect_ref (addr);
2530 : }
2531 : }
2532 : else
2533 : {
2534 90 : operand = maybe_constant_value (operand);
2535 90 : if (!initializer_constant_valid_p (operand,
2536 90 : TREE_TYPE (operand)))
2537 : {
2538 3 : error_at (loc, "input operand outside of a "
2539 : "function is not constant");
2540 3 : operand = error_mark_node;
2541 : }
2542 : }
2543 : }
2544 16349 : else if (operand != error_mark_node && strstr (constraint, "-"))
2545 : {
2546 9 : error_at (loc, "%<-%> modifier used inside of a function");
2547 9 : operand = error_mark_node;
2548 : }
2549 :
2550 16466 : TREE_VALUE (t) = operand;
2551 : }
2552 : }
2553 :
2554 25030 : r = build_stmt (loc, ASM_EXPR, string,
2555 : output_operands, input_operands,
2556 : clobbers, labels);
2557 25030 : ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
2558 25030 : ASM_INLINE_P (r) = inline_p;
2559 25030 : if (toplev_p)
2560 : {
2561 99 : symtab->finalize_toplevel_asm (r);
2562 99 : return r;
2563 : }
2564 24931 : r = maybe_cleanup_point_expr_void (r);
2565 24931 : return add_stmt (r);
2566 : }
2567 :
2568 : /* Finish a label with the indicated NAME. Returns the new label. */
2569 :
2570 : tree
2571 2478 : finish_label_stmt (tree name)
2572 : {
2573 2478 : tree decl = define_label (input_location, name);
2574 :
2575 2478 : if (decl == error_mark_node)
2576 : return error_mark_node;
2577 :
2578 2472 : add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
2579 :
2580 2472 : return decl;
2581 : }
2582 :
2583 : /* Finish a series of declarations for local labels. G++ allows users
2584 : to declare "local" labels, i.e., labels with scope. This extension
2585 : is useful when writing code involving statement-expressions. */
2586 :
2587 : void
2588 219 : finish_label_decl (tree name)
2589 : {
2590 219 : if (!at_function_scope_p ())
2591 : {
2592 0 : error ("%<__label__%> declarations are only allowed in function scopes");
2593 0 : return;
2594 : }
2595 :
2596 219 : add_decl_expr (declare_local_label (name));
2597 : }
2598 :
2599 : /* When DECL goes out of scope, make sure that CLEANUP is executed. */
2600 :
2601 : void
2602 3906333 : finish_decl_cleanup (tree decl, tree cleanup)
2603 : {
2604 3906333 : push_cleanup (decl, cleanup, false);
2605 3906333 : }
2606 :
2607 : /* If the current scope exits with an exception, run CLEANUP. */
2608 :
2609 : void
2610 2171892 : finish_eh_cleanup (tree cleanup)
2611 : {
2612 2171892 : push_cleanup (NULL, cleanup, true);
2613 2171892 : }
2614 :
2615 : /* The MEM_INITS is a list of mem-initializers, in reverse of the
2616 : order they were written by the user. Each node is as for
2617 : emit_mem_initializers. */
2618 :
2619 : void
2620 20498940 : finish_mem_initializers (tree mem_inits)
2621 : {
2622 : /* Reorder the MEM_INITS so that they are in the order they appeared
2623 : in the source program. */
2624 20498940 : mem_inits = nreverse (mem_inits);
2625 :
2626 20498940 : if (processing_template_decl)
2627 : {
2628 : tree mem;
2629 :
2630 33247833 : for (mem = mem_inits; mem; mem = TREE_CHAIN (mem))
2631 : {
2632 : /* If the TREE_PURPOSE is a TYPE_PACK_EXPANSION, skip the
2633 : check for bare parameter packs in the TREE_VALUE, because
2634 : any parameter packs in the TREE_VALUE have already been
2635 : bound as part of the TREE_PURPOSE. See
2636 : make_pack_expansion for more information. */
2637 19682994 : if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
2638 19682994 : && check_for_bare_parameter_packs (TREE_VALUE (mem)))
2639 3 : TREE_VALUE (mem) = error_mark_node;
2640 : }
2641 :
2642 13564839 : add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
2643 : CTOR_INITIALIZER, mem_inits));
2644 : }
2645 : else
2646 6934101 : emit_mem_initializers (mem_inits);
2647 20498940 : }
2648 :
2649 : /* Obfuscate EXPR if it looks like an id-expression or member access so
2650 : that the call to finish_decltype in do_auto_deduction will give the
2651 : right result. If EVEN_UNEVAL, do this even in unevaluated context. */
2652 :
2653 : tree
2654 46931029 : force_paren_expr (tree expr, bool even_uneval /* = false */)
2655 : {
2656 : /* This is only needed for decltype(auto) in C++14. */
2657 46931029 : if (cxx_dialect < cxx14)
2658 : return expr;
2659 :
2660 : /* If we're in unevaluated context, we can't be deducing a
2661 : return/initializer type, so we don't need to mess with this. */
2662 46299652 : if (cp_unevaluated_operand && !even_uneval)
2663 : return expr;
2664 :
2665 38857872 : if (TREE_CODE (expr) == COMPONENT_REF
2666 38800941 : || TREE_CODE (expr) == SCOPE_REF
2667 77652682 : || REFERENCE_REF_P (expr))
2668 893761 : REF_PARENTHESIZED_P (expr) = true;
2669 37964111 : else if (DECL_P (tree_strip_any_location_wrapper (expr)))
2670 : {
2671 1898262 : location_t loc = cp_expr_location (expr);
2672 1898262 : const tree_code code = processing_template_decl ? PAREN_EXPR
2673 : : VIEW_CONVERT_EXPR;
2674 1898262 : expr = build1_loc (loc, code, TREE_TYPE (expr), expr);
2675 1898262 : REF_PARENTHESIZED_P (expr) = true;
2676 : }
2677 : return expr;
2678 : }
2679 :
2680 : /* If T is an id-expression obfuscated by force_paren_expr, undo the
2681 : obfuscation and return the underlying id-expression. Otherwise
2682 : return T. */
2683 :
2684 : tree
2685 1217521355 : maybe_undo_parenthesized_ref (tree t)
2686 : {
2687 1217521355 : if (cxx_dialect < cxx14)
2688 : return t;
2689 :
2690 1207637993 : if ((TREE_CODE (t) == PAREN_EXPR || TREE_CODE (t) == VIEW_CONVERT_EXPR)
2691 1340942119 : && REF_PARENTHESIZED_P (t))
2692 290770 : t = TREE_OPERAND (t, 0);
2693 :
2694 : return t;
2695 : }
2696 :
2697 : /* Finish a parenthesized expression EXPR. */
2698 :
2699 : cp_expr
2700 32268306 : finish_parenthesized_expr (cp_expr expr)
2701 : {
2702 32268306 : if (EXPR_P (expr))
2703 : {
2704 : /* This inhibits warnings in maybe_warn_unparenthesized_assignment
2705 : and c_common_truthvalue_conversion. */
2706 64250932 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wparentheses);
2707 : /* And maybe_warn_sizeof_array_div. */
2708 64250932 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wsizeof_array_div);
2709 : }
2710 :
2711 32268306 : if (TREE_CODE (expr) == OFFSET_REF
2712 32268306 : || TREE_CODE (expr) == SCOPE_REF)
2713 : /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
2714 : enclosed in parentheses. */
2715 28854 : PTRMEM_OK_P (expr) = 0;
2716 :
2717 32268306 : tree stripped_expr = tree_strip_any_location_wrapper (expr);
2718 32268306 : if (TREE_CODE (stripped_expr) == STRING_CST)
2719 818174 : PAREN_STRING_LITERAL_P (stripped_expr) = 1;
2720 31450132 : else if (TREE_CODE (stripped_expr) == PACK_INDEX_EXPR)
2721 850 : PACK_INDEX_PARENTHESIZED_P (stripped_expr) = true;
2722 :
2723 32268306 : expr = cp_expr (force_paren_expr (expr), expr.get_location ());
2724 :
2725 32268306 : return expr;
2726 : }
2727 :
2728 : /* Finish a reference to a non-static data member (DECL) that is not
2729 : preceded by `.' or `->'. */
2730 :
2731 : tree
2732 84230182 : finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
2733 : tsubst_flags_t complain /* = tf_warning_or_error */)
2734 : {
2735 84230182 : gcc_assert (TREE_CODE (decl) == FIELD_DECL);
2736 84230182 : bool try_omp_private = !object && omp_private_member_map;
2737 65069401 : tree ret;
2738 :
2739 65069401 : if (!object)
2740 : {
2741 65069401 : tree scope = qualifying_scope;
2742 65069401 : if (scope == NULL_TREE)
2743 : {
2744 65058388 : scope = context_for_name_lookup (decl);
2745 65058388 : if (!TYPE_P (scope))
2746 : {
2747 : /* Can happen during error recovery (c++/85014). */
2748 3 : gcc_assert (seen_error ());
2749 3 : return error_mark_node;
2750 : }
2751 : }
2752 65069398 : object = maybe_dummy_object (scope, NULL);
2753 : }
2754 :
2755 84230179 : object = maybe_resolve_dummy (object, true);
2756 84230179 : if (object == error_mark_node)
2757 : return error_mark_node;
2758 :
2759 : /* DR 613/850: Can use non-static data members without an associated
2760 : object in sizeof/decltype/alignof. */
2761 84230176 : if (is_dummy_object (object)
2762 29928 : && !cp_unevaluated_operand
2763 84230270 : && (!processing_template_decl || !current_class_ref))
2764 : {
2765 79 : if (complain & tf_error)
2766 : {
2767 73 : auto_diagnostic_group d;
2768 73 : if (current_function_decl
2769 73 : && DECL_STATIC_FUNCTION_P (current_function_decl))
2770 3 : error ("invalid use of member %qD in static member function", decl);
2771 70 : else if (current_function_decl
2772 63 : && processing_contract_condition
2773 70 : && DECL_CONSTRUCTOR_P (current_function_decl))
2774 0 : error ("invalid use of member %qD in constructor %<pre%> contract", decl);
2775 70 : else if (current_function_decl
2776 63 : && processing_contract_condition
2777 70 : && DECL_DESTRUCTOR_P (current_function_decl))
2778 0 : error ("invalid use of member %qD in destructor %<post%> contract", decl);
2779 : else
2780 70 : error ("invalid use of non-static data member %qD", decl);
2781 73 : inform (DECL_SOURCE_LOCATION (decl), "declared here");
2782 73 : }
2783 :
2784 79 : return error_mark_node;
2785 : }
2786 :
2787 84230097 : if (current_class_ptr)
2788 83816577 : TREE_USED (current_class_ptr) = 1;
2789 84230097 : if (processing_template_decl)
2790 : {
2791 59491068 : tree type = TREE_TYPE (decl);
2792 :
2793 59491068 : if (TYPE_REF_P (type))
2794 : /* Quals on the object don't matter. */;
2795 57193763 : else if (PACK_EXPANSION_P (type))
2796 : /* Don't bother trying to represent this. */
2797 : type = NULL_TREE;
2798 57191447 : else if (!TREE_TYPE (object) || WILDCARD_TYPE_P (TREE_TYPE (object)))
2799 : /* We don't know what the eventual quals will be, so punt until
2800 : instantiation time.
2801 :
2802 : This can happen when called from build_capture_proxy for an explicit
2803 : object lambda. It's a bit marginal to call this function in that
2804 : case, since this function is for references to members of 'this',
2805 : but the deduced type is required to be derived from the closure
2806 : type, so it works. */
2807 : type = NULL_TREE;
2808 : else
2809 : {
2810 : /* Set the cv qualifiers. */
2811 57189306 : int quals = cp_type_quals (TREE_TYPE (object));
2812 :
2813 57189306 : if (DECL_MUTABLE_P (decl))
2814 287514 : quals &= ~TYPE_QUAL_CONST;
2815 :
2816 57189306 : quals |= cp_type_quals (TREE_TYPE (decl));
2817 57189306 : type = cp_build_qualified_type (type, quals);
2818 : }
2819 :
2820 59491068 : if (qualifying_scope)
2821 : /* Wrap this in a SCOPE_REF for now. */
2822 9110 : ret = build_qualified_name (type, qualifying_scope, decl,
2823 : /*template_p=*/false);
2824 : else
2825 59481958 : ret = (convert_from_reference
2826 59481958 : (build_min (COMPONENT_REF, type, object, decl, NULL_TREE)));
2827 : }
2828 : /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
2829 : QUALIFYING_SCOPE is also non-null. */
2830 : else
2831 : {
2832 24739029 : tree access_type = TREE_TYPE (object);
2833 :
2834 24739029 : if (!perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
2835 : decl, complain))
2836 0 : return error_mark_node;
2837 :
2838 : /* If the data member was named `C::M', convert `*this' to `C'
2839 : first. */
2840 24739029 : if (qualifying_scope)
2841 : {
2842 1867 : tree binfo = NULL_TREE;
2843 1867 : object = build_scoped_ref (object, qualifying_scope,
2844 : &binfo);
2845 : }
2846 :
2847 24739029 : ret = build_class_member_access_expr (object, decl,
2848 : /*access_path=*/NULL_TREE,
2849 : /*preserve_reference=*/false,
2850 : complain);
2851 : }
2852 84230097 : if (try_omp_private)
2853 : {
2854 1671 : tree *v = omp_private_member_map->get (decl);
2855 1671 : if (v)
2856 1243 : ret = convert_from_reference (*v);
2857 : }
2858 : return ret;
2859 : }
2860 :
2861 : /* DECL was the declaration to which a qualified-id resolved. Issue
2862 : an error message if it is not accessible. If OBJECT_TYPE is
2863 : non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
2864 : type of `*x', or `x', respectively. If the DECL was named as
2865 : `A::B' then NESTED_NAME_SPECIFIER is `A'. Return value is like
2866 : perform_access_checks above. */
2867 :
2868 : bool
2869 4760876510 : check_accessibility_of_qualified_id (tree decl,
2870 : tree object_type,
2871 : tree nested_name_specifier,
2872 : tsubst_flags_t complain)
2873 : {
2874 : /* If we're not checking, return immediately. */
2875 4760876510 : if (deferred_access_no_check)
2876 : return true;
2877 :
2878 : /* Determine the SCOPE of DECL. */
2879 4753009244 : tree scope = context_for_name_lookup (decl);
2880 : /* If the SCOPE is not a type, then DECL is not a member. */
2881 4753009244 : if (!TYPE_P (scope)
2882 : /* If SCOPE is dependent then we can't perform this access check now,
2883 : and since we'll perform this access check again after substitution
2884 : there's no need to explicitly defer it. */
2885 4753009244 : || dependent_type_p (scope))
2886 4193880170 : return true;
2887 :
2888 559129074 : tree qualifying_type = NULL_TREE;
2889 : /* Compute the scope through which DECL is being accessed. */
2890 559129074 : if (object_type
2891 : /* OBJECT_TYPE might not be a class type; consider:
2892 :
2893 : class A { typedef int I; };
2894 : I *p;
2895 : p->A::I::~I();
2896 :
2897 : In this case, we will have "A::I" as the DECL, but "I" as the
2898 : OBJECT_TYPE. */
2899 93573 : && CLASS_TYPE_P (object_type)
2900 559222630 : && DERIVED_FROM_P (scope, object_type))
2901 : {
2902 : /* If we are processing a `->' or `.' expression, use the type of the
2903 : left-hand side. */
2904 93547 : if (tree open = currently_open_class (object_type))
2905 : qualifying_type = open;
2906 : else
2907 : qualifying_type = object_type;
2908 : }
2909 559035527 : else if (nested_name_specifier)
2910 : {
2911 : /* If the reference is to a non-static member of the
2912 : current class, treat it as if it were referenced through
2913 : `this'. */
2914 817674799 : if (DECL_NONSTATIC_MEMBER_P (decl)
2915 408886863 : && current_class_ptr)
2916 39686 : if (tree current = current_nonlambda_class_type ())
2917 : {
2918 39663 : if (dependent_type_p (current))
2919 : /* In general we can't know whether this access goes through
2920 : `this' until instantiation time. Punt now, or else we might
2921 : create a deferred access check that's not relative to `this'
2922 : when it ought to be. We'll check this access again after
2923 : substitution, e.g. from tsubst_qualified_id. */
2924 : return true;
2925 :
2926 3557 : if (DERIVED_FROM_P (scope, current))
2927 : qualifying_type = current;
2928 : }
2929 : /* Otherwise, use the type indicated by the
2930 : nested-name-specifier. */
2931 : if (!qualifying_type)
2932 : qualifying_type = nested_name_specifier;
2933 : }
2934 : else
2935 : /* Otherwise, the name must be from the current class or one of
2936 : its bases. */
2937 150198126 : qualifying_type = currently_open_derived_class (scope);
2938 :
2939 559036020 : if (qualifying_type
2940 : /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
2941 : or similar in a default argument value. */
2942 559092968 : && CLASS_TYPE_P (qualifying_type))
2943 533052580 : return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
2944 533052580 : decl, complain);
2945 :
2946 : return true;
2947 : }
2948 :
2949 : /* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the
2950 : class named to the left of the "::" operator. DONE is true if this
2951 : expression is a complete postfix-expression; it is false if this
2952 : expression is followed by '->', '[', '(', etc. ADDRESS_P is true
2953 : iff this expression is the operand of '&'. TEMPLATE_P is true iff
2954 : the qualified-id was of the form "A::template B". TEMPLATE_ARG_P
2955 : is true iff this qualified name appears as a template argument. */
2956 :
2957 : tree
2958 96464704 : finish_qualified_id_expr (tree qualifying_class,
2959 : tree expr,
2960 : bool done,
2961 : bool address_p,
2962 : bool template_p,
2963 : bool template_arg_p,
2964 : tsubst_flags_t complain)
2965 : {
2966 96464704 : gcc_assert (TYPE_P (qualifying_class));
2967 :
2968 96464704 : if (error_operand_p (expr))
2969 21 : return error_mark_node;
2970 :
2971 96464683 : if (DECL_P (expr)
2972 : /* Functions are marked after overload resolution; avoid redundant
2973 : warnings. */
2974 88921970 : && TREE_CODE (expr) != FUNCTION_DECL
2975 185386629 : && !mark_used (expr, complain))
2976 0 : return error_mark_node;
2977 :
2978 96464683 : if (template_p)
2979 : {
2980 236362 : if (TREE_CODE (expr) == UNBOUND_CLASS_TEMPLATE)
2981 : {
2982 : /* cp_parser_lookup_name thought we were looking for a type,
2983 : but we're actually looking for a declaration. */
2984 9 : qualifying_class = TYPE_CONTEXT (expr);
2985 9 : expr = TYPE_IDENTIFIER (expr);
2986 : }
2987 : else
2988 236353 : check_template_keyword (expr);
2989 : }
2990 :
2991 : /* If EXPR occurs as the operand of '&', use special handling that
2992 : permits a pointer-to-member. */
2993 96464683 : if (address_p && done
2994 154482 : && TREE_CODE (qualifying_class) != ENUMERAL_TYPE)
2995 : {
2996 154480 : if (TREE_CODE (expr) == SCOPE_REF)
2997 0 : expr = TREE_OPERAND (expr, 1);
2998 154480 : expr = build_offset_ref (qualifying_class, expr,
2999 : /*address_p=*/true, complain);
3000 154480 : return expr;
3001 : }
3002 :
3003 : /* No need to check access within an enum. */
3004 96310203 : if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE
3005 3389340 : && TREE_CODE (expr) != IDENTIFIER_NODE)
3006 : return expr;
3007 :
3008 : /* Within the scope of a class, turn references to non-static
3009 : members into expression of the form "this->...". */
3010 92920866 : if (template_arg_p)
3011 : /* But, within a template argument, we do not want make the
3012 : transformation, as there is no "this" pointer. */
3013 : ;
3014 92918258 : else if (TREE_CODE (expr) == FIELD_DECL)
3015 : {
3016 11013 : push_deferring_access_checks (dk_no_check);
3017 11013 : expr = finish_non_static_data_member (expr, NULL_TREE,
3018 : qualifying_class, complain);
3019 11013 : pop_deferring_access_checks ();
3020 : }
3021 92907245 : else if (BASELINK_P (expr))
3022 : {
3023 : /* See if any of the functions are non-static members. */
3024 : /* If so, the expression may be relative to 'this'. */
3025 7106331 : if (!shared_member_p (expr)
3026 456978 : && current_class_ptr
3027 7562706 : && DERIVED_FROM_P (qualifying_class,
3028 : current_nonlambda_class_type ()))
3029 456175 : expr = (build_class_member_access_expr
3030 456175 : (maybe_dummy_object (qualifying_class, NULL),
3031 : expr,
3032 456175 : BASELINK_ACCESS_BINFO (expr),
3033 : /*preserve_reference=*/false,
3034 : complain));
3035 6650156 : else if (done)
3036 : /* The expression is a qualified name whose address is not
3037 : being taken. */
3038 2358 : expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
3039 : complain);
3040 : }
3041 85800914 : else if (!template_p
3042 85608859 : && TREE_CODE (expr) == TEMPLATE_DECL
3043 85800994 : && !DECL_FUNCTION_TEMPLATE_P (expr))
3044 : {
3045 80 : if (complain & tf_error)
3046 4 : error ("%qE missing template arguments", expr);
3047 80 : return error_mark_node;
3048 : }
3049 : else
3050 : {
3051 : /* In a template, return a SCOPE_REF for most qualified-ids
3052 : so that we can check access at instantiation time. But if
3053 : we're looking at a member of the current instantiation, we
3054 : know we have access and building up the SCOPE_REF confuses
3055 : non-type template argument handling. */
3056 85800834 : if (processing_template_decl
3057 85800834 : && (!currently_open_class (qualifying_class)
3058 9816 : || TREE_CODE (expr) == IDENTIFIER_NODE
3059 9816 : || TREE_CODE (expr) == TEMPLATE_ID_EXPR
3060 82 : || TREE_CODE (expr) == BIT_NOT_EXPR))
3061 10520521 : expr = build_qualified_name (TREE_TYPE (expr),
3062 : qualifying_class, expr,
3063 : template_p);
3064 75280313 : else if (tree wrap = maybe_get_tls_wrapper_call (expr))
3065 9 : expr = wrap;
3066 :
3067 85800834 : expr = convert_from_reference (expr);
3068 : }
3069 :
3070 : return expr;
3071 : }
3072 :
3073 : /* Begin a statement-expression. The value returned must be passed to
3074 : finish_stmt_expr. */
3075 :
3076 : tree
3077 7834494 : begin_stmt_expr (void)
3078 : {
3079 7834494 : return push_stmt_list ();
3080 : }
3081 :
3082 : /* Process the final expression of a statement expression. EXPR can be
3083 : NULL, if the final expression is empty. Return a STATEMENT_LIST
3084 : containing all the statements in the statement-expression, or
3085 : ERROR_MARK_NODE if there was an error. */
3086 :
3087 : tree
3088 29523 : finish_stmt_expr_expr (tree expr, tree stmt_expr)
3089 : {
3090 29523 : if (error_operand_p (expr))
3091 : {
3092 : /* The type of the statement-expression is the type of the last
3093 : expression. */
3094 3 : TREE_TYPE (stmt_expr) = error_mark_node;
3095 3 : return error_mark_node;
3096 : }
3097 :
3098 : /* If the last statement does not have "void" type, then the value
3099 : of the last statement is the value of the entire expression. */
3100 29520 : if (expr)
3101 : {
3102 29505 : tree type = TREE_TYPE (expr);
3103 :
3104 29505 : if (type && type_unknown_p (type))
3105 : {
3106 15 : error ("a statement expression is an insufficient context"
3107 : " for overload resolution");
3108 15 : TREE_TYPE (stmt_expr) = error_mark_node;
3109 15 : return error_mark_node;
3110 : }
3111 29490 : else if (processing_template_decl)
3112 : {
3113 : /* Not finish_expr_stmt because we don't want convert_to_void. */
3114 169 : expr = build_stmt (input_location, EXPR_STMT, expr);
3115 169 : expr = add_stmt (expr);
3116 : /* Mark the last statement so that we can recognize it as such at
3117 : template-instantiation time. */
3118 169 : EXPR_STMT_STMT_EXPR_RESULT (expr) = 1;
3119 : }
3120 29321 : else if (VOID_TYPE_P (type))
3121 : {
3122 : /* Just treat this like an ordinary statement. */
3123 31 : expr = finish_expr_stmt (expr);
3124 : }
3125 : else
3126 : {
3127 : /* It actually has a value we need to deal with. First, force it
3128 : to be an rvalue so that we won't need to build up a copy
3129 : constructor call later when we try to assign it to something. */
3130 29290 : expr = force_rvalue (expr, tf_warning_or_error);
3131 29290 : if (error_operand_p (expr))
3132 0 : return error_mark_node;
3133 :
3134 : /* Update for array-to-pointer decay. */
3135 29290 : type = TREE_TYPE (expr);
3136 :
3137 : /* This TARGET_EXPR will initialize the outer one added by
3138 : finish_stmt_expr. */
3139 29290 : set_target_expr_eliding (expr);
3140 :
3141 : /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a
3142 : normal statement, but don't convert to void or actually add
3143 : the EXPR_STMT. */
3144 29290 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
3145 29290 : expr = maybe_cleanup_point_expr (expr);
3146 29290 : add_stmt (expr);
3147 : }
3148 :
3149 : /* The type of the statement-expression is the type of the last
3150 : expression. */
3151 29490 : TREE_TYPE (stmt_expr) = type;
3152 : }
3153 :
3154 : return stmt_expr;
3155 : }
3156 :
3157 : /* Finish a statement-expression. EXPR should be the value returned
3158 : by the previous begin_stmt_expr. Returns an expression
3159 : representing the statement-expression. */
3160 :
3161 : tree
3162 7834494 : finish_stmt_expr (tree stmt_expr, bool has_no_scope)
3163 : {
3164 7834494 : tree type;
3165 7834494 : tree result;
3166 :
3167 7834494 : if (error_operand_p (stmt_expr))
3168 : {
3169 18 : pop_stmt_list (stmt_expr);
3170 18 : return error_mark_node;
3171 : }
3172 :
3173 7834476 : gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
3174 :
3175 7834476 : type = TREE_TYPE (stmt_expr);
3176 7834476 : result = pop_stmt_list (stmt_expr);
3177 7834476 : TREE_TYPE (result) = type;
3178 :
3179 7834476 : if (processing_template_decl)
3180 : {
3181 36252 : result = build_min (STMT_EXPR, type, result);
3182 36252 : TREE_SIDE_EFFECTS (result) = 1;
3183 36252 : STMT_EXPR_NO_SCOPE (result) = has_no_scope;
3184 : }
3185 7798224 : else if (CLASS_TYPE_P (type))
3186 : {
3187 : /* Wrap the statement-expression in a TARGET_EXPR so that the
3188 : temporary object created by the final expression is destroyed at
3189 : the end of the full-expression containing the
3190 : statement-expression. */
3191 118 : result = force_target_expr (type, result, tf_warning_or_error);
3192 : }
3193 :
3194 : return result;
3195 : }
3196 :
3197 : /* Returns the expression which provides the value of STMT_EXPR. */
3198 :
3199 : tree
3200 191 : stmt_expr_value_expr (tree stmt_expr)
3201 : {
3202 191 : tree t = STMT_EXPR_STMT (stmt_expr);
3203 :
3204 191 : if (TREE_CODE (t) == BIND_EXPR)
3205 191 : t = BIND_EXPR_BODY (t);
3206 :
3207 191 : if (TREE_CODE (t) == STATEMENT_LIST && STATEMENT_LIST_TAIL (t))
3208 158 : t = STATEMENT_LIST_TAIL (t)->stmt;
3209 :
3210 191 : if (TREE_CODE (t) == EXPR_STMT)
3211 173 : t = EXPR_STMT_EXPR (t);
3212 :
3213 191 : return t;
3214 : }
3215 :
3216 : /* Return TRUE iff EXPR_STMT is an empty list of
3217 : expression statements. */
3218 :
3219 : bool
3220 59125221 : empty_expr_stmt_p (tree expr_stmt)
3221 : {
3222 59125225 : tree body = NULL_TREE;
3223 :
3224 59125225 : if (expr_stmt == void_node)
3225 : return true;
3226 :
3227 59125222 : if (expr_stmt)
3228 : {
3229 59125222 : if (TREE_CODE (expr_stmt) == EXPR_STMT)
3230 4 : body = EXPR_STMT_EXPR (expr_stmt);
3231 59125218 : else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
3232 : body = expr_stmt;
3233 : }
3234 :
3235 4 : if (body)
3236 : {
3237 58232982 : if (TREE_CODE (body) == STATEMENT_LIST)
3238 58232978 : return tsi_end_p (tsi_start (body));
3239 : else
3240 : return empty_expr_stmt_p (body);
3241 : }
3242 : return false;
3243 : }
3244 :
3245 : /* Perform Koenig lookup. FN_EXPR is the postfix-expression representing
3246 : the function (or functions) to call; ARGS are the arguments to the
3247 : call. Returns the functions to be considered by overload resolution. */
3248 :
3249 : cp_expr
3250 19809789 : perform_koenig_lookup (cp_expr fn_expr, vec<tree, va_gc> *args,
3251 : tsubst_flags_t complain)
3252 : {
3253 19809789 : tree identifier = NULL_TREE;
3254 19809789 : tree functions = NULL_TREE;
3255 19809789 : tree tmpl_args = NULL_TREE;
3256 19809789 : bool template_id = false;
3257 19809789 : location_t loc = fn_expr.get_location ();
3258 19809789 : tree fn = fn_expr.get_value ();
3259 :
3260 19809789 : STRIP_ANY_LOCATION_WRAPPER (fn);
3261 :
3262 19809789 : if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
3263 : {
3264 : /* Use a separate flag to handle null args. */
3265 4125882 : template_id = true;
3266 4125882 : tmpl_args = TREE_OPERAND (fn, 1);
3267 4125882 : fn = TREE_OPERAND (fn, 0);
3268 : }
3269 :
3270 : /* Find the name of the overloaded function. */
3271 19809789 : if (identifier_p (fn))
3272 : identifier = fn;
3273 : else
3274 : {
3275 28589851 : functions = fn;
3276 19562274 : identifier = OVL_NAME (functions);
3277 : }
3278 :
3279 : /* A call to a namespace-scope function using an unqualified name.
3280 :
3281 : Do Koenig lookup -- unless any of the arguments are
3282 : type-dependent. */
3283 19809789 : if (!any_type_dependent_arguments_p (args)
3284 19809789 : && !any_dependent_template_arguments_p (tmpl_args))
3285 : {
3286 18920790 : fn = lookup_arg_dependent (identifier, functions, args);
3287 18920790 : if (!fn)
3288 : {
3289 : /* The unqualified name could not be resolved. */
3290 56643 : if (complain & tf_error)
3291 390 : fn = unqualified_fn_lookup_error (cp_expr (identifier, loc));
3292 : else
3293 : fn = identifier;
3294 : }
3295 : }
3296 :
3297 19809789 : if (fn && template_id && fn != error_mark_node)
3298 4125869 : fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
3299 :
3300 19809789 : return cp_expr (fn, loc);
3301 : }
3302 :
3303 : /* Generate an expression for `FN (ARGS)'. This may change the
3304 : contents of ARGS.
3305 :
3306 : If DISALLOW_VIRTUAL is true, the call to FN will be not generated
3307 : as a virtual call, even if FN is virtual. (This flag is set when
3308 : encountering an expression where the function name is explicitly
3309 : qualified. For example a call to `X::f' never generates a virtual
3310 : call.)
3311 :
3312 : Returns code for the call. */
3313 :
3314 : tree
3315 406717640 : finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
3316 : bool koenig_p, tsubst_flags_t complain)
3317 : {
3318 406717640 : tree result;
3319 406717640 : tree orig_fn;
3320 406717640 : vec<tree, va_gc> *orig_args = *args;
3321 406717640 : tsubst_flags_t orig_complain = complain;
3322 :
3323 406717640 : if (fn == error_mark_node)
3324 : return error_mark_node;
3325 :
3326 406716626 : complain &= ~tf_any_viable;
3327 406716626 : gcc_assert (!TYPE_P (fn));
3328 :
3329 : /* If FN may be a FUNCTION_DECL obfuscated by force_paren_expr, undo
3330 : it so that we can tell this is a call to a known function. */
3331 406716626 : fn = maybe_undo_parenthesized_ref (fn);
3332 :
3333 406716626 : STRIP_ANY_LOCATION_WRAPPER (fn);
3334 :
3335 406716626 : orig_fn = fn;
3336 :
3337 406716626 : if (concept_check_p (fn))
3338 : {
3339 6 : error_at (EXPR_LOC_OR_LOC (fn, input_location),
3340 : "cannot call a concept as a function");
3341 6 : return error_mark_node;
3342 : }
3343 :
3344 406716620 : if (processing_template_decl)
3345 : {
3346 : /* If FN is a local extern declaration (or set thereof) in a template,
3347 : look it up again at instantiation time. */
3348 225494021 : if (is_overloaded_fn (fn))
3349 : {
3350 138143015 : tree ifn = get_first_fn (fn);
3351 138143015 : if (TREE_CODE (ifn) == FUNCTION_DECL
3352 138143015 : && dependent_local_decl_p (ifn))
3353 38702 : orig_fn = DECL_NAME (ifn);
3354 : }
3355 :
3356 : /* If the call expression is dependent, build a CALL_EXPR node
3357 : with no type; type_dependent_expression_p recognizes
3358 : expressions with no type as being dependent. */
3359 225494021 : if (type_dependent_expression_p (fn)
3360 225494021 : || any_type_dependent_arguments_p (*args))
3361 : {
3362 204284154 : if (koenig_p
3363 10130579 : && TREE_CODE (orig_fn) == FUNCTION_DECL
3364 207415605 : && !fndecl_built_in_p (orig_fn))
3365 : /* For an ADL-enabled call where unqualified lookup found a
3366 : single non-template function, wrap it in an OVERLOAD so that
3367 : later substitution doesn't overeagerly mark the function as
3368 : used. */
3369 821069 : orig_fn = ovl_make (orig_fn, NULL_TREE);
3370 204284154 : result = build_min_nt_call_vec (orig_fn, *args);
3371 277495593 : SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
3372 204284154 : KOENIG_LOOKUP_P (result) = koenig_p;
3373 : /* Disable the std::move warnings since this call was dependent
3374 : (c++/89780, c++/107363). This also suppresses the
3375 : -Wredundant-move warning. */
3376 204284154 : suppress_warning (result, OPT_Wpessimizing_move);
3377 :
3378 204284154 : if (cfun && cp_function_chain && !cp_unevaluated_operand)
3379 : {
3380 178307781 : bool abnormal = true;
3381 178515550 : for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter)
3382 : {
3383 98641908 : tree fndecl = STRIP_TEMPLATE (*iter);
3384 98641908 : if (TREE_CODE (fndecl) != FUNCTION_DECL
3385 98641830 : || !TREE_THIS_VOLATILE (fndecl))
3386 : {
3387 : abnormal = false;
3388 : break;
3389 : }
3390 : }
3391 : /* FIXME: Stop warning about falling off end of non-void
3392 : function. But this is wrong. Even if we only see
3393 : no-return fns at this point, we could select a
3394 : future-defined return fn during instantiation. Or
3395 : vice-versa. */
3396 178307781 : if (abnormal)
3397 79873642 : current_function_returns_abnormally = 1;
3398 : }
3399 204284154 : if (TREE_CODE (fn) == COMPONENT_REF)
3400 95078606 : maybe_generic_this_capture (TREE_OPERAND (fn, 0),
3401 95078606 : TREE_OPERAND (fn, 1));
3402 204284154 : return result;
3403 : }
3404 21209867 : orig_args = make_tree_vector_copy (*args);
3405 : }
3406 :
3407 202432466 : if (TREE_CODE (fn) == COMPONENT_REF)
3408 : {
3409 42238112 : tree member = TREE_OPERAND (fn, 1);
3410 42238112 : if (BASELINK_P (member))
3411 : {
3412 42060916 : tree object = TREE_OPERAND (fn, 0);
3413 83681706 : return build_new_method_call (object, member,
3414 : args, NULL_TREE,
3415 : (disallow_virtual
3416 : ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL
3417 : : LOOKUP_NORMAL),
3418 : /*fn_p=*/NULL,
3419 42060916 : complain);
3420 : }
3421 : }
3422 :
3423 : /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */
3424 160371550 : if (TREE_CODE (fn) == ADDR_EXPR
3425 160371550 : && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
3426 9 : fn = TREE_OPERAND (fn, 0);
3427 :
3428 160371550 : if (is_overloaded_fn (fn))
3429 149108152 : fn = baselink_for_fns (fn);
3430 :
3431 160371550 : result = NULL_TREE;
3432 160371550 : if (BASELINK_P (fn))
3433 : {
3434 14714481 : tree object;
3435 :
3436 : /* A call to a member function. From [over.call.func]:
3437 :
3438 : If the keyword this is in scope and refers to the class of
3439 : that member function, or a derived class thereof, then the
3440 : function call is transformed into a qualified function call
3441 : using (*this) as the postfix-expression to the left of the
3442 : . operator.... [Otherwise] a contrived object of type T
3443 : becomes the implied object argument.
3444 :
3445 : In this situation:
3446 :
3447 : struct A { void f(); };
3448 : struct B : public A {};
3449 : struct C : public A { void g() { B::f(); }};
3450 :
3451 : "the class of that member function" refers to `A'. But 11.2
3452 : [class.access.base] says that we need to convert 'this' to B* as
3453 : part of the access, so we pass 'B' to maybe_dummy_object. */
3454 :
3455 14714481 : if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn)))
3456 : {
3457 : /* A constructor call always uses a dummy object. (This constructor
3458 : call which has the form A::A () is actually invalid and we are
3459 : going to reject it later in build_new_method_call.) */
3460 39 : object = build_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)));
3461 : }
3462 : else
3463 14714442 : object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
3464 : NULL);
3465 :
3466 16564362 : result = build_new_method_call (object, fn, args, NULL_TREE,
3467 : (disallow_virtual
3468 : ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
3469 : : LOOKUP_NORMAL),
3470 : /*fn_p=*/NULL,
3471 : complain);
3472 : }
3473 145657069 : else if (is_overloaded_fn (fn))
3474 : {
3475 : /* If the function is an overloaded builtin, resolve it. */
3476 134393671 : if (TREE_CODE (fn) == FUNCTION_DECL
3477 134393671 : && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3478 19294908 : || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
3479 10204705 : result = resolve_overloaded_builtin (input_location, fn, *args,
3480 : complain & tf_error);
3481 :
3482 10204705 : if (!result)
3483 : {
3484 134061870 : tree alloc_size_attr = NULL_TREE;
3485 134061870 : if (warn_calloc_transposed_args
3486 665121 : && TREE_CODE (fn) == FUNCTION_DECL
3487 134061870 : && (alloc_size_attr
3488 421914 : = lookup_attribute ("alloc_size",
3489 421914 : TYPE_ATTRIBUTES (TREE_TYPE (fn)))))
3490 3489 : if (TREE_VALUE (alloc_size_attr) == NULL_TREE
3491 3489 : || TREE_CHAIN (TREE_VALUE (alloc_size_attr)) == NULL_TREE)
3492 : alloc_size_attr = NULL_TREE;
3493 132389173 : if ((warn_sizeof_pointer_memaccess || alloc_size_attr)
3494 1672757 : && (complain & tf_warning)
3495 1478136 : && !vec_safe_is_empty (*args)
3496 135202256 : && !processing_template_decl)
3497 : {
3498 : location_t sizeof_arg_loc[6];
3499 : tree sizeof_arg[6];
3500 : unsigned int i;
3501 8188396 : for (i = 0; i < (alloc_size_attr ? 6 : 3); i++)
3502 : {
3503 3070851 : tree t;
3504 :
3505 3070851 : sizeof_arg_loc[i] = UNKNOWN_LOCATION;
3506 3070851 : sizeof_arg[i] = NULL_TREE;
3507 3070851 : if (i >= (*args)->length ())
3508 639190 : continue;
3509 2431661 : t = (**args)[i];
3510 2431661 : if (TREE_CODE (t) != SIZEOF_EXPR)
3511 2425086 : continue;
3512 6575 : if (SIZEOF_EXPR_TYPE_P (t))
3513 2601 : sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
3514 : else
3515 3974 : sizeof_arg[i] = TREE_OPERAND (t, 0);
3516 6575 : sizeof_arg_loc[i] = EXPR_LOCATION (t);
3517 : }
3518 1023557 : if (warn_sizeof_pointer_memaccess)
3519 : {
3520 1023497 : auto same_p = same_type_ignoring_top_level_qualifiers_p;
3521 1023497 : sizeof_pointer_memaccess_warning (sizeof_arg_loc, fn, *args,
3522 : sizeof_arg, same_p);
3523 : }
3524 1023557 : if (alloc_size_attr)
3525 60 : warn_for_calloc (sizeof_arg_loc, fn, *args, sizeof_arg,
3526 : alloc_size_attr);
3527 : }
3528 :
3529 134061870 : if ((complain & tf_warning)
3530 61030784 : && TREE_CODE (fn) == FUNCTION_DECL
3531 27810706 : && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
3532 198552 : && vec_safe_length (*args) == 3
3533 134260422 : && !any_type_dependent_arguments_p (*args))
3534 : {
3535 198552 : tree arg0 = (*orig_args)[0];
3536 198552 : tree arg1 = (*orig_args)[1];
3537 198552 : tree arg2 = (*orig_args)[2];
3538 198552 : int literal_mask = ((literal_integer_zerop (arg1) << 1)
3539 198552 : | (literal_integer_zerop (arg2) << 2));
3540 198552 : warn_for_memset (input_location, arg0, arg2, literal_mask);
3541 : }
3542 :
3543 : /* A call to a namespace-scope function. */
3544 134061870 : result = build_new_function_call (fn, args, orig_complain);
3545 : }
3546 : }
3547 11263398 : else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
3548 : {
3549 165566 : if (!vec_safe_is_empty (*args))
3550 0 : error ("arguments to destructor are not allowed");
3551 : /* C++20/DR: If the postfix-expression names a pseudo-destructor (in
3552 : which case the postfix-expression is a possibly-parenthesized class
3553 : member access), the function call destroys the object of scalar type
3554 : denoted by the object expression of the class member access. */
3555 165566 : tree ob = TREE_OPERAND (fn, 0);
3556 165566 : if (obvalue_p (ob))
3557 165548 : result = build_trivial_dtor_call (ob, true);
3558 : else
3559 : /* No location to clobber. */
3560 18 : result = convert_to_void (ob, ICV_STATEMENT, complain);
3561 : }
3562 11097832 : else if (CLASS_TYPE_P (TREE_TYPE (fn)))
3563 : /* If the "function" is really an object of class type, it might
3564 : have an overloaded `operator ()'. */
3565 4478683 : result = build_op_call (fn, args, complain);
3566 :
3567 153407082 : if (!result)
3568 : /* A call where the function is unknown. */
3569 6619149 : result = cp_build_function_call_vec (fn, args, complain);
3570 :
3571 160358032 : if (processing_template_decl && result != error_mark_node)
3572 : {
3573 15747125 : if (INDIRECT_REF_P (result))
3574 1137036 : result = TREE_OPERAND (result, 0);
3575 :
3576 : /* Prune all but the selected function from the original overload
3577 : set so that we can avoid some duplicate work at instantiation time. */
3578 15747125 : if (TREE_CODE (result) == CALL_EXPR
3579 15737798 : && really_overloaded_fn (orig_fn))
3580 : {
3581 5934778 : tree sel_fn = CALL_EXPR_FN (result);
3582 5934778 : if (TREE_CODE (sel_fn) == COMPONENT_REF)
3583 : {
3584 : /* The non-dependent result of build_new_method_call. */
3585 245890 : sel_fn = TREE_OPERAND (sel_fn, 1);
3586 245890 : gcc_assert (BASELINK_P (sel_fn));
3587 : }
3588 5688888 : else if (TREE_CODE (sel_fn) == ADDR_EXPR)
3589 : /* Our original callee wasn't wrapped in an ADDR_EXPR,
3590 : so strip this ADDR_EXPR added by build_over_call. */
3591 5688888 : sel_fn = TREE_OPERAND (sel_fn, 0);
3592 : orig_fn = sel_fn;
3593 : }
3594 :
3595 15747125 : tree r = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
3596 15747125 : SET_EXPR_LOCATION (r, input_location);
3597 15747125 : KOENIG_LOOKUP_P (r) = koenig_p;
3598 15747125 : TREE_NO_WARNING (r) = TREE_NO_WARNING (result);
3599 15747125 : release_tree_vector (orig_args);
3600 15747125 : result = convert_from_reference (r);
3601 : }
3602 :
3603 : return result;
3604 : }
3605 :
3606 : /* Finish a call to a postfix increment or decrement or EXPR. (Which
3607 : is indicated by CODE, which should be POSTINCREMENT_EXPR or
3608 : POSTDECREMENT_EXPR.) */
3609 :
3610 : cp_expr
3611 2545644 : finish_increment_expr (cp_expr expr, enum tree_code code)
3612 : {
3613 : /* input_location holds the location of the trailing operator token.
3614 : Build a location of the form:
3615 : expr++
3616 : ~~~~^~
3617 : with the caret at the operator token, ranging from the start
3618 : of EXPR to the end of the operator token. */
3619 2545644 : location_t combined_loc = make_location (input_location,
3620 : expr.get_start (),
3621 : get_finish (input_location));
3622 2545644 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3623 2545644 : NULL_TREE, tf_warning_or_error);
3624 : /* TODO: build_x_unary_op doesn't honor the location, so set it here. */
3625 2545644 : result.set_location (combined_loc);
3626 2545644 : return result;
3627 : }
3628 :
3629 : /* Finish a use of `this'. Returns an expression for `this'. */
3630 :
3631 : tree
3632 34838766 : finish_this_expr (void)
3633 : {
3634 34838766 : tree result = NULL_TREE;
3635 :
3636 69677418 : if (current_class_ref && !LAMBDA_TYPE_P (TREE_TYPE (current_class_ref)))
3637 34564256 : result = current_class_ptr;
3638 549004 : else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
3639 274436 : result = (lambda_expr_this_capture
3640 274436 : (CLASSTYPE_LAMBDA_EXPR (current_class_type), /*add*/true));
3641 : else
3642 74 : gcc_checking_assert (!current_class_ptr);
3643 :
3644 34838692 : if (result)
3645 : /* The keyword 'this' is a prvalue expression. */
3646 34838689 : return rvalue (result);
3647 :
3648 77 : tree fn = current_nonlambda_function ();
3649 77 : if (fn && DECL_XOBJ_MEMBER_FUNCTION_P (fn))
3650 : {
3651 4 : auto_diagnostic_group d;
3652 4 : error ("%<this%> is unavailable for explicit object member "
3653 : "functions");
3654 4 : tree xobj_parm = DECL_ARGUMENTS (fn);
3655 4 : gcc_assert (xobj_parm);
3656 4 : tree parm_name = DECL_NAME (xobj_parm);
3657 :
3658 4 : static tree remembered_fn = NULL_TREE;
3659 : /* Only output this diagnostic once per function. */
3660 4 : if (remembered_fn == fn)
3661 : /* Early escape. */;
3662 4 : else if (parm_name)
3663 4 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3664 : "use explicit object parameter %qs instead",
3665 2 : IDENTIFIER_POINTER (parm_name));
3666 : else
3667 2 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3668 : "name the explicit object parameter");
3669 :
3670 4 : remembered_fn = fn;
3671 4 : }
3672 73 : else if (fn && DECL_STATIC_FUNCTION_P (fn))
3673 3 : error ("%<this%> is unavailable for static member functions");
3674 70 : else if (fn && processing_contract_condition && DECL_CONSTRUCTOR_P (fn))
3675 0 : error ("invalid use of %<this%> in a constructor %<pre%> condition");
3676 70 : else if (fn && processing_contract_condition && DECL_DESTRUCTOR_P (fn))
3677 0 : error ("invalid use of %<this%> in a destructor %<post%> condition");
3678 70 : else if (fn)
3679 22 : error ("invalid use of %<this%> in non-member function");
3680 : else
3681 48 : error ("invalid use of %<this%> at top level");
3682 77 : return error_mark_node;
3683 : }
3684 :
3685 : /* Finish a pseudo-destructor expression. If SCOPE is NULL, the
3686 : expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
3687 : the TYPE for the type given. If SCOPE is non-NULL, the expression
3688 : was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
3689 :
3690 : tree
3691 165617 : finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
3692 : location_t loc, tsubst_flags_t complain)
3693 : {
3694 165617 : if (object == error_mark_node || destructor == error_mark_node)
3695 : return error_mark_node;
3696 :
3697 165608 : gcc_assert (TYPE_P (destructor));
3698 :
3699 165608 : if (!processing_template_decl)
3700 : {
3701 165587 : if (scope == error_mark_node)
3702 : {
3703 0 : if (complain & tf_error)
3704 0 : error_at (loc, "invalid qualifying scope in pseudo-destructor name");
3705 0 : return error_mark_node;
3706 : }
3707 165587 : if (is_auto (destructor))
3708 3 : destructor = TREE_TYPE (object);
3709 165587 : if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
3710 : {
3711 3 : if (complain & tf_error)
3712 3 : error_at (loc,
3713 : "qualified type %qT does not match destructor name ~%qT",
3714 : scope, destructor);
3715 3 : return error_mark_node;
3716 : }
3717 :
3718 :
3719 : /* [expr.pseudo] says both:
3720 :
3721 : The type designated by the pseudo-destructor-name shall be
3722 : the same as the object type.
3723 :
3724 : and:
3725 :
3726 : The cv-unqualified versions of the object type and of the
3727 : type designated by the pseudo-destructor-name shall be the
3728 : same type.
3729 :
3730 : We implement the more generous second sentence, since that is
3731 : what most other compilers do. */
3732 165584 : if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
3733 : destructor))
3734 : {
3735 12 : if (complain & tf_error)
3736 9 : error_at (loc, "%qE is not of type %qT", object, destructor);
3737 12 : return error_mark_node;
3738 : }
3739 : }
3740 :
3741 165593 : tree type = (type_dependent_expression_p (object)
3742 165593 : ? NULL_TREE : void_type_node);
3743 :
3744 165593 : return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
3745 165593 : scope, destructor);
3746 : }
3747 :
3748 : /* Finish an expression of the form CODE EXPR. */
3749 :
3750 : cp_expr
3751 36666134 : finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr,
3752 : tsubst_flags_t complain)
3753 : {
3754 : /* Build a location of the form:
3755 : ++expr
3756 : ^~~~~~
3757 : with the caret at the operator token, ranging from the start
3758 : of the operator token to the end of EXPR. */
3759 36666134 : location_t combined_loc = make_location (op_loc,
3760 : op_loc, expr.get_finish ());
3761 36666134 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3762 36666134 : NULL_TREE, complain);
3763 : /* TODO: build_x_unary_op doesn't always honor the location. */
3764 36666134 : result.set_location (combined_loc);
3765 :
3766 36666134 : if (result == error_mark_node)
3767 : return result;
3768 :
3769 36665670 : if (!(complain & tf_warning))
3770 : return result;
3771 :
3772 : /* These will never fold into a constant, so no need to check for
3773 : overflow for them. */
3774 36665670 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
3775 : return result;
3776 :
3777 19599442 : tree result_ovl = result;
3778 19599442 : tree expr_ovl = expr;
3779 :
3780 19599442 : if (!processing_template_decl)
3781 1748087 : expr_ovl = cp_fully_fold (expr_ovl);
3782 :
3783 19599442 : if (!CONSTANT_CLASS_P (expr_ovl)
3784 19599442 : || TREE_OVERFLOW_P (expr_ovl))
3785 : return result;
3786 :
3787 240980 : if (!processing_template_decl)
3788 231936 : result_ovl = cp_fully_fold (result_ovl);
3789 :
3790 240980 : if (CONSTANT_CLASS_P (result_ovl) && TREE_OVERFLOW_P (result_ovl))
3791 9 : overflow_warning (combined_loc, result_ovl);
3792 :
3793 : return result;
3794 : }
3795 :
3796 : /* Return true if CONSTRUCTOR EXPR after pack expansion could have no
3797 : elements. */
3798 :
3799 : static bool
3800 12 : maybe_zero_constructor_nelts (tree expr)
3801 : {
3802 12 : if (CONSTRUCTOR_NELTS (expr) == 0)
3803 : return true;
3804 12 : if (!processing_template_decl)
3805 : return false;
3806 30 : for (constructor_elt &elt : CONSTRUCTOR_ELTS (expr))
3807 21 : if (!PACK_EXPANSION_P (elt.value))
3808 : return false;
3809 : return true;
3810 : }
3811 :
3812 : /* Finish a compound-literal expression or C++11 functional cast with aggregate
3813 : initializer. TYPE is the type to which the CONSTRUCTOR in COMPOUND_LITERAL
3814 : is being cast. */
3815 :
3816 : tree
3817 10054853 : finish_compound_literal (tree type, tree compound_literal,
3818 : tsubst_flags_t complain,
3819 : fcl_t fcl_context)
3820 : {
3821 10054853 : if (type == error_mark_node)
3822 : return error_mark_node;
3823 :
3824 10054822 : if (TYPE_REF_P (type))
3825 : {
3826 12 : compound_literal
3827 12 : = finish_compound_literal (TREE_TYPE (type), compound_literal,
3828 : complain, fcl_context);
3829 : /* The prvalue is then used to direct-initialize the reference. */
3830 12 : tree r = (perform_implicit_conversion_flags
3831 12 : (type, compound_literal, complain, LOOKUP_NORMAL));
3832 12 : return convert_from_reference (r);
3833 : }
3834 :
3835 10054810 : if (!TYPE_OBJ_P (type))
3836 : {
3837 : /* DR2351 */
3838 60 : if (VOID_TYPE_P (type) && CONSTRUCTOR_NELTS (compound_literal) == 0)
3839 : {
3840 12 : if (!processing_template_decl)
3841 9 : return void_node;
3842 3 : TREE_TYPE (compound_literal) = type;
3843 3 : TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
3844 3 : CONSTRUCTOR_IS_DEPENDENT (compound_literal) = 0;
3845 3 : return compound_literal;
3846 : }
3847 21 : else if (VOID_TYPE_P (type)
3848 15 : && processing_template_decl
3849 33 : && maybe_zero_constructor_nelts (compound_literal))
3850 : /* If there are only packs in compound_literal, it could
3851 : be void{} after pack expansion. */;
3852 : else
3853 : {
3854 12 : if (complain & tf_error)
3855 9 : error ("compound literal of non-object type %qT", type);
3856 12 : return error_mark_node;
3857 : }
3858 : }
3859 :
3860 10054786 : if (template_placeholder_p (type))
3861 : {
3862 172196 : type = do_auto_deduction (type, compound_literal, type, complain,
3863 : adc_variable_type);
3864 172196 : if (type == error_mark_node)
3865 : return error_mark_node;
3866 : }
3867 : /* C++23 auto{x}. */
3868 9882590 : else if (is_auto (type)
3869 109 : && !AUTO_IS_DECLTYPE (type)
3870 9882697 : && CONSTRUCTOR_NELTS (compound_literal) == 1)
3871 : {
3872 101 : if (is_constrained_auto (type))
3873 : {
3874 2 : if (complain & tf_error)
3875 2 : error ("%<auto{x}%> cannot be constrained");
3876 2 : return error_mark_node;
3877 : }
3878 99 : else if (cxx_dialect < cxx23)
3879 : {
3880 1 : if ((complain & tf_warning_or_error) == 0)
3881 0 : return error_mark_node;
3882 1 : pedwarn (input_location, OPT_Wc__23_extensions,
3883 : "%<auto{x}%> only available with "
3884 : "%<-std=c++23%> or %<-std=gnu++23%>");
3885 : }
3886 99 : type = do_auto_deduction (type, compound_literal, type, complain,
3887 : adc_variable_type);
3888 99 : if (type == error_mark_node)
3889 : return error_mark_node;
3890 : }
3891 :
3892 : /* Used to hold a copy of the compound literal in a template. */
3893 10054668 : tree orig_cl = NULL_TREE;
3894 :
3895 10054668 : if (processing_template_decl)
3896 : {
3897 4812375 : const bool dependent_p
3898 4812375 : = (instantiation_dependent_expression_p (compound_literal)
3899 4812375 : || dependent_type_p (type));
3900 1589376 : if (dependent_p)
3901 : /* We're about to return, no need to copy. */
3902 : orig_cl = compound_literal;
3903 : else
3904 : /* We're going to need a copy. */
3905 1589376 : orig_cl = unshare_constructor (compound_literal);
3906 4812375 : TREE_TYPE (orig_cl) = type;
3907 : /* Mark the expression as a compound literal. */
3908 4812375 : TREE_HAS_CONSTRUCTOR (orig_cl) = 1;
3909 : /* And as instantiation-dependent. */
3910 4812375 : CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p;
3911 4812375 : if (fcl_context == fcl_c99)
3912 130 : CONSTRUCTOR_C99_COMPOUND_LITERAL (orig_cl) = 1;
3913 : /* If the compound literal is dependent, we're done for now. */
3914 4812375 : if (dependent_p)
3915 : return orig_cl;
3916 : /* Otherwise, do go on to e.g. check narrowing. */
3917 : }
3918 :
3919 6831669 : type = complete_type (type);
3920 :
3921 6831669 : if (TYPE_NON_AGGREGATE_CLASS (type))
3922 : {
3923 : /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST
3924 : everywhere that deals with function arguments would be a pain, so
3925 : just wrap it in a TREE_LIST. The parser set a flag so we know
3926 : that it came from T{} rather than T({}). */
3927 1084224 : CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
3928 1084224 : compound_literal = build_tree_list (NULL_TREE, compound_literal);
3929 1084224 : return build_functional_cast (input_location, type,
3930 1084224 : compound_literal, complain);
3931 : }
3932 :
3933 5747445 : if (TREE_CODE (type) == ARRAY_TYPE
3934 5747445 : && check_array_initializer (NULL_TREE, type, compound_literal))
3935 9 : return error_mark_node;
3936 5747436 : compound_literal = reshape_init (type, compound_literal, complain);
3937 5431949 : if (SCALAR_TYPE_P (type)
3938 843321 : && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
3939 5955029 : && !check_narrowing (type, compound_literal, complain))
3940 102 : return error_mark_node;
3941 5747334 : if (TREE_CODE (type) == ARRAY_TYPE
3942 5747334 : && TYPE_DOMAIN (type) == NULL_TREE)
3943 : {
3944 1192 : cp_complete_array_type_or_error (&type, compound_literal,
3945 : false, complain);
3946 1192 : if (type == error_mark_node)
3947 : return error_mark_node;
3948 : }
3949 5747331 : compound_literal = digest_init_flags (type, compound_literal,
3950 : LOOKUP_NORMAL | LOOKUP_NO_NARROWING,
3951 : complain);
3952 5747331 : if (compound_literal == error_mark_node)
3953 : return error_mark_node;
3954 :
3955 : /* If we're in a template, return the original compound literal. */
3956 5746747 : if (orig_cl)
3957 : return orig_cl;
3958 :
3959 4247069 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
3960 : {
3961 3456183 : TREE_HAS_CONSTRUCTOR (compound_literal) = true;
3962 3456183 : if (fcl_context == fcl_c99)
3963 37983 : CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1;
3964 : }
3965 :
3966 : /* Put static/constant array temporaries in static variables. */
3967 : /* FIXME all C99 compound literals should be variables rather than C++
3968 : temporaries, unless they are used as an aggregate initializer. */
3969 5777698 : if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
3970 2721535 : && fcl_context == fcl_c99
3971 80 : && TREE_CODE (type) == ARRAY_TYPE
3972 28 : && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
3973 4247097 : && initializer_constant_valid_p (compound_literal, type))
3974 : {
3975 28 : tree decl = create_temporary_var (type);
3976 28 : DECL_CONTEXT (decl) = NULL_TREE;
3977 28 : DECL_INITIAL (decl) = compound_literal;
3978 28 : TREE_STATIC (decl) = 1;
3979 28 : if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
3980 : {
3981 : /* 5.19 says that a constant expression can include an
3982 : lvalue-rvalue conversion applied to "a glvalue of literal type
3983 : that refers to a non-volatile temporary object initialized
3984 : with a constant expression". Rather than try to communicate
3985 : that this VAR_DECL is a temporary, just mark it constexpr. */
3986 24 : DECL_DECLARED_CONSTEXPR_P (decl) = true;
3987 24 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
3988 24 : TREE_CONSTANT (decl) = true;
3989 : }
3990 28 : cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
3991 28 : decl = pushdecl_top_level (decl);
3992 28 : DECL_NAME (decl) = make_anon_name ();
3993 28 : SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
3994 : /* Make sure the destructor is callable. */
3995 28 : tree clean = cxx_maybe_build_cleanup (decl, complain);
3996 28 : if (clean == error_mark_node)
3997 : return error_mark_node;
3998 28 : return decl;
3999 : }
4000 :
4001 : /* Represent other compound literals with TARGET_EXPR so we produce
4002 : a prvalue, and can elide copies. */
4003 4247041 : if (!VECTOR_TYPE_P (type)
4004 4210117 : && (TREE_CODE (compound_literal) == CONSTRUCTOR
4005 790880 : || TREE_CODE (compound_literal) == VEC_INIT_EXPR))
4006 : {
4007 : /* The CONSTRUCTOR is now an initializer, not a compound literal. */
4008 3419237 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
4009 3419237 : TREE_HAS_CONSTRUCTOR (compound_literal) = false;
4010 3419237 : compound_literal = get_target_expr (compound_literal, complain);
4011 : }
4012 : else
4013 : /* For e.g. int{42} just make sure it's a prvalue. */
4014 827804 : compound_literal = rvalue (compound_literal);
4015 :
4016 : return compound_literal;
4017 : }
4018 :
4019 : /* Return the declaration for the function-name variable indicated by
4020 : ID. */
4021 :
4022 : tree
4023 224677 : finish_fname (tree id)
4024 : {
4025 224677 : tree decl = fname_decl (input_location, C_RID_CODE (id), id);
4026 : /* [expr.prim.lambda.closure]/16 "Unless the compound-statement is that
4027 : of a consteval-block-declaration, a variable __func__ is implicitly
4028 : defined...". We could be in a consteval block in a function, though,
4029 : and then we shouldn't warn. */
4030 224677 : if (current_function_decl
4031 224677 : && !current_nonlambda_function (/*only_skip_consteval_block_p=*/true))
4032 4 : pedwarn (input_location, 0, "%qD is not defined outside of function scope",
4033 : decl);
4034 224677 : if (processing_template_decl && current_function_decl
4035 154827 : && decl != error_mark_node)
4036 154827 : decl = DECL_NAME (decl);
4037 224677 : return decl;
4038 : }
4039 :
4040 : /* Finish a translation unit. */
4041 :
4042 : void
4043 95897 : finish_translation_unit (void)
4044 : {
4045 : /* In case there were missing closebraces,
4046 : get us back to the global binding level. */
4047 95897 : pop_everything ();
4048 191794 : while (current_namespace != global_namespace)
4049 0 : pop_namespace ();
4050 :
4051 : /* Do file scope __FUNCTION__ et al. */
4052 95897 : finish_fname_decls ();
4053 :
4054 95897 : if (vec_safe_length (scope_chain->omp_declare_target_attribute))
4055 : {
4056 12 : cp_omp_declare_target_attr
4057 12 : a = scope_chain->omp_declare_target_attribute->pop ();
4058 12 : if (!errorcount)
4059 9 : error ("%qs without corresponding %qs",
4060 : a.device_type >= 0 ? "#pragma omp begin declare target"
4061 : : "#pragma omp declare target",
4062 : "#pragma omp end declare target");
4063 24 : vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0);
4064 : }
4065 95897 : if (vec_safe_length (scope_chain->omp_declare_variant_attribute))
4066 : {
4067 0 : if (!errorcount)
4068 0 : error ("%<omp begin declare variant%> without corresponding "
4069 : "%<omp end declare variant%>");
4070 0 : vec_safe_truncate (scope_chain->omp_declare_variant_attribute, 0);
4071 : }
4072 95897 : if (vec_safe_length (scope_chain->omp_begin_assumes))
4073 : {
4074 3 : if (!errorcount)
4075 3 : error ("%qs without corresponding %qs",
4076 : "#pragma omp begin assumes", "#pragma omp end assumes");
4077 3 : vec_safe_truncate (scope_chain->omp_begin_assumes, 0);
4078 : }
4079 95897 : }
4080 :
4081 : /* Finish a template type parameter, specified as AGGR IDENTIFIER.
4082 : Returns the parameter. */
4083 :
4084 : tree
4085 153480796 : finish_template_type_parm (tree aggr, tree identifier)
4086 : {
4087 153480796 : if (aggr != class_type_node)
4088 : {
4089 0 : permerror (input_location, "template type parameters must use the keyword %<class%> or %<typename%>");
4090 0 : aggr = class_type_node;
4091 : }
4092 :
4093 153480796 : return build_tree_list (aggr, identifier);
4094 : }
4095 :
4096 : /* Finish a template template parameter, specified as AGGR IDENTIFIER.
4097 : Returns the parameter. */
4098 :
4099 : tree
4100 382441 : finish_template_template_parm (tree aggr, tree identifier)
4101 : {
4102 382441 : tree decl = build_decl (input_location,
4103 : TYPE_DECL, identifier, NULL_TREE);
4104 :
4105 382441 : tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
4106 382441 : DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
4107 382441 : DECL_TEMPLATE_RESULT (tmpl) = decl;
4108 382441 : DECL_ARTIFICIAL (decl) = 1;
4109 :
4110 : /* Associate the constraints with the underlying declaration,
4111 : not the template. */
4112 382441 : tree constr = current_template_constraints ();
4113 382441 : set_constraints (decl, constr);
4114 :
4115 382441 : end_template_decl ();
4116 :
4117 382441 : gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
4118 :
4119 382441 : check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
4120 : /*is_primary=*/true, /*is_partial=*/false,
4121 : /*is_friend=*/0);
4122 :
4123 382441 : return finish_template_type_parm (aggr, tmpl);
4124 : }
4125 :
4126 : /* ARGUMENT is the default-argument value for a template template
4127 : parameter. If ARGUMENT is invalid, issue error messages and return
4128 : the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
4129 :
4130 : tree
4131 905 : check_template_template_default_arg (tree argument)
4132 : {
4133 905 : if (TREE_CODE (argument) != TEMPLATE_DECL
4134 : && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
4135 : && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
4136 : {
4137 : if (TREE_CODE (argument) == TYPE_DECL)
4138 : {
4139 18 : if (tree t = maybe_get_template_decl_from_type_decl (argument))
4140 18 : if (TREE_CODE (t) == TEMPLATE_DECL)
4141 : return t;
4142 15 : error ("invalid use of type %qT as a default value for a template "
4143 15 : "template-parameter", TREE_TYPE (argument));
4144 : }
4145 : else
4146 0 : error ("invalid default argument for a template template parameter");
4147 15 : return error_mark_node;
4148 : }
4149 :
4150 : return argument;
4151 : }
4152 :
4153 : /* Begin a class definition, as indicated by T. */
4154 :
4155 : tree
4156 29656487 : begin_class_definition (tree t)
4157 : {
4158 29656487 : if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
4159 33 : return error_mark_node;
4160 :
4161 29656576 : if (processing_template_parmlist && !LAMBDA_TYPE_P (t))
4162 : {
4163 9 : error ("definition of %q#T inside template parameter list", t);
4164 9 : return error_mark_node;
4165 : }
4166 :
4167 : /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
4168 : are passed the same as decimal scalar types. */
4169 29656445 : if (TREE_CODE (t) == RECORD_TYPE
4170 29159852 : && !processing_template_decl)
4171 : {
4172 10628364 : tree ns = TYPE_CONTEXT (t);
4173 10628362 : if (ns && TREE_CODE (ns) == NAMESPACE_DECL
4174 8514025 : && DECL_CONTEXT (ns) == std_node
4175 2077506 : && DECL_NAME (ns)
4176 12705850 : && id_equal (DECL_NAME (ns), "decimal"))
4177 : {
4178 150 : const char *n = TYPE_NAME_STRING (t);
4179 150 : if ((strcmp (n, "decimal32") == 0)
4180 101 : || (strcmp (n, "decimal64") == 0)
4181 46 : || (strcmp (n, "decimal128") == 0))
4182 147 : TYPE_TRANSPARENT_AGGR (t) = 1;
4183 : }
4184 : }
4185 :
4186 : /* A non-implicit typename comes from code like:
4187 :
4188 : template <typename T> struct A {
4189 : template <typename U> struct A<T>::B ...
4190 :
4191 : This is erroneous. */
4192 19028081 : else if (TREE_CODE (t) == TYPENAME_TYPE)
4193 : {
4194 0 : error ("invalid definition of qualified type %qT", t);
4195 0 : t = error_mark_node;
4196 : }
4197 :
4198 29656445 : if (t == error_mark_node || ! MAYBE_CLASS_TYPE_P (t))
4199 : {
4200 0 : t = make_class_type (RECORD_TYPE);
4201 0 : pushtag (make_anon_name (), t);
4202 : }
4203 :
4204 29656445 : if (TYPE_BEING_DEFINED (t))
4205 : {
4206 0 : t = make_class_type (TREE_CODE (t));
4207 0 : pushtag (TYPE_IDENTIFIER (t), t);
4208 : }
4209 :
4210 29656445 : if (modules_p ())
4211 : {
4212 108432 : if (!module_may_redeclare (TYPE_NAME (t)))
4213 0 : return error_mark_node;
4214 108432 : set_instantiating_module (TYPE_NAME (t));
4215 108432 : set_defining_module (TYPE_NAME (t));
4216 : }
4217 :
4218 29656445 : maybe_process_partial_specialization (t);
4219 29656445 : pushclass (t);
4220 29656445 : TYPE_BEING_DEFINED (t) = 1;
4221 29656445 : class_binding_level->defining_class_p = 1;
4222 :
4223 29656445 : if (flag_pack_struct)
4224 : {
4225 99 : tree v;
4226 99 : TYPE_PACKED (t) = 1;
4227 : /* Even though the type is being defined for the first time
4228 : here, there might have been a forward declaration, so there
4229 : might be cv-qualified variants of T. */
4230 99 : for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
4231 0 : TYPE_PACKED (v) = 1;
4232 : }
4233 : /* Reset the interface data, at the earliest possible
4234 : moment, as it might have been set via a class foo;
4235 : before. */
4236 61801894 : if (! TYPE_UNNAMED_P (t))
4237 : {
4238 28941353 : struct c_fileinfo *finfo = \
4239 28941353 : get_fileinfo (LOCATION_FILE (input_location));
4240 28941353 : CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
4241 28941353 : SET_CLASSTYPE_INTERFACE_UNKNOWN_X
4242 : (t, finfo->interface_unknown);
4243 : }
4244 29656445 : reset_specialization ();
4245 :
4246 : /* Make a declaration for this class in its own scope. */
4247 29656445 : build_self_reference ();
4248 :
4249 29656445 : return t;
4250 : }
4251 :
4252 : /* Finish the member declaration given by DECL. */
4253 :
4254 : void
4255 418620853 : finish_member_declaration (tree decl)
4256 : {
4257 418620853 : if (decl == error_mark_node || decl == NULL_TREE)
4258 : return;
4259 :
4260 418619856 : if (decl == void_type_node)
4261 : /* The COMPONENT was a friend, not a member, and so there's
4262 : nothing for us to do. */
4263 : return;
4264 :
4265 : /* We should see only one DECL at a time. */
4266 418619856 : gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
4267 :
4268 : /* Don't add decls after definition. */
4269 418619877 : gcc_assert (TYPE_BEING_DEFINED (current_class_type)
4270 : /* We can add lambda types when late parsing default
4271 : arguments. */
4272 : || LAMBDA_TYPE_P (TREE_TYPE (decl)));
4273 :
4274 : /* Set up access control for DECL. */
4275 418619856 : TREE_PRIVATE (decl)
4276 418619856 : = (current_access_specifier == access_private_node);
4277 418619856 : TREE_PROTECTED (decl)
4278 418619856 : = (current_access_specifier == access_protected_node);
4279 418619856 : if (TREE_CODE (decl) == TEMPLATE_DECL)
4280 : {
4281 46723791 : TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
4282 46723791 : TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
4283 : }
4284 :
4285 : /* Mark the DECL as a member of the current class, unless it's
4286 : a member of an enumeration. */
4287 418619856 : if (TREE_CODE (decl) != CONST_DECL)
4288 416357231 : DECL_CONTEXT (decl) = current_class_type;
4289 :
4290 : /* Remember the single FIELD_DECL an anonymous aggregate type is used for. */
4291 418619856 : if (TREE_CODE (decl) == FIELD_DECL
4292 418619856 : && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
4293 : {
4294 268631 : gcc_assert (!ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))));
4295 268631 : ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = decl;
4296 : }
4297 :
4298 418619856 : if (TREE_CODE (decl) == USING_DECL)
4299 : /* Avoid debug info for class-scope USING_DECLS for now, we'll
4300 : call cp_emit_debug_info_for_using later. */
4301 3109201 : DECL_IGNORED_P (decl) = 1;
4302 :
4303 : /* Check for bare parameter packs in the non-static data member
4304 : declaration. */
4305 418619856 : if (TREE_CODE (decl) == FIELD_DECL)
4306 : {
4307 31449982 : if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
4308 9 : TREE_TYPE (decl) = error_mark_node;
4309 31449982 : if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
4310 0 : DECL_ATTRIBUTES (decl) = NULL_TREE;
4311 : }
4312 :
4313 : /* [dcl.link]
4314 :
4315 : A C language linkage is ignored for the names of class members
4316 : and the member function type of class member functions. */
4317 418619856 : if (DECL_LANG_SPECIFIC (decl))
4318 381703304 : SET_DECL_LANGUAGE (decl, lang_cplusplus);
4319 :
4320 418619856 : bool add = false;
4321 :
4322 : /* Functions and non-functions are added differently. */
4323 418619856 : if (DECL_DECLARES_FUNCTION_P (decl))
4324 213015644 : add = add_method (current_class_type, decl, false);
4325 : /* Enter the DECL into the scope of the class, if the class
4326 : isn't a closure (whose fields are supposed to be unnamed). */
4327 205604212 : else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
4328 200996058 : || maybe_push_used_methods (decl)
4329 404841232 : || pushdecl_class_level (decl))
4330 : add = true;
4331 :
4332 213015644 : if (add)
4333 : {
4334 : /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
4335 : go at the beginning. The reason is that
4336 : legacy_nonfn_member_lookup searches the list in order, and we
4337 : want a field name to override a type name so that the "struct
4338 : stat hack" will work. In particular:
4339 :
4340 : struct S { enum E { }; static const int E = 5; int ary[S::E]; } s;
4341 :
4342 : is valid. */
4343 :
4344 418611259 : if (TREE_CODE (decl) == TYPE_DECL)
4345 147207117 : TYPE_FIELDS (current_class_type)
4346 294414234 : = chainon (TYPE_FIELDS (current_class_type), decl);
4347 : else
4348 : {
4349 271404142 : DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
4350 271404142 : TYPE_FIELDS (current_class_type) = decl;
4351 : }
4352 :
4353 418611259 : maybe_add_class_template_decl_list (current_class_type, decl,
4354 : /*friend_p=*/0);
4355 : }
4356 : }
4357 :
4358 : /* Finish processing a complete template declaration. The PARMS are
4359 : the template parameters. */
4360 :
4361 : void
4362 87779590 : finish_template_decl (tree parms)
4363 : {
4364 87779590 : if (parms)
4365 87779581 : end_template_decl ();
4366 : else
4367 9 : end_specialization ();
4368 87779590 : }
4369 :
4370 : // Returns the template type of the class scope being entered. If we're
4371 : // entering a constrained class scope. TYPE is the class template
4372 : // scope being entered and we may need to match the intended type with
4373 : // a constrained specialization. For example:
4374 : //
4375 : // template<Object T>
4376 : // struct S { void f(); }; #1
4377 : //
4378 : // template<Object T>
4379 : // void S<T>::f() { } #2
4380 : //
4381 : // We check, in #2, that S<T> refers precisely to the type declared by
4382 : // #1 (i.e., that the constraints match). Note that the following should
4383 : // be an error since there is no specialization of S<T> that is
4384 : // unconstrained, but this is not diagnosed here.
4385 : //
4386 : // template<typename T>
4387 : // void S<T>::f() { }
4388 : //
4389 : // We cannot diagnose this problem here since this function also matches
4390 : // qualified template names that are not part of a definition. For example:
4391 : //
4392 : // template<Integral T, Floating_point U>
4393 : // typename pair<T, U>::first_type void f(T, U);
4394 : //
4395 : // Here, it is unlikely that there is a partial specialization of
4396 : // pair constrained for Integral and Floating_point arguments.
4397 : //
4398 : // The general rule is: if a constrained specialization with matching
4399 : // constraints is found return that type. Also note that if TYPE is not a
4400 : // class-type (e.g. a typename type), then no fixup is needed.
4401 :
4402 : static tree
4403 17366643 : fixup_template_type (tree type)
4404 : {
4405 : // Find the template parameter list at the a depth appropriate to
4406 : // the scope we're trying to enter.
4407 17366643 : tree parms = current_template_parms;
4408 17366643 : int depth = template_class_depth (type);
4409 38712165 : for (int n = current_template_depth; n > depth && parms; --n)
4410 3978879 : parms = TREE_CHAIN (parms);
4411 17366643 : if (!parms)
4412 : return type;
4413 17366633 : tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms);
4414 17366633 : tree cur_constr = build_constraints (cur_reqs, NULL_TREE);
4415 :
4416 : // Search for a specialization whose type and constraints match.
4417 17366633 : tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
4418 17366633 : tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
4419 33789686 : while (specs)
4420 : {
4421 16830062 : tree spec_constr = get_constraints (TREE_VALUE (specs));
4422 :
4423 : // If the type and constraints match a specialization, then we
4424 : // are entering that type.
4425 16830062 : if (same_type_p (type, TREE_TYPE (specs))
4426 16830062 : && equivalent_constraints (cur_constr, spec_constr))
4427 407009 : return TREE_TYPE (specs);
4428 16423053 : specs = TREE_CHAIN (specs);
4429 : }
4430 :
4431 : // If no specialization matches, then must return the type
4432 : // previously found.
4433 : return type;
4434 : }
4435 :
4436 : /* Finish processing a template-id (which names a type) of the form
4437 : NAME < ARGS >. Return the TYPE_DECL for the type named by the
4438 : template-id. If ENTERING_SCOPE is nonzero we are about to enter
4439 : the scope of template-id indicated. */
4440 :
4441 : tree
4442 178935404 : finish_template_type (tree name, tree args, int entering_scope)
4443 : {
4444 178935404 : tree type;
4445 :
4446 178935404 : type = lookup_template_class (name, args,
4447 : NULL_TREE, NULL_TREE,
4448 : tf_warning_or_error | tf_user);
4449 178935401 : if (entering_scope)
4450 18366005 : type = adjust_type_for_entering_scope (type);
4451 :
4452 : /* If we might be entering the scope of a partial specialization,
4453 : find the one with the right constraints. */
4454 178935401 : if (flag_concepts
4455 176273161 : && entering_scope
4456 18009165 : && CLASS_TYPE_P (type)
4457 17852348 : && CLASSTYPE_TEMPLATE_INFO (type)
4458 17852339 : && dependent_type_p (type)
4459 196302044 : && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
4460 17366643 : type = fixup_template_type (type);
4461 :
4462 178935401 : if (type == error_mark_node)
4463 : return type;
4464 178933141 : else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
4465 141825666 : return TYPE_STUB_DECL (type);
4466 : else
4467 37107475 : return TYPE_NAME (type);
4468 : }
4469 :
4470 : /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER
4471 : and ANNOTATIONS.
4472 : Return a TREE_LIST containing the ACCESS_SPECIFIER (or if there are
4473 : ANNOTATIONS, TREE_LIST containing the ACCESS_SPECIFIER and ANNOTATIONS)
4474 : and the BASE_CLASS, or NULL_TREE if an error occurred. The
4475 : ACCESS_SPECIFIER is one of
4476 : access_{default,public,protected,private}_node. For a virtual base
4477 : we set TREE_TYPE. */
4478 :
4479 : tree
4480 10911675 : finish_base_specifier (tree base, tree access, bool virtual_p,
4481 : tree annotations)
4482 : {
4483 10911675 : tree result;
4484 :
4485 10911675 : if (base == error_mark_node)
4486 : {
4487 0 : error ("invalid base-class specification");
4488 0 : result = NULL_TREE;
4489 : }
4490 10911675 : else if (! MAYBE_CLASS_TYPE_P (base))
4491 : {
4492 3 : error ("%qT is not a class type", base);
4493 3 : result = NULL_TREE;
4494 : }
4495 : else
4496 : {
4497 10911672 : if (cp_type_quals (base) != 0)
4498 : {
4499 : /* DR 484: Can a base-specifier name a cv-qualified
4500 : class type? */
4501 12 : base = TYPE_MAIN_VARIANT (base);
4502 : }
4503 10911672 : if (annotations)
4504 9 : access = build_tree_list (access, nreverse (annotations));
4505 10911672 : result = build_tree_list (access, base);
4506 10911672 : if (virtual_p)
4507 25169 : TREE_TYPE (result) = integer_type_node;
4508 : }
4509 :
4510 10911675 : return result;
4511 : }
4512 :
4513 : /* If FNS is a member function, a set of member functions, or a
4514 : template-id referring to one or more member functions, return a
4515 : BASELINK for FNS, incorporating the current access context.
4516 : Otherwise, return FNS unchanged. */
4517 :
4518 : tree
4519 233352181 : baselink_for_fns (tree fns)
4520 : {
4521 233352181 : tree scope;
4522 233352181 : tree cl;
4523 :
4524 233352181 : if (BASELINK_P (fns)
4525 233352181 : || error_operand_p (fns))
4526 : return fns;
4527 :
4528 218752452 : scope = ovl_scope (fns);
4529 218752452 : if (!CLASS_TYPE_P (scope))
4530 : return fns;
4531 :
4532 8237775 : cl = currently_open_derived_class (scope);
4533 8237775 : if (!cl)
4534 5999083 : cl = scope;
4535 8237775 : tree access_path = TYPE_BINFO (cl);
4536 8237775 : tree conv_path = (cl == scope ? access_path
4537 666321 : : lookup_base (cl, scope, ba_any, NULL, tf_none));
4538 8237775 : return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE);
4539 : }
4540 :
4541 : /* Returns true iff we are currently parsing a lambda-declarator. */
4542 :
4543 : bool
4544 2222238048 : parsing_lambda_declarator ()
4545 : {
4546 2222238048 : cp_binding_level *b = current_binding_level;
4547 2224111777 : while (b->kind == sk_template_parms || b->kind == sk_function_parms)
4548 1873729 : b = b->level_chain;
4549 2222238048 : return b->kind == sk_lambda;
4550 : }
4551 :
4552 : /* Returns true iff DECL is a variable from a function outside
4553 : the current one. */
4554 :
4555 : static bool
4556 2929213227 : outer_var_p (tree decl)
4557 : {
4558 : /* These should have been stripped or otherwise handled by the caller. */
4559 2929213227 : gcc_checking_assert (!REFERENCE_REF_P (decl));
4560 :
4561 1861276742 : return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
4562 2724065544 : && DECL_FUNCTION_SCOPE_P (decl)
4563 : /* Don't get confused by temporaries. */
4564 2255762381 : && DECL_NAME (decl)
4565 5160832459 : && (DECL_CONTEXT (decl) != current_function_decl
4566 2220337182 : || parsing_nsdmi ()
4567 : /* Also consider captures as outer vars if we are in
4568 : decltype in a lambda declarator as in:
4569 : auto l = [j=0]() -> decltype((j)) { ... }
4570 : for the sake of finish_decltype_type.
4571 :
4572 : (Similar issue also affects non-lambdas, but vexing parse
4573 : makes it more difficult to handle than lambdas.) */
4574 2220336239 : || parsing_lambda_declarator ()));
4575 : }
4576 :
4577 : /* As above, but also checks that DECL is automatic. */
4578 :
4579 : bool
4580 2929213227 : outer_automatic_var_p (tree decl)
4581 : {
4582 2929213227 : return (outer_var_p (decl)
4583 2929213227 : && !TREE_STATIC (decl));
4584 : }
4585 :
4586 : /* DECL satisfies outer_automatic_var_p. Possibly complain about it or
4587 : rewrite it for lambda capture.
4588 :
4589 : If ODR_USE is true, we're being called from mark_use, and we complain about
4590 : use of constant variables. If ODR_USE is false, we're being called for the
4591 : id-expression, and we do lambda capture. */
4592 :
4593 : tree
4594 5395024 : process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
4595 : {
4596 5395024 : if (cp_unevaluated_operand)
4597 : {
4598 3493049 : tree type = TREE_TYPE (decl);
4599 3493049 : if (!dependent_type_p (type)
4600 3493049 : && variably_modified_type_p (type, NULL_TREE))
4601 : /* VLAs are used even in unevaluated context. */;
4602 : else
4603 : /* It's not a use (3.2) if we're in an unevaluated context. */
4604 3493043 : return decl;
4605 : }
4606 1901981 : if (decl == error_mark_node)
4607 : return decl;
4608 :
4609 1901981 : tree context = DECL_CONTEXT (decl);
4610 1901981 : tree containing_function = current_function_decl;
4611 1901981 : tree lambda_stack = NULL_TREE;
4612 1901981 : tree lambda_expr = NULL_TREE;
4613 1901981 : tree initializer = convert_from_reference (decl);
4614 1901981 : tree var = strip_normal_capture_proxy (decl);
4615 :
4616 : /* Mark it as used now even if the use is ill-formed. */
4617 1901981 : if (!mark_used (decl, complain))
4618 3 : return error_mark_node;
4619 :
4620 1901978 : if (parsing_nsdmi () || parsing_lambda_declarator ())
4621 : containing_function = NULL_TREE;
4622 :
4623 3803259 : if (containing_function && LAMBDA_FUNCTION_P (containing_function))
4624 : {
4625 : /* Check whether we've already built a proxy. */
4626 1901542 : tree d = retrieve_local_specialization (var);
4627 :
4628 1901542 : if (d && d != decl && is_capture_proxy (d))
4629 : {
4630 976629 : if (DECL_CONTEXT (d) == containing_function)
4631 : /* We already have an inner proxy. */
4632 : return d;
4633 : else
4634 : /* We need to capture an outer proxy. */
4635 2269 : return process_outer_var_ref (d, complain, odr_use);
4636 : }
4637 : }
4638 :
4639 : /* If we are in a lambda function, we can move out until we hit
4640 : 1. the context,
4641 : 2. a non-lambda function, or
4642 : 3. a non-default capturing lambda function. */
4643 1853359 : while (context != containing_function
4644 : /* containing_function can be null with invalid generic lambdas. */
4645 1853359 : && containing_function
4646 2781725 : && LAMBDA_FUNCTION_P (containing_function))
4647 : {
4648 928366 : tree closure = DECL_CONTEXT (containing_function);
4649 928366 : lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure);
4650 :
4651 928366 : if (TYPE_CLASS_SCOPE_P (closure))
4652 : /* A lambda in an NSDMI (c++/64496). */
4653 : break;
4654 :
4655 928363 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4656 : break;
4657 :
4658 928010 : lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack);
4659 :
4660 928010 : containing_function = decl_function_context (containing_function);
4661 : }
4662 :
4663 : /* In a lambda within a template, wait until instantiation time to implicitly
4664 : capture a parameter pack. We want to wait because we don't know if we're
4665 : capturing the whole pack or a single element, and it's OK to wait because
4666 : find_parameter_packs_r walks into the lambda body. */
4667 925349 : if (context == containing_function
4668 925349 : && DECL_PACK_P (decl))
4669 : return decl;
4670 :
4671 885052 : if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
4672 : {
4673 6 : if (complain & tf_error)
4674 6 : error ("cannot capture member %qD of anonymous union", decl);
4675 6 : return error_mark_node;
4676 : }
4677 : /* Do lambda capture when processing the id-expression, not when
4678 : odr-using a variable. */
4679 885046 : if (!odr_use && context == containing_function)
4680 1768508 : decl = add_default_capture (lambda_stack,
4681 884254 : /*id=*/DECL_NAME (decl), initializer);
4682 : /* Only an odr-use of an outer automatic variable causes an
4683 : error, and a constant variable can decay to a prvalue
4684 : constant without odr-use. So don't complain yet. */
4685 792 : else if (!odr_use && decl_constant_var_p (var))
4686 : return var;
4687 308 : else if (lambda_expr)
4688 : {
4689 45 : if (complain & tf_error)
4690 : {
4691 43 : auto_diagnostic_group d;
4692 43 : error ("%qD is not captured", decl);
4693 43 : tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
4694 43 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4695 40 : inform (location_of (closure),
4696 : "the lambda has no capture-default");
4697 3 : else if (TYPE_CLASS_SCOPE_P (closure))
4698 3 : inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot "
4699 : "capture variables from the enclosing context",
4700 3 : TYPE_CONTEXT (closure));
4701 43 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4702 43 : }
4703 45 : return error_mark_node;
4704 : }
4705 263 : else if (processing_contract_condition && (TREE_CODE (decl) == PARM_DECL))
4706 : /* Use of a parameter in a contract condition is fine. */
4707 : return decl;
4708 : else
4709 : {
4710 46 : if (complain & tf_error)
4711 : {
4712 39 : auto_diagnostic_group d;
4713 57 : error (VAR_P (decl)
4714 : ? G_("use of local variable with automatic storage from "
4715 : "containing function")
4716 : : G_("use of parameter from containing function"));
4717 39 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4718 39 : }
4719 46 : return error_mark_node;
4720 : }
4721 884254 : return decl;
4722 : }
4723 :
4724 : /* ID_EXPRESSION is a representation of parsed, but unprocessed,
4725 : id-expression. (See cp_parser_id_expression for details.) SCOPE,
4726 : if non-NULL, is the type or namespace used to explicitly qualify
4727 : ID_EXPRESSION. DECL is the entity to which that name has been
4728 : resolved.
4729 :
4730 : *CONSTANT_EXPRESSION_P is true if we are presently parsing a
4731 : constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
4732 : be set to true if this expression isn't permitted in a
4733 : constant-expression, but it is otherwise not set by this function.
4734 : *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
4735 : constant-expression, but a non-constant expression is also
4736 : permissible.
4737 :
4738 : DONE is true if this expression is a complete postfix-expression;
4739 : it is false if this expression is followed by '->', '[', '(', etc.
4740 : ADDRESS_P is true iff this expression is the operand of '&'.
4741 : TEMPLATE_P is true iff the qualified-id was of the form
4742 : "A::template B". TEMPLATE_ARG_P is true iff this qualified name
4743 : appears as a template argument.
4744 :
4745 : If an error occurs, and it is the kind of error that might cause
4746 : the parser to abort a tentative parse, *ERROR_MSG is filled in. It
4747 : is the caller's responsibility to issue the message. *ERROR_MSG
4748 : will be a string with static storage duration, so the caller need
4749 : not "free" it.
4750 :
4751 : Return an expression for the entity, after issuing appropriate
4752 : diagnostics. This function is also responsible for transforming a
4753 : reference to a non-static member into a COMPONENT_REF that makes
4754 : the use of "this" explicit.
4755 :
4756 : Upon return, *IDK will be filled in appropriately. */
4757 : static cp_expr
4758 745491731 : finish_id_expression_1 (tree id_expression,
4759 : tree decl,
4760 : tree scope,
4761 : cp_id_kind *idk,
4762 : bool integral_constant_expression_p,
4763 : bool allow_non_integral_constant_expression_p,
4764 : bool *non_integral_constant_expression_p,
4765 : bool template_p,
4766 : bool done,
4767 : bool address_p,
4768 : bool template_arg_p,
4769 : const char **error_msg,
4770 : location_t location)
4771 : {
4772 745491731 : decl = strip_using_decl (decl);
4773 :
4774 : /* Initialize the output parameters. */
4775 745491731 : *idk = CP_ID_KIND_NONE;
4776 745491731 : *error_msg = NULL;
4777 :
4778 745491731 : if (id_expression == error_mark_node)
4779 12 : return error_mark_node;
4780 : /* If we have a template-id, then no further lookup is
4781 : required. If the template-id was for a template-class, we
4782 : will sometimes have a TYPE_DECL at this point. */
4783 745491719 : else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4784 695118985 : || TREE_CODE (decl) == TYPE_DECL)
4785 : ;
4786 : /* Look up the name. */
4787 : else
4788 : {
4789 695118096 : if (decl == error_mark_node)
4790 : {
4791 : /* Name lookup failed. */
4792 120306 : if (scope
4793 370 : && !dependent_namespace_p (scope)
4794 120676 : && (!TYPE_P (scope)
4795 116 : || (!dependentish_scope_p (scope)
4796 112 : && !(identifier_p (id_expression)
4797 97 : && IDENTIFIER_CONV_OP_P (id_expression)
4798 3 : && dependent_type_p (TREE_TYPE (id_expression))))))
4799 : {
4800 : /* If the qualifying type is non-dependent (and the name
4801 : does not name a conversion operator to a dependent
4802 : type), issue an error. */
4803 360 : qualified_name_lookup_error (scope, id_expression, decl, location);
4804 360 : return error_mark_node;
4805 : }
4806 119946 : else if (!scope)
4807 : {
4808 : /* It may be resolved via Koenig lookup. */
4809 119936 : *idk = CP_ID_KIND_UNQUALIFIED;
4810 119936 : return id_expression;
4811 : }
4812 : else
4813 : decl = id_expression;
4814 : }
4815 :
4816 : /* Remember that the name was used in the definition of
4817 : the current class so that we can check later to see if
4818 : the meaning would have been different after the class
4819 : was entirely defined. */
4820 694997790 : if (!scope && decl != error_mark_node && identifier_p (id_expression))
4821 621714177 : maybe_note_name_used_in_class (id_expression, decl);
4822 :
4823 : /* A use in unevaluated operand might not be instantiated appropriately
4824 : if tsubst_copy builds a dummy parm, or if we never instantiate a
4825 : generic lambda, so mark it now. */
4826 694997800 : if (processing_template_decl
4827 694997800 : && (cp_unevaluated_operand
4828 601015809 : || generic_lambda_fn_p (current_function_decl)))
4829 18719905 : mark_type_use (decl);
4830 :
4831 : /* Disallow uses of local variables from containing functions, except
4832 : within lambda-expressions. */
4833 694997800 : if (outer_automatic_var_p (decl))
4834 : {
4835 3397910 : decl = process_outer_var_ref (decl, tf_warning_or_error);
4836 3397910 : if (decl == error_mark_node)
4837 85 : return error_mark_node;
4838 : }
4839 :
4840 : /* Also disallow uses of function parameters outside the function
4841 : body, except inside an unevaluated context (i.e. decltype). */
4842 694997715 : if (TREE_CODE (decl) == PARM_DECL
4843 289338299 : && DECL_CONTEXT (decl) == NULL_TREE
4844 7775635 : && !CONSTRAINT_VAR_P (decl)
4845 4204404 : && !cp_unevaluated_operand
4846 374 : && !processing_contract_condition
4847 694997759 : && !processing_omp_trait_property_expr)
4848 : {
4849 26 : *error_msg = G_("use of parameter outside function body");
4850 26 : return error_mark_node;
4851 : }
4852 : }
4853 :
4854 : /* If we didn't find anything, or what we found was a type,
4855 : then this wasn't really an id-expression. */
4856 745371312 : if (TREE_CODE (decl) == TEMPLATE_DECL
4857 745371312 : && !DECL_FUNCTION_TEMPLATE_P (decl))
4858 : {
4859 51 : *error_msg = G_("missing template arguments");
4860 51 : return error_mark_node;
4861 : }
4862 745371261 : else if (TREE_CODE (decl) == TYPE_DECL
4863 745370372 : || TREE_CODE (decl) == NAMESPACE_DECL)
4864 : {
4865 904 : *error_msg = G_("expected primary-expression");
4866 904 : return error_mark_node;
4867 : }
4868 :
4869 : /* If the name resolved to a template parameter, there is no
4870 : need to look it up again later. */
4871 31525021 : if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
4872 758751697 : || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4873 : {
4874 18143681 : tree r;
4875 :
4876 18143681 : *idk = CP_ID_KIND_NONE;
4877 18143681 : if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4878 0 : decl = TEMPLATE_PARM_DECL (decl);
4879 18143681 : r = DECL_INITIAL (decl);
4880 18143681 : if (CLASS_TYPE_P (TREE_TYPE (r)) && !CP_TYPE_CONST_P (TREE_TYPE (r)))
4881 : {
4882 : /* If the entity is a template parameter object for a template
4883 : parameter of type T, the type of the expression is const T. */
4884 163 : tree ctype = TREE_TYPE (r);
4885 163 : ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
4886 : | TYPE_QUAL_CONST));
4887 163 : r = build1 (VIEW_CONVERT_EXPR, ctype, r);
4888 : }
4889 18143681 : r = convert_from_reference (r);
4890 18143681 : if (integral_constant_expression_p
4891 3149344 : && !dependent_type_p (TREE_TYPE (decl))
4892 20819217 : && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
4893 : {
4894 338 : if (!allow_non_integral_constant_expression_p)
4895 6 : error ("template parameter %qD of type %qT is not allowed in "
4896 : "an integral constant expression because it is not of "
4897 6 : "integral or enumeration type", decl, TREE_TYPE (decl));
4898 338 : *non_integral_constant_expression_p = true;
4899 : }
4900 :
4901 18143681 : if (flag_contracts && processing_contract_condition)
4902 9 : r = constify_contract_access (r);
4903 :
4904 18143681 : return r;
4905 : }
4906 727226676 : else if (TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE)
4907 : {
4908 9 : gcc_checking_assert (scope);
4909 9 : *idk = CP_ID_KIND_QUALIFIED;
4910 9 : cp_warn_deprecated_use_scopes (scope);
4911 9 : decl = finish_qualified_id_expr (scope, decl, done, address_p,
4912 : template_p, template_arg_p,
4913 : tf_warning_or_error);
4914 : }
4915 : else
4916 : {
4917 727226667 : if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4918 50372734 : && variable_template_p (TREE_OPERAND (decl, 0))
4919 738554746 : && !concept_check_p (decl))
4920 : /* Try resolving this variable TEMPLATE_ID_EXPR (which is always
4921 : considered type-dependent) now, so that the dependence test that
4922 : follows gives us the right answer: if it represents a non-dependent
4923 : variable template-id then finish_template_variable will yield the
4924 : corresponding non-dependent VAR_DECL. */
4925 11328079 : decl = finish_template_variable (decl);
4926 :
4927 727226667 : bool dependent_p = type_dependent_expression_p (decl);
4928 :
4929 : /* If the declaration was explicitly qualified indicate
4930 : that. The semantics of `A::f(3)' are different than
4931 : `f(3)' if `f' is virtual. */
4932 1454453334 : *idk = (scope
4933 727226667 : ? CP_ID_KIND_QUALIFIED
4934 633243482 : : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4935 633243482 : ? CP_ID_KIND_TEMPLATE_ID
4936 : : (dependent_p
4937 603838247 : ? CP_ID_KIND_UNQUALIFIED_DEPENDENT
4938 : : CP_ID_KIND_UNQUALIFIED)));
4939 :
4940 727226667 : if (dependent_p
4941 727226667 : && !scope
4942 416035983 : && DECL_P (decl)
4943 1114476597 : && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
4944 : /* Dependent type attributes on the decl mean that the TREE_TYPE is
4945 : wrong, so just return the identifier. */
4946 39 : return id_expression;
4947 :
4948 727226628 : if (DECL_CLASS_TEMPLATE_P (decl))
4949 : {
4950 0 : error ("use of class template %qT as expression", decl);
4951 0 : return error_mark_node;
4952 : }
4953 :
4954 727226628 : if (TREE_CODE (decl) == TREE_LIST)
4955 : {
4956 : /* Ambiguous reference to base members. */
4957 0 : auto_diagnostic_group d;
4958 0 : error ("request for member %qD is ambiguous in "
4959 : "multiple inheritance lattice", id_expression);
4960 0 : print_candidates (input_location, decl);
4961 0 : return error_mark_node;
4962 0 : }
4963 :
4964 : /* Mark variable-like entities as used. Functions are similarly
4965 : marked either below or after overload resolution. */
4966 727226628 : if ((VAR_P (decl)
4967 526381599 : || TREE_CODE (decl) == PARM_DECL
4968 237043332 : || TREE_CODE (decl) == CONST_DECL
4969 223661992 : || TREE_CODE (decl) == RESULT_DECL)
4970 1029946235 : && !mark_used (decl))
4971 12 : return error_mark_node;
4972 :
4973 : /* Only certain kinds of names are allowed in constant
4974 : expression. Template parameters have already
4975 : been handled above. */
4976 727226613 : if (! error_operand_p (decl)
4977 727226312 : && !dependent_p
4978 727226312 : && integral_constant_expression_p
4979 73860784 : && !decl_constant_var_p (decl)
4980 60285465 : && TREE_CODE (decl) != CONST_DECL
4981 52115473 : && !builtin_valid_in_constant_expr_p (decl)
4982 779294614 : && !concept_check_p (decl))
4983 : {
4984 51557292 : if (!allow_non_integral_constant_expression_p)
4985 : {
4986 30 : error ("%qD cannot appear in a constant-expression", decl);
4987 30 : return error_mark_node;
4988 : }
4989 51557262 : *non_integral_constant_expression_p = true;
4990 : }
4991 :
4992 727226583 : if (tree wrap = maybe_get_tls_wrapper_call (decl))
4993 : /* Replace an evaluated use of the thread_local variable with
4994 : a call to its wrapper. */
4995 : decl = wrap;
4996 727226071 : else if (concept_check_p (decl))
4997 : {
4998 : /* Nothing more to do. All of the analysis for concept checks
4999 : is done by build_conept_id, called from the parser. */
5000 : }
5001 711848789 : else if (scope)
5002 : {
5003 92242542 : if (TREE_CODE (decl) == SCOPE_REF)
5004 : {
5005 71950 : gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0)));
5006 71950 : decl = TREE_OPERAND (decl, 1);
5007 : }
5008 :
5009 92242542 : decl = (adjust_result_of_qualified_name_lookup
5010 92242542 : (decl, scope, current_nonlambda_class_type()));
5011 :
5012 92242542 : cp_warn_deprecated_use_scopes (scope);
5013 :
5014 92242542 : if (TYPE_P (scope))
5015 13266985 : decl = finish_qualified_id_expr (scope,
5016 : decl,
5017 : done,
5018 : address_p,
5019 : template_p,
5020 : template_arg_p,
5021 : tf_warning_or_error);
5022 : else
5023 78975557 : decl = convert_from_reference (decl);
5024 : }
5025 619606247 : else if (TREE_CODE (decl) == FIELD_DECL)
5026 : {
5027 65057495 : if (flag_contracts && processing_contract_condition
5028 22 : && contract_class_ptr == current_class_ptr)
5029 : {
5030 4 : error ("%qD 'this' required when accessing a member within a "
5031 : "constructor precondition or destructor postcondition "
5032 : "contract check", decl);
5033 4 : return error_mark_node;
5034 : }
5035 : /* Since SCOPE is NULL here, this is an unqualified name.
5036 : Access checking has been performed during name lookup
5037 : already. Turn off checking to avoid duplicate errors. */
5038 65057491 : push_deferring_access_checks (dk_no_check);
5039 65057491 : decl = finish_non_static_data_member (decl, NULL_TREE,
5040 : /*qualifying_scope=*/NULL_TREE);
5041 65057491 : pop_deferring_access_checks ();
5042 : }
5043 554548752 : else if (is_overloaded_fn (decl))
5044 : {
5045 : /* We only need to look at the first function,
5046 : because all the fns share the attribute we're
5047 : concerned with (all member fns or all non-members). */
5048 59106199 : tree first_fn = get_first_fn (decl);
5049 59106199 : first_fn = STRIP_TEMPLATE (first_fn);
5050 :
5051 59106199 : if (!template_arg_p
5052 59106199 : && (TREE_CODE (first_fn) == USING_DECL
5053 59104351 : || (TREE_CODE (first_fn) == FUNCTION_DECL
5054 59104351 : && DECL_FUNCTION_MEMBER_P (first_fn)
5055 35816119 : && !shared_member_p (decl))))
5056 : {
5057 : /* A set of member functions. */
5058 27693961 : if (flag_contracts && processing_contract_condition
5059 16 : && contract_class_ptr == current_class_ptr)
5060 : {
5061 2 : error ("%qD 'this' required when accessing a member within a "
5062 : "constructor precondition or destructor postcondition "
5063 : "contract check", decl);
5064 2 : return error_mark_node;
5065 : }
5066 27693959 : decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
5067 27693959 : return finish_class_member_access_expr (decl, id_expression,
5068 : /*template_p=*/false,
5069 27693959 : tf_warning_or_error);
5070 : }
5071 :
5072 31412238 : decl = baselink_for_fns (decl);
5073 : }
5074 : else
5075 : {
5076 484988092 : if (DECL_P (decl) && DECL_NONLOCAL (decl)
5077 496899404 : && DECL_CLASS_SCOPE_P (decl))
5078 : {
5079 1456851 : tree context = context_for_name_lookup (decl);
5080 1456851 : if (context != current_class_type)
5081 : {
5082 766606 : tree path = currently_open_derived_class (context);
5083 766606 : if (!path)
5084 : /* PATH can be null for using an enum of an unrelated
5085 : class; we checked its access in lookup_using_decl.
5086 :
5087 : ??? Should this case make a clone instead, like
5088 : handle_using_decl? */
5089 23 : gcc_assert (TREE_CODE (decl) == CONST_DECL
5090 : /* This is for:
5091 : constexpr auto r = ^^S::i;
5092 : auto a = [:r:]; */
5093 : || flag_reflection);
5094 : else
5095 766583 : perform_or_defer_access_check (TYPE_BINFO (path),
5096 : decl, decl,
5097 : tf_warning_or_error);
5098 : }
5099 : }
5100 :
5101 495442553 : decl = convert_from_reference (decl);
5102 : }
5103 : }
5104 :
5105 699532627 : check_param_in_postcondition (decl, location);
5106 699532627 : if (flag_contracts && processing_contract_condition)
5107 1303 : decl = constify_contract_access (decl);
5108 :
5109 699532627 : return cp_expr (decl, location);
5110 : }
5111 :
5112 : /* As per finish_id_expression_1, but adding a wrapper node
5113 : around the result if needed to express LOCATION. */
5114 :
5115 : cp_expr
5116 745491731 : finish_id_expression (tree id_expression,
5117 : tree decl,
5118 : tree scope,
5119 : cp_id_kind *idk,
5120 : bool integral_constant_expression_p,
5121 : bool allow_non_integral_constant_expression_p,
5122 : bool *non_integral_constant_expression_p,
5123 : bool template_p,
5124 : bool done,
5125 : bool address_p,
5126 : bool template_arg_p,
5127 : const char **error_msg,
5128 : location_t location)
5129 : {
5130 745491731 : cp_expr result
5131 745491731 : = finish_id_expression_1 (id_expression, decl, scope, idk,
5132 : integral_constant_expression_p,
5133 : allow_non_integral_constant_expression_p,
5134 : non_integral_constant_expression_p,
5135 : template_p, done, address_p, template_arg_p,
5136 : error_msg, location);
5137 745491728 : return result.maybe_add_location_wrapper ();
5138 : }
5139 :
5140 : /* Implement the __typeof keyword: Return the type of EXPR, suitable for
5141 : use as a type-specifier. */
5142 :
5143 : tree
5144 20994225 : finish_typeof (tree expr)
5145 : {
5146 20994225 : tree type;
5147 :
5148 20994225 : if (type_dependent_expression_p (expr))
5149 : {
5150 20903668 : type = cxx_make_type (TYPEOF_TYPE);
5151 20903668 : TYPEOF_TYPE_EXPR (type) = expr;
5152 20903668 : SET_TYPE_STRUCTURAL_EQUALITY (type);
5153 :
5154 20903668 : return type;
5155 : }
5156 :
5157 90557 : expr = mark_type_use (expr);
5158 :
5159 90557 : type = unlowered_expr_type (expr);
5160 :
5161 90557 : if (!type || type == unknown_type_node)
5162 : {
5163 3 : error ("type of %qE is unknown", expr);
5164 3 : return error_mark_node;
5165 : }
5166 :
5167 : return type;
5168 : }
5169 :
5170 : /* Implement the __underlying_type keyword: Return the underlying
5171 : type of TYPE, suitable for use as a type-specifier. */
5172 :
5173 : tree
5174 46368 : finish_underlying_type (tree type)
5175 : {
5176 46368 : if (!complete_type_or_else (type, NULL_TREE))
5177 3 : return error_mark_node;
5178 :
5179 46365 : if (TREE_CODE (type) != ENUMERAL_TYPE)
5180 : {
5181 24 : error ("%qT is not an enumeration type", type);
5182 24 : return error_mark_node;
5183 : }
5184 :
5185 46341 : tree underlying_type = ENUM_UNDERLYING_TYPE (type);
5186 :
5187 : /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
5188 : includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
5189 : See finish_enum_value_list for details. */
5190 46341 : if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
5191 54 : underlying_type
5192 54 : = c_common_type_for_mode (TYPE_MODE (underlying_type),
5193 54 : TYPE_UNSIGNED (underlying_type));
5194 :
5195 : return underlying_type;
5196 : }
5197 :
5198 : /* Implement the __type_pack_element keyword: Return the type
5199 : at index IDX within TYPES. */
5200 :
5201 : static tree
5202 113378 : finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
5203 : {
5204 113378 : idx = maybe_constant_value (idx, NULL_TREE, mce_true);
5205 113378 : if (!INTEGRAL_TYPE_P (TREE_TYPE (idx)))
5206 : {
5207 6 : if (complain & tf_error)
5208 3 : error ("pack index has non-integral type %qT", TREE_TYPE (idx));
5209 6 : return error_mark_node;
5210 : }
5211 113372 : if (TREE_CODE (idx) != INTEGER_CST)
5212 : {
5213 1 : if (complain & tf_error)
5214 : {
5215 1 : error ("pack index is not an integral constant");
5216 1 : cxx_constant_value (idx);
5217 : }
5218 1 : return error_mark_node;
5219 : }
5220 113371 : if (tree_int_cst_sgn (idx) < 0)
5221 : {
5222 5 : if (complain & tf_error)
5223 5 : error ("pack index %qE is negative", idx);
5224 5 : return error_mark_node;
5225 : }
5226 113366 : if (wi::to_widest (idx) >= TREE_VEC_LENGTH (types))
5227 : {
5228 28 : if (complain & tf_error)
5229 22 : error ("pack index %qE is out of range for pack of length %qd",
5230 22 : idx, TREE_VEC_LENGTH (types));
5231 28 : return error_mark_node;
5232 : }
5233 113338 : return TREE_VEC_ELT (types, tree_to_shwi (idx));
5234 : }
5235 :
5236 : /* In a pack-index T...[N], return the element at index IDX within TYPES.
5237 : PARENTHESIZED_P is true iff the pack index was wrapped in (). */
5238 :
5239 : tree
5240 7618 : pack_index_element (tree idx, tree types, bool parenthesized_p,
5241 : tsubst_flags_t complain)
5242 : {
5243 7618 : tree r = finish_type_pack_element (idx, types, complain);
5244 7618 : if (parenthesized_p)
5245 : /* For the benefit of decltype(auto). */
5246 22 : r = force_paren_expr (r);
5247 7618 : return r;
5248 : }
5249 :
5250 : /* Implement the __direct_bases keyword: Return the direct base classes
5251 : of type. */
5252 :
5253 : tree
5254 15 : calculate_direct_bases (tree type, tsubst_flags_t complain)
5255 : {
5256 15 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5257 15 : || !NON_UNION_CLASS_TYPE_P (type))
5258 8 : return make_tree_vec (0);
5259 :
5260 7 : releasing_vec vector;
5261 7 : vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
5262 7 : tree binfo;
5263 7 : unsigned i;
5264 :
5265 : /* Virtual bases are initialized first */
5266 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5267 13 : if (BINFO_VIRTUAL_P (binfo))
5268 2 : vec_safe_push (vector, binfo);
5269 :
5270 : /* Now non-virtuals */
5271 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5272 13 : if (!BINFO_VIRTUAL_P (binfo))
5273 11 : vec_safe_push (vector, binfo);
5274 :
5275 7 : tree bases_vec = make_tree_vec (vector->length ());
5276 :
5277 27 : for (i = 0; i < vector->length (); ++i)
5278 13 : TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
5279 :
5280 7 : return bases_vec;
5281 7 : }
5282 :
5283 : /* Implement the __bases keyword: Return the base classes
5284 : of type */
5285 :
5286 : /* Find morally non-virtual base classes by walking binfo hierarchy */
5287 : /* Virtual base classes are handled separately in finish_bases */
5288 :
5289 : static tree
5290 73 : dfs_calculate_bases_pre (tree binfo, void * /*data_*/)
5291 : {
5292 : /* Don't walk bases of virtual bases */
5293 73 : return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE;
5294 : }
5295 :
5296 : static tree
5297 73 : dfs_calculate_bases_post (tree binfo, void *data_)
5298 : {
5299 73 : vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
5300 73 : if (!BINFO_VIRTUAL_P (binfo))
5301 48 : vec_safe_push (*data, BINFO_TYPE (binfo));
5302 73 : return NULL_TREE;
5303 : }
5304 :
5305 : /* Calculates the morally non-virtual base classes of a class */
5306 : static vec<tree, va_gc> *
5307 16 : calculate_bases_helper (tree type)
5308 : {
5309 16 : vec<tree, va_gc> *vector = make_tree_vector ();
5310 :
5311 : /* Now add non-virtual base classes in order of construction */
5312 16 : if (TYPE_BINFO (type))
5313 16 : dfs_walk_all (TYPE_BINFO (type),
5314 : dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector);
5315 16 : return vector;
5316 : }
5317 :
5318 : tree
5319 12 : calculate_bases (tree type, tsubst_flags_t complain)
5320 : {
5321 12 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5322 12 : || !NON_UNION_CLASS_TYPE_P (type))
5323 5 : return make_tree_vec (0);
5324 :
5325 7 : releasing_vec vector;
5326 7 : tree bases_vec = NULL_TREE;
5327 7 : unsigned i;
5328 7 : vec<tree, va_gc> *vbases;
5329 7 : tree binfo;
5330 :
5331 : /* First go through virtual base classes */
5332 7 : for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
5333 16 : vec_safe_iterate (vbases, i, &binfo); i++)
5334 : {
5335 9 : releasing_vec vbase_bases
5336 9 : = calculate_bases_helper (BINFO_TYPE (binfo));
5337 9 : vec_safe_splice (vector, vbase_bases);
5338 9 : }
5339 :
5340 : /* Now for the non-virtual bases */
5341 7 : releasing_vec nonvbases = calculate_bases_helper (type);
5342 7 : vec_safe_splice (vector, nonvbases);
5343 :
5344 : /* Note that during error recovery vector->length can even be zero. */
5345 7 : if (vector->length () > 1)
5346 : {
5347 : /* Last element is entire class, so don't copy */
5348 6 : bases_vec = make_tree_vec (vector->length () - 1);
5349 :
5350 53 : for (i = 0; i < vector->length () - 1; ++i)
5351 41 : TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
5352 : }
5353 : else
5354 1 : bases_vec = make_tree_vec (0);
5355 :
5356 7 : return bases_vec;
5357 7 : }
5358 :
5359 : tree
5360 28 : finish_bases (tree type, bool direct)
5361 : {
5362 28 : tree bases = NULL_TREE;
5363 :
5364 28 : if (!processing_template_decl)
5365 : {
5366 : /* Parameter packs can only be used in templates */
5367 0 : error ("parameter pack %<__bases%> only valid in template declaration");
5368 0 : return error_mark_node;
5369 : }
5370 :
5371 28 : bases = cxx_make_type (BASES);
5372 28 : BASES_TYPE (bases) = type;
5373 28 : BASES_DIRECT (bases) = direct;
5374 28 : SET_TYPE_STRUCTURAL_EQUALITY (bases);
5375 :
5376 28 : return bases;
5377 : }
5378 :
5379 : /* Perform C++-specific checks for __builtin_offsetof before calling
5380 : fold_offsetof. */
5381 :
5382 : tree
5383 2400 : finish_offsetof (tree object_ptr, tree expr, location_t loc)
5384 : {
5385 : /* If we're processing a template, we can't finish the semantics yet.
5386 : Otherwise we can fold the entire expression now. */
5387 2400 : if (processing_template_decl)
5388 : {
5389 60 : expr = build2 (OFFSETOF_EXPR, size_type_node, expr, object_ptr);
5390 60 : SET_EXPR_LOCATION (expr, loc);
5391 60 : return expr;
5392 : }
5393 :
5394 2340 : if (expr == error_mark_node)
5395 : return error_mark_node;
5396 :
5397 2323 : if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
5398 : {
5399 6 : error ("cannot apply %<offsetof%> to destructor %<~%T%>",
5400 6 : TREE_OPERAND (expr, 2));
5401 6 : return error_mark_node;
5402 : }
5403 4619 : if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr))
5404 4619 : || TREE_TYPE (expr) == unknown_type_node)
5405 : {
5406 30 : while (TREE_CODE (expr) == COMPONENT_REF
5407 30 : || TREE_CODE (expr) == COMPOUND_EXPR)
5408 12 : expr = TREE_OPERAND (expr, 1);
5409 :
5410 18 : if (DECL_P (expr))
5411 : {
5412 0 : auto_diagnostic_group d;
5413 0 : error ("cannot apply %<offsetof%> to member function %qD", expr);
5414 0 : inform (DECL_SOURCE_LOCATION (expr), "declared here");
5415 0 : }
5416 : else
5417 18 : error ("cannot apply %<offsetof%> to member function");
5418 18 : return error_mark_node;
5419 : }
5420 2299 : if (TREE_CODE (expr) == CONST_DECL)
5421 : {
5422 3 : error ("cannot apply %<offsetof%> to an enumerator %qD", expr);
5423 3 : return error_mark_node;
5424 : }
5425 2296 : if (REFERENCE_REF_P (expr))
5426 9 : expr = TREE_OPERAND (expr, 0);
5427 2296 : if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr))
5428 3 : return error_mark_node;
5429 2293 : if (warn_invalid_offsetof
5430 2293 : && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
5431 2293 : && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
5432 2338 : && cp_unevaluated_operand == 0)
5433 45 : warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within "
5434 : "non-standard-layout type %qT is conditionally-supported",
5435 45 : TREE_TYPE (TREE_TYPE (object_ptr)));
5436 2293 : return fold_offsetof (expr);
5437 : }
5438 :
5439 : /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
5440 : function is broken out from the above for the benefit of the tree-ssa
5441 : project. */
5442 :
5443 : void
5444 338583 : simplify_aggr_init_expr (tree *tp)
5445 : {
5446 338583 : tree aggr_init_expr = *tp;
5447 :
5448 : /* Form an appropriate CALL_EXPR. */
5449 338583 : tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
5450 338583 : tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
5451 338583 : tree type = TREE_TYPE (slot);
5452 :
5453 338583 : tree call_expr;
5454 338583 : enum style_t { ctor, arg, pcc } style;
5455 :
5456 338583 : if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
5457 : style = ctor;
5458 : #ifdef PCC_STATIC_STRUCT_RETURN
5459 : else if (1)
5460 : style = pcc;
5461 : #endif
5462 : else
5463 : {
5464 89175 : gcc_assert (TREE_ADDRESSABLE (type));
5465 : style = arg;
5466 : }
5467 :
5468 338583 : call_expr = build_call_array_loc (input_location,
5469 338583 : TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
5470 : fn,
5471 338583 : aggr_init_expr_nargs (aggr_init_expr),
5472 338583 : AGGR_INIT_EXPR_ARGP (aggr_init_expr));
5473 338583 : TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
5474 338583 : CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr);
5475 338583 : CALL_EXPR_OPERATOR_SYNTAX (call_expr)
5476 338583 : = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
5477 338583 : CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
5478 338583 : CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
5479 338583 : CALL_EXPR_MUST_TAIL_CALL (call_expr) = AGGR_INIT_EXPR_MUST_TAIL (aggr_init_expr);
5480 :
5481 338583 : if (style == ctor)
5482 : {
5483 : /* Replace the first argument to the ctor with the address of the
5484 : slot. */
5485 249408 : cxx_mark_addressable (slot);
5486 249408 : CALL_EXPR_ARG (call_expr, 0) =
5487 249408 : build1 (ADDR_EXPR, build_pointer_type (type), slot);
5488 : }
5489 89175 : else if (style == arg)
5490 : {
5491 : /* Just mark it addressable here, and leave the rest to
5492 : expand_call{,_inline}. */
5493 89175 : cxx_mark_addressable (slot);
5494 89175 : CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
5495 89175 : call_expr = cp_build_init_expr (slot, call_expr);
5496 : }
5497 : else if (style == pcc)
5498 : {
5499 : /* If we're using the non-reentrant PCC calling convention, then we
5500 : need to copy the returned value out of the static buffer into the
5501 : SLOT. */
5502 : push_deferring_access_checks (dk_no_check);
5503 : call_expr = build_aggr_init (slot, call_expr,
5504 : DIRECT_BIND | LOOKUP_ONLYCONVERTING,
5505 : tf_warning_or_error);
5506 : pop_deferring_access_checks ();
5507 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
5508 : }
5509 :
5510 338583 : if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
5511 : {
5512 3227 : tree init = build_zero_init (type, NULL_TREE,
5513 : /*static_storage_p=*/false);
5514 3227 : init = cp_build_init_expr (slot, init);
5515 3227 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
5516 : init, call_expr);
5517 : }
5518 :
5519 338583 : *tp = call_expr;
5520 338583 : }
5521 :
5522 : /* Emit all thunks to FN that should be emitted when FN is emitted. */
5523 :
5524 : void
5525 65328873 : emit_associated_thunks (tree fn)
5526 : {
5527 : /* When we use vcall offsets, we emit thunks with the virtual
5528 : functions to which they thunk. The whole point of vcall offsets
5529 : is so that you can know statically the entire set of thunks that
5530 : will ever be needed for a given virtual function, thereby
5531 : enabling you to output all the thunks with the function itself. */
5532 65328873 : if (DECL_VIRTUAL_P (fn)
5533 : /* Do not emit thunks for extern template instantiations. */
5534 1328523 : && ! DECL_REALLY_EXTERN (fn)
5535 : /* Do not emit thunks for tentative decls, those will be processed
5536 : again at_eof if really needed. */
5537 66493872 : && (DECL_INTERFACE_KNOWN (fn) || !DECL_DEFER_OUTPUT (fn)))
5538 : {
5539 1164316 : tree thunk;
5540 :
5541 2332840 : for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
5542 : {
5543 4208 : if (!THUNK_ALIAS (thunk))
5544 : {
5545 4208 : use_thunk (thunk, /*emit_p=*/1);
5546 4208 : if (DECL_RESULT_THUNK_P (thunk))
5547 : {
5548 178 : tree probe;
5549 :
5550 178 : for (probe = DECL_THUNKS (thunk);
5551 327 : probe; probe = DECL_CHAIN (probe))
5552 149 : use_thunk (probe, /*emit_p=*/1);
5553 : }
5554 : }
5555 : else
5556 0 : gcc_assert (!DECL_THUNKS (thunk));
5557 : }
5558 : }
5559 65328873 : }
5560 :
5561 : /* Generate RTL for FN. */
5562 :
5563 : bool
5564 164984740 : expand_or_defer_fn_1 (tree fn)
5565 : {
5566 : /* When the parser calls us after finishing the body of a template
5567 : function, we don't really want to expand the body. */
5568 164984740 : if (processing_template_decl)
5569 : {
5570 : /* Normally, collection only occurs in rest_of_compilation. So,
5571 : if we don't collect here, we never collect junk generated
5572 : during the processing of templates until we hit a
5573 : non-template function. It's not safe to do this inside a
5574 : nested class, though, as the parser may have local state that
5575 : is not a GC root. */
5576 90992314 : if (!function_depth)
5577 90562947 : ggc_collect ();
5578 90992314 : return false;
5579 : }
5580 :
5581 73992426 : gcc_assert (DECL_SAVED_TREE (fn));
5582 :
5583 : /* We make a decision about linkage for these functions at the end
5584 : of the compilation. Until that point, we do not want the back
5585 : end to output them -- but we do want it to see the bodies of
5586 : these functions so that it can inline them as appropriate. */
5587 73992426 : if (DECL_DECLARED_INLINE_P (fn)
5588 2039583 : || DECL_IMPLICIT_INSTANTIATION (fn)
5589 74249294 : || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
5590 : {
5591 73735585 : if (DECL_INTERFACE_KNOWN (fn))
5592 : /* We've already made a decision as to how this function will
5593 : be handled. */;
5594 52639967 : else if (!at_eof
5595 23567550 : || DECL_IMMEDIATE_FUNCTION_P (fn)
5596 75304946 : || DECL_OMP_DECLARE_REDUCTION_P (fn))
5597 29974988 : tentative_decl_linkage (fn);
5598 : else
5599 22664979 : import_export_decl (fn);
5600 :
5601 : /* If the user wants us to keep all inline functions, then mark
5602 : this function as needed so that finish_file will make sure to
5603 : output it later. Similarly, all dllexport'd functions must
5604 : be emitted; there may be callers in other DLLs. */
5605 73735585 : if (DECL_DECLARED_INLINE_P (fn)
5606 71952843 : && !DECL_REALLY_EXTERN (fn)
5607 69387909 : && !DECL_IMMEDIATE_FUNCTION_P (fn)
5608 67972176 : && !DECL_OMP_DECLARE_REDUCTION_P (fn)
5609 141707761 : && (flag_keep_inline_functions
5610 67969284 : || (flag_keep_inline_dllexport
5611 67969284 : && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))))
5612 : {
5613 2892 : mark_needed (fn);
5614 2892 : DECL_EXTERNAL (fn) = 0;
5615 : }
5616 : }
5617 :
5618 : /* If this is a constructor or destructor body, we have to clone
5619 : it. */
5620 73992426 : if (maybe_clone_body (fn))
5621 : {
5622 : /* We don't want to process FN again, so pretend we've written
5623 : it out, even though we haven't. */
5624 8635409 : TREE_ASM_WRITTEN (fn) = 1;
5625 : /* If this is a constexpr function we still need the body to be
5626 : able to evaluate it. Similarly, with modules we only stream
5627 : the maybe-in-charge cdtor and regenerate the clones from it on
5628 : demand, so we also need to keep the body. Otherwise we don't
5629 : need it anymore. */
5630 8635409 : if (!maybe_constexpr_fn (fn)
5631 8635409 : && !(module_maybe_has_cmi_p () && vague_linkage_p (fn)))
5632 3790682 : DECL_SAVED_TREE (fn) = void_node;
5633 8635409 : return false;
5634 : }
5635 :
5636 : /* There's no reason to do any of the work here if we're only doing
5637 : semantic analysis; this code just generates RTL. */
5638 65357017 : if (flag_syntax_only)
5639 : {
5640 : /* Pretend that this function has been written out so that we don't try
5641 : to expand it again. */
5642 28128 : TREE_ASM_WRITTEN (fn) = 1;
5643 28128 : return false;
5644 : }
5645 :
5646 65328889 : if (DECL_OMP_DECLARE_REDUCTION_P (fn))
5647 : return false;
5648 :
5649 : return true;
5650 : }
5651 :
5652 : void
5653 156367880 : expand_or_defer_fn (tree fn)
5654 : {
5655 156367880 : if (expand_or_defer_fn_1 (fn))
5656 : {
5657 56714504 : function_depth++;
5658 :
5659 : /* Expand or defer, at the whim of the compilation unit manager. */
5660 56714504 : cgraph_node::finalize_function (fn, function_depth > 1);
5661 56714504 : emit_associated_thunks (fn);
5662 :
5663 56714504 : function_depth--;
5664 :
5665 113429008 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
5666 : {
5667 1357858 : if (cgraph_node *node = cgraph_node::get (fn))
5668 : {
5669 1357858 : node->body_removed = true;
5670 1357858 : node->analyzed = false;
5671 1357858 : node->definition = false;
5672 1357858 : node->force_output = false;
5673 : }
5674 : }
5675 : }
5676 156367880 : }
5677 :
5678 507334 : class nrv_data
5679 : {
5680 : public:
5681 253667 : nrv_data () : visited (37) {}
5682 :
5683 : tree var;
5684 : tree result;
5685 : hash_set<tree> visited;
5686 : bool simple;
5687 : bool in_nrv_cleanup;
5688 : };
5689 :
5690 : /* Helper function for walk_tree, used by finalize_nrv below. */
5691 :
5692 : static tree
5693 27046281 : finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
5694 : {
5695 27046281 : class nrv_data *dp = (class nrv_data *)data;
5696 :
5697 : /* No need to walk into types. There wouldn't be any need to walk into
5698 : non-statements, except that we have to consider STMT_EXPRs. */
5699 27046281 : if (TYPE_P (*tp))
5700 201648 : *walk_subtrees = 0;
5701 :
5702 : /* Replace all uses of the NRV with the RESULT_DECL. */
5703 26844633 : else if (*tp == dp->var)
5704 576669 : *tp = dp->result;
5705 :
5706 : /* Avoid walking into the same tree more than once. Unfortunately, we
5707 : can't just use walk_tree_without duplicates because it would only call
5708 : us for the first occurrence of dp->var in the function body. */
5709 26267964 : else if (dp->visited.add (*tp))
5710 5782165 : *walk_subtrees = 0;
5711 :
5712 : /* If there's a label, we might need to destroy the NRV on goto (92407). */
5713 20485799 : else if (TREE_CODE (*tp) == LABEL_EXPR && !dp->in_nrv_cleanup)
5714 3 : dp->simple = false;
5715 : /* Change NRV returns to just refer to the RESULT_DECL; this is a nop,
5716 : but differs from using NULL_TREE in that it indicates that we care
5717 : about the value of the RESULT_DECL. But preserve anything appended
5718 : by check_return_expr. */
5719 20485796 : else if (TREE_CODE (*tp) == RETURN_EXPR)
5720 : {
5721 291681 : tree *p = &TREE_OPERAND (*tp, 0);
5722 754246 : while (TREE_CODE (*p) == COMPOUND_EXPR)
5723 170884 : p = &TREE_OPERAND (*p, 0);
5724 291681 : if (TREE_CODE (*p) == INIT_EXPR
5725 291681 : && INIT_EXPR_NRV_P (*p))
5726 291304 : *p = dp->result;
5727 : }
5728 : /* Change all cleanups for the NRV to only run when not returning. */
5729 20194115 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5730 20194115 : && CLEANUP_DECL (*tp) == dp->var)
5731 : {
5732 133828 : dp->in_nrv_cleanup = true;
5733 133828 : cp_walk_tree (&CLEANUP_BODY (*tp), finalize_nrv_r, data, 0);
5734 133828 : dp->in_nrv_cleanup = false;
5735 133828 : cp_walk_tree (&CLEANUP_EXPR (*tp), finalize_nrv_r, data, 0);
5736 133828 : *walk_subtrees = 0;
5737 :
5738 133828 : if (dp->simple)
5739 : /* For a simple NRV, just run it on the EH path. */
5740 133212 : CLEANUP_EH_ONLY (*tp) = true;
5741 : else
5742 : {
5743 : /* Not simple, we need to check current_retval_sentinel to decide
5744 : whether to run it. If it's set, we're returning normally and
5745 : don't want to destroy the NRV. If the sentinel is not set, we're
5746 : leaving scope some other way, either by flowing off the end of its
5747 : scope or throwing an exception. */
5748 1848 : tree cond = build3 (COND_EXPR, void_type_node,
5749 616 : current_retval_sentinel,
5750 616 : void_node, CLEANUP_EXPR (*tp));
5751 616 : CLEANUP_EXPR (*tp) = cond;
5752 : }
5753 :
5754 : /* If a cleanup might throw, we need to clear current_retval_sentinel on
5755 : the exception path, both so the check above succeeds and so an outer
5756 : cleanup added by maybe_splice_retval_cleanup doesn't run. */
5757 133828 : if (cp_function_chain->throwing_cleanup)
5758 : {
5759 194 : tree clear = build2 (MODIFY_EXPR, boolean_type_node,
5760 : current_retval_sentinel,
5761 : boolean_false_node);
5762 194 : if (dp->simple)
5763 : {
5764 : /* We're already only on the EH path, just prepend it. */
5765 184 : tree &exp = CLEANUP_EXPR (*tp);
5766 184 : exp = build2 (COMPOUND_EXPR, void_type_node, clear, exp);
5767 : }
5768 : else
5769 : {
5770 : /* The cleanup runs on both normal and EH paths, we need another
5771 : CLEANUP_STMT to clear the flag only on the EH path. */
5772 10 : tree &bod = CLEANUP_BODY (*tp);
5773 10 : bod = build_stmt (EXPR_LOCATION (*tp), CLEANUP_STMT,
5774 10 : bod, clear, current_retval_sentinel);
5775 10 : CLEANUP_EH_ONLY (bod) = true;
5776 : }
5777 : }
5778 : }
5779 : /* Disable maybe_splice_retval_cleanup within the NRV cleanup scope, we don't
5780 : want to destroy the retval before the variable goes out of scope. */
5781 20060287 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5782 20958 : && dp->in_nrv_cleanup
5783 20080115 : && CLEANUP_DECL (*tp) == dp->result)
5784 6 : CLEANUP_EXPR (*tp) = void_node;
5785 : /* Replace the DECL_EXPR for the NRV with an initialization of the
5786 : RESULT_DECL, if needed. */
5787 20060281 : else if (TREE_CODE (*tp) == DECL_EXPR
5788 20060281 : && DECL_EXPR_DECL (*tp) == dp->var)
5789 : {
5790 253669 : tree init;
5791 253669 : if (DECL_INITIAL (dp->var)
5792 253669 : && DECL_INITIAL (dp->var) != error_mark_node)
5793 95130 : init = cp_build_init_expr (dp->result,
5794 95130 : DECL_INITIAL (dp->var));
5795 : else
5796 158539 : init = build_empty_stmt (EXPR_LOCATION (*tp));
5797 253669 : DECL_INITIAL (dp->var) = NULL_TREE;
5798 253669 : SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
5799 253669 : *tp = init;
5800 : }
5801 :
5802 : /* Keep iterating. */
5803 27046281 : return NULL_TREE;
5804 : }
5805 :
5806 : /* Called from finish_function to implement the named return value
5807 : optimization by overriding all the RETURN_EXPRs and pertinent
5808 : CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
5809 : RESULT_DECL for the function. */
5810 :
5811 : void
5812 253667 : finalize_nrv (tree fndecl, tree var)
5813 : {
5814 253667 : class nrv_data data;
5815 253667 : tree result = DECL_RESULT (fndecl);
5816 :
5817 : /* Copy name from VAR to RESULT. */
5818 253667 : DECL_NAME (result) = DECL_NAME (var);
5819 : /* Don't forget that we take its address. */
5820 253667 : TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
5821 : /* Finally set DECL_VALUE_EXPR to avoid assigning
5822 : a stack slot at -O0 for the original var and debug info
5823 : uses RESULT location for VAR. */
5824 253667 : SET_DECL_VALUE_EXPR (var, result);
5825 253667 : DECL_HAS_VALUE_EXPR_P (var) = 1;
5826 :
5827 253667 : data.var = var;
5828 253667 : data.result = result;
5829 253667 : data.in_nrv_cleanup = false;
5830 :
5831 : /* This is simpler for variables declared in the outer scope of
5832 : the function so we know that their lifetime always ends with a
5833 : return; see g++.dg/opt/nrv6.C. */
5834 253667 : tree outer = outer_curly_brace_block (fndecl);
5835 253667 : data.simple = chain_member (var, BLOCK_VARS (outer));
5836 :
5837 253667 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), finalize_nrv_r, &data, 0);
5838 253667 : }
5839 :
5840 : /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */
5841 :
5842 : bool
5843 2239 : cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
5844 : bool need_copy_ctor, bool need_copy_assignment,
5845 : bool need_dtor)
5846 : {
5847 2239 : int save_errorcount = errorcount;
5848 2239 : tree info, t;
5849 :
5850 : /* Always allocate 3 elements for simplicity. These are the
5851 : function decls for the ctor, dtor, and assignment op.
5852 : This layout is known to the three lang hooks,
5853 : cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
5854 : and cxx_omp_clause_assign_op. */
5855 2239 : info = make_tree_vec (3);
5856 2239 : CP_OMP_CLAUSE_INFO (c) = info;
5857 :
5858 2239 : if (need_default_ctor || need_copy_ctor)
5859 : {
5860 1654 : if (need_default_ctor)
5861 1255 : t = get_default_ctor (type);
5862 : else
5863 399 : t = get_copy_ctor (type, tf_warning_or_error);
5864 :
5865 1654 : if (t && !trivial_fn_p (t))
5866 1400 : TREE_VEC_ELT (info, 0) = t;
5867 : }
5868 :
5869 2239 : if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
5870 1632 : TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error);
5871 :
5872 2239 : if (need_copy_assignment)
5873 : {
5874 397 : t = get_copy_assign (type);
5875 :
5876 397 : if (t && !trivial_fn_p (t))
5877 344 : TREE_VEC_ELT (info, 2) = t;
5878 : }
5879 :
5880 2239 : return errorcount != save_errorcount;
5881 : }
5882 :
5883 : /* If DECL is DECL_OMP_PRIVATIZED_MEMBER, return corresponding
5884 : FIELD_DECL, otherwise return DECL itself. */
5885 :
5886 : static tree
5887 26243 : omp_clause_decl_field (tree decl)
5888 : {
5889 26243 : if (VAR_P (decl)
5890 18396 : && DECL_HAS_VALUE_EXPR_P (decl)
5891 359 : && DECL_ARTIFICIAL (decl)
5892 359 : && DECL_LANG_SPECIFIC (decl)
5893 26578 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
5894 : {
5895 328 : tree f = DECL_VALUE_EXPR (decl);
5896 328 : if (INDIRECT_REF_P (f))
5897 0 : f = TREE_OPERAND (f, 0);
5898 328 : if (TREE_CODE (f) == COMPONENT_REF)
5899 : {
5900 328 : f = TREE_OPERAND (f, 1);
5901 328 : gcc_assert (TREE_CODE (f) == FIELD_DECL);
5902 : return f;
5903 : }
5904 : }
5905 : return NULL_TREE;
5906 : }
5907 :
5908 : /* Adjust DECL if needed for printing using %qE. */
5909 :
5910 : static tree
5911 187 : omp_clause_printable_decl (tree decl)
5912 : {
5913 0 : tree t = omp_clause_decl_field (decl);
5914 187 : if (t)
5915 45 : return t;
5916 : return decl;
5917 : }
5918 :
5919 : /* For a FIELD_DECL F and corresponding DECL_OMP_PRIVATIZED_MEMBER
5920 : VAR_DECL T that doesn't need a DECL_EXPR added, record it for
5921 : privatization. */
5922 :
5923 : static void
5924 219 : omp_note_field_privatization (tree f, tree t)
5925 : {
5926 219 : if (!omp_private_member_map)
5927 71 : omp_private_member_map = new hash_map<tree, tree>;
5928 219 : tree &v = omp_private_member_map->get_or_insert (f);
5929 219 : if (v == NULL_TREE)
5930 : {
5931 146 : v = t;
5932 146 : omp_private_member_vec.safe_push (f);
5933 : /* Signal that we don't want to create DECL_EXPR for this dummy var. */
5934 146 : omp_private_member_vec.safe_push (integer_zero_node);
5935 : }
5936 219 : }
5937 :
5938 : /* Privatize FIELD_DECL T, return corresponding DECL_OMP_PRIVATIZED_MEMBER
5939 : dummy VAR_DECL. */
5940 :
5941 : tree
5942 861 : omp_privatize_field (tree t, bool shared)
5943 : {
5944 861 : tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
5945 861 : if (m == error_mark_node)
5946 : return error_mark_node;
5947 861 : if (!omp_private_member_map && !shared)
5948 365 : omp_private_member_map = new hash_map<tree, tree>;
5949 861 : if (TYPE_REF_P (TREE_TYPE (t)))
5950 : {
5951 123 : gcc_assert (INDIRECT_REF_P (m));
5952 123 : m = TREE_OPERAND (m, 0);
5953 : }
5954 861 : tree vb = NULL_TREE;
5955 861 : tree &v = shared ? vb : omp_private_member_map->get_or_insert (t);
5956 861 : if (v == NULL_TREE)
5957 : {
5958 770 : v = create_temporary_var (TREE_TYPE (m));
5959 770 : retrofit_lang_decl (v);
5960 770 : DECL_OMP_PRIVATIZED_MEMBER (v) = 1;
5961 770 : SET_DECL_VALUE_EXPR (v, m);
5962 770 : DECL_HAS_VALUE_EXPR_P (v) = 1;
5963 770 : if (!shared)
5964 690 : omp_private_member_vec.safe_push (t);
5965 : }
5966 861 : return v;
5967 : }
5968 :
5969 : /* C++ specialisation of the c_omp_address_inspector class. */
5970 :
5971 : class cp_omp_address_inspector : public c_omp_address_inspector
5972 : {
5973 : public:
5974 30551 : cp_omp_address_inspector (location_t loc, tree t)
5975 30551 : : c_omp_address_inspector (loc, t)
5976 : {
5977 : }
5978 :
5979 30551 : ~cp_omp_address_inspector ()
5980 : {
5981 22256 : }
5982 :
5983 129566 : bool processing_template_decl_p ()
5984 : {
5985 129566 : return processing_template_decl;
5986 : }
5987 :
5988 0 : void emit_unmappable_type_notes (tree t)
5989 : {
5990 0 : if (TREE_TYPE (t) != error_mark_node
5991 0 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
5992 0 : cxx_incomplete_type_inform (TREE_TYPE (t));
5993 0 : }
5994 :
5995 1058 : tree convert_from_reference (tree x)
5996 : {
5997 1058 : return ::convert_from_reference (x);
5998 : }
5999 :
6000 141 : tree build_array_ref (location_t loc, tree arr, tree idx)
6001 : {
6002 141 : return ::build_array_ref (loc, arr, idx);
6003 : }
6004 :
6005 22198 : bool check_clause (tree clause)
6006 : {
6007 22198 : if (TREE_CODE (orig) == COMPONENT_REF
6008 22198 : && invalid_nonstatic_memfn_p (EXPR_LOCATION (orig), orig,
6009 : tf_warning_or_error))
6010 : return false;
6011 22195 : if (!c_omp_address_inspector::check_clause (clause))
6012 : return false;
6013 : return true;
6014 : }
6015 : };
6016 :
6017 : /* Helper function for handle_omp_array_sections. Called recursively
6018 : to handle multiple array-section-subscripts. C is the clause,
6019 : T current expression (initially OMP_CLAUSE_DECL), which is either
6020 : a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound
6021 : expression if specified, TREE_VALUE length expression if specified,
6022 : TREE_CHAIN is what it has been specified after, or some decl.
6023 : TYPES vector is populated with array section types, MAYBE_ZERO_LEN
6024 : set to true if any of the array-section-subscript could have length
6025 : of zero (explicit or implicit), FIRST_NON_ONE is the index of the
6026 : first array-section-subscript which is known not to have length
6027 : of one. Given say:
6028 : map(a[:b][2:1][:c][:2][:d][e:f][2:5])
6029 : FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c]
6030 : all are or may have length of 1, array-section-subscript [:2] is the
6031 : first one known not to have length 1. For array-section-subscript
6032 : <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't
6033 : 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we
6034 : can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above
6035 : case though, as some lengths could be zero. */
6036 :
6037 : static tree
6038 20456 : handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
6039 : bool &maybe_zero_len, unsigned int &first_non_one,
6040 : enum c_omp_region_type ort)
6041 : {
6042 20456 : tree ret, low_bound, length, type;
6043 20456 : bool openacc = (ort & C_ORT_ACC) != 0;
6044 20456 : if (TREE_CODE (t) != OMP_ARRAY_SECTION)
6045 : {
6046 9270 : if (error_operand_p (t))
6047 6 : return error_mark_node;
6048 :
6049 9264 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6050 9264 : tree t_refto = ai.maybe_unconvert_ref (t);
6051 :
6052 9264 : if (!ai.check_clause (c))
6053 0 : return error_mark_node;
6054 9264 : else if (ai.component_access_p ()
6055 10652 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6056 64 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
6057 40 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
6058 1388 : t = ai.get_root_term (true);
6059 : else
6060 7876 : t = ai.unconverted_ref_origin ();
6061 9264 : if (t == error_mark_node)
6062 : return error_mark_node;
6063 9264 : ret = t_refto;
6064 9264 : if (TREE_CODE (t) == FIELD_DECL)
6065 33 : ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6066 9231 : else if (!VAR_P (t)
6067 2698 : && (openacc || !EXPR_P (t))
6068 2503 : && TREE_CODE (t) != PARM_DECL)
6069 : {
6070 48 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
6071 : return NULL_TREE;
6072 30 : if (DECL_P (t))
6073 30 : error_at (OMP_CLAUSE_LOCATION (c),
6074 : "%qD is not a variable in %qs clause", t,
6075 30 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6076 : else
6077 0 : error_at (OMP_CLAUSE_LOCATION (c),
6078 : "%qE is not a variable in %qs clause", t,
6079 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6080 30 : return error_mark_node;
6081 : }
6082 9183 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6083 8993 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6084 17249 : && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
6085 : {
6086 17 : error_at (OMP_CLAUSE_LOCATION (c),
6087 : "%qD is threadprivate variable in %qs clause", t,
6088 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6089 17 : return error_mark_node;
6090 : }
6091 9199 : if (type_dependent_expression_p (ret))
6092 : return NULL_TREE;
6093 8512 : ret = convert_from_reference (ret);
6094 8512 : return ret;
6095 9264 : }
6096 :
6097 11186 : if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
6098 7383 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6099 6189 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6100 4905 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6101 13792 : && TREE_CODE (TREE_OPERAND (t, 0)) == FIELD_DECL)
6102 43 : TREE_OPERAND (t, 0) = omp_privatize_field (TREE_OPERAND (t, 0), false);
6103 11186 : ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
6104 : maybe_zero_len, first_non_one, ort);
6105 11186 : if (ret == error_mark_node || ret == NULL_TREE)
6106 : return ret;
6107 :
6108 10182 : type = TREE_TYPE (ret);
6109 10182 : low_bound = TREE_OPERAND (t, 1);
6110 10182 : length = TREE_OPERAND (t, 2);
6111 8235 : if ((low_bound && type_dependent_expression_p (low_bound))
6112 18334 : || (length && type_dependent_expression_p (length)))
6113 88 : return NULL_TREE;
6114 :
6115 10094 : if (low_bound == error_mark_node || length == error_mark_node)
6116 : return error_mark_node;
6117 :
6118 10094 : if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound)))
6119 : {
6120 69 : error_at (OMP_CLAUSE_LOCATION (c),
6121 : "low bound %qE of array section does not have integral type",
6122 : low_bound);
6123 69 : return error_mark_node;
6124 : }
6125 10025 : if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length)))
6126 : {
6127 63 : error_at (OMP_CLAUSE_LOCATION (c),
6128 : "length %qE of array section does not have integral type",
6129 : length);
6130 63 : return error_mark_node;
6131 : }
6132 9962 : if (low_bound)
6133 8069 : low_bound = mark_rvalue_use (low_bound);
6134 9962 : if (length)
6135 9016 : length = mark_rvalue_use (length);
6136 : /* We need to reduce to real constant-values for checks below. */
6137 9016 : if (length)
6138 9016 : length = fold_simple (length);
6139 9962 : if (low_bound)
6140 8069 : low_bound = fold_simple (low_bound);
6141 8069 : if (low_bound
6142 8069 : && TREE_CODE (low_bound) == INTEGER_CST
6143 15213 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6144 7144 : > TYPE_PRECISION (sizetype))
6145 0 : low_bound = fold_convert (sizetype, low_bound);
6146 9962 : if (length
6147 9016 : && TREE_CODE (length) == INTEGER_CST
6148 16967 : && TYPE_PRECISION (TREE_TYPE (length))
6149 7005 : > TYPE_PRECISION (sizetype))
6150 0 : length = fold_convert (sizetype, length);
6151 9962 : if (low_bound == NULL_TREE)
6152 1893 : low_bound = integer_zero_node;
6153 :
6154 9962 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6155 9962 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
6156 5079 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
6157 : {
6158 60 : if (length != integer_one_node)
6159 : {
6160 36 : error_at (OMP_CLAUSE_LOCATION (c),
6161 : "expected single pointer in %qs clause",
6162 : user_omp_clause_code_name (c, openacc));
6163 36 : return error_mark_node;
6164 : }
6165 : }
6166 9926 : if (length != NULL_TREE)
6167 : {
6168 9004 : if (!integer_nonzerop (length))
6169 : {
6170 2058 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6171 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6172 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6173 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6174 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6175 : {
6176 459 : if (integer_zerop (length))
6177 : {
6178 28 : error_at (OMP_CLAUSE_LOCATION (c),
6179 : "zero length array section in %qs clause",
6180 28 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6181 28 : return error_mark_node;
6182 : }
6183 : }
6184 : else
6185 1599 : maybe_zero_len = true;
6186 : }
6187 8976 : if (first_non_one == types.length ()
6188 8976 : && (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
6189 3926 : first_non_one++;
6190 : }
6191 9898 : if (TREE_CODE (type) == ARRAY_TYPE)
6192 : {
6193 5461 : if (length == NULL_TREE
6194 5461 : && (TYPE_DOMAIN (type) == NULL_TREE
6195 850 : || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE))
6196 : {
6197 30 : error_at (OMP_CLAUSE_LOCATION (c),
6198 : "for unknown bound array type length expression must "
6199 : "be specified");
6200 30 : return error_mark_node;
6201 : }
6202 5431 : if (TREE_CODE (low_bound) == INTEGER_CST
6203 5431 : && tree_int_cst_sgn (low_bound) == -1)
6204 : {
6205 153 : error_at (OMP_CLAUSE_LOCATION (c),
6206 : "negative low bound in array section in %qs clause",
6207 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6208 153 : return error_mark_node;
6209 : }
6210 5278 : if (length != NULL_TREE
6211 4476 : && TREE_CODE (length) == INTEGER_CST
6212 8836 : && tree_int_cst_sgn (length) == -1)
6213 : {
6214 153 : error_at (OMP_CLAUSE_LOCATION (c),
6215 : "negative length in array section in %qs clause",
6216 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6217 153 : return error_mark_node;
6218 : }
6219 5125 : if (TYPE_DOMAIN (type)
6220 5031 : && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
6221 10156 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
6222 : == INTEGER_CST)
6223 : {
6224 4635 : tree size
6225 4635 : = fold_convert (sizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
6226 4635 : size = size_binop (PLUS_EXPR, size, size_one_node);
6227 4635 : if (TREE_CODE (low_bound) == INTEGER_CST)
6228 : {
6229 3868 : if (tree_int_cst_lt (size, low_bound))
6230 : {
6231 54 : error_at (OMP_CLAUSE_LOCATION (c),
6232 : "low bound %qE above array section size "
6233 : "in %qs clause", low_bound,
6234 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6235 54 : return error_mark_node;
6236 : }
6237 3814 : if (tree_int_cst_equal (size, low_bound))
6238 : {
6239 17 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6240 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6241 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6242 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6243 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6244 : {
6245 17 : error_at (OMP_CLAUSE_LOCATION (c),
6246 : "zero length array section in %qs clause",
6247 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6248 17 : return error_mark_node;
6249 : }
6250 0 : maybe_zero_len = true;
6251 : }
6252 3797 : else if (length == NULL_TREE
6253 1420 : && first_non_one == types.length ()
6254 4095 : && tree_int_cst_equal
6255 298 : (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
6256 : low_bound))
6257 195 : first_non_one++;
6258 : }
6259 767 : else if (length == NULL_TREE)
6260 : {
6261 20 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6262 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6263 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6264 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6265 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6266 13 : maybe_zero_len = true;
6267 40 : if (first_non_one == types.length ())
6268 17 : first_non_one++;
6269 : }
6270 4564 : if (length && TREE_CODE (length) == INTEGER_CST)
6271 : {
6272 3290 : if (tree_int_cst_lt (size, length))
6273 : {
6274 57 : error_at (OMP_CLAUSE_LOCATION (c),
6275 : "length %qE above array section size "
6276 : "in %qs clause", length,
6277 57 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6278 57 : return error_mark_node;
6279 : }
6280 3233 : if (TREE_CODE (low_bound) == INTEGER_CST)
6281 : {
6282 2899 : tree lbpluslen
6283 2899 : = size_binop (PLUS_EXPR,
6284 : fold_convert (sizetype, low_bound),
6285 : fold_convert (sizetype, length));
6286 2899 : if (TREE_CODE (lbpluslen) == INTEGER_CST
6287 2899 : && tree_int_cst_lt (size, lbpluslen))
6288 : {
6289 54 : error_at (OMP_CLAUSE_LOCATION (c),
6290 : "high bound %qE above array section size "
6291 : "in %qs clause", lbpluslen,
6292 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6293 54 : return error_mark_node;
6294 : }
6295 : }
6296 : }
6297 : }
6298 490 : else if (length == NULL_TREE)
6299 : {
6300 1 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6301 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6302 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6303 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6304 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6305 0 : maybe_zero_len = true;
6306 2 : if (first_non_one == types.length ())
6307 1 : first_non_one++;
6308 : }
6309 :
6310 : /* For [lb:] we will need to evaluate lb more than once. */
6311 3911 : if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6312 : {
6313 650 : tree lb = cp_save_expr (low_bound);
6314 650 : if (lb != low_bound)
6315 : {
6316 9 : TREE_OPERAND (t, 1) = lb;
6317 9 : low_bound = lb;
6318 : }
6319 : }
6320 : }
6321 4437 : else if (TYPE_PTR_P (type))
6322 : {
6323 4380 : if (length == NULL_TREE)
6324 : {
6325 42 : if (TREE_CODE (ret) == PARM_DECL && DECL_ARRAY_PARAMETER_P (ret))
6326 36 : error_at (OMP_CLAUSE_LOCATION (c),
6327 : "for array function parameter length expression "
6328 : "must be specified");
6329 : else
6330 6 : error_at (OMP_CLAUSE_LOCATION (c),
6331 : "for pointer type length expression must be specified");
6332 42 : return error_mark_node;
6333 : }
6334 4338 : if (length != NULL_TREE
6335 4338 : && TREE_CODE (length) == INTEGER_CST
6336 3245 : && tree_int_cst_sgn (length) == -1)
6337 : {
6338 84 : error_at (OMP_CLAUSE_LOCATION (c),
6339 : "negative length in array section in %qs clause",
6340 84 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6341 84 : return error_mark_node;
6342 : }
6343 : /* If there is a pointer type anywhere but in the very first
6344 : array-section-subscript, the array section could be non-contiguous. */
6345 4254 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6346 4212 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6347 7983 : && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION)
6348 : {
6349 : /* If any prior dimension has a non-one length, then deem this
6350 : array section as non-contiguous. */
6351 158 : for (tree d = TREE_OPERAND (t, 0); TREE_CODE (d) == OMP_ARRAY_SECTION;
6352 69 : d = TREE_OPERAND (d, 0))
6353 : {
6354 89 : tree d_length = TREE_OPERAND (d, 2);
6355 89 : if (d_length == NULL_TREE || !integer_onep (d_length))
6356 : {
6357 20 : error_at (OMP_CLAUSE_LOCATION (c),
6358 : "array section is not contiguous in %qs clause",
6359 20 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6360 20 : return error_mark_node;
6361 : }
6362 : }
6363 : }
6364 : }
6365 : else
6366 : {
6367 57 : error_at (OMP_CLAUSE_LOCATION (c),
6368 : "%qE does not have pointer or array type", ret);
6369 57 : return error_mark_node;
6370 : }
6371 9177 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6372 8274 : types.safe_push (TREE_TYPE (ret));
6373 : /* We will need to evaluate lb more than once. */
6374 9177 : tree lb = cp_save_expr (low_bound);
6375 9177 : if (lb != low_bound)
6376 : {
6377 716 : TREE_OPERAND (t, 1) = lb;
6378 716 : low_bound = lb;
6379 : }
6380 : /* Temporarily disable -fstrong-eval-order for array reductions.
6381 : The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects
6382 : is something the middle-end can't cope with and more importantly,
6383 : it needs to be the actual base variable that is privatized, not some
6384 : temporary assigned previous value of it. That, together with OpenMP
6385 : saying how many times the side-effects are evaluated is unspecified,
6386 : makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified. */
6387 9177 : warning_sentinel s (flag_strong_eval_order,
6388 9177 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6389 8164 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6390 18473 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION);
6391 9177 : ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, NULL,
6392 : tf_warning_or_error);
6393 9177 : return ret;
6394 9177 : }
6395 :
6396 : /* Handle array sections for clause C. */
6397 :
6398 : static bool
6399 9270 : handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
6400 : {
6401 9270 : bool maybe_zero_len = false;
6402 9270 : unsigned int first_non_one = 0;
6403 9270 : auto_vec<tree, 10> types;
6404 9270 : tree *tp = &OMP_CLAUSE_DECL (c);
6405 9270 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6406 8313 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6407 9476 : && OMP_ITERATOR_DECL_P (*tp))
6408 258 : tp = &TREE_VALUE (*tp);
6409 9270 : tree first = handle_omp_array_sections_1 (c, *tp, types,
6410 : maybe_zero_len, first_non_one,
6411 : ort);
6412 9270 : if (first == error_mark_node)
6413 : return true;
6414 8300 : if (first == NULL_TREE)
6415 : return false;
6416 7507 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6417 7507 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6418 : {
6419 849 : tree t = *tp;
6420 849 : tree tem = NULL_TREE;
6421 849 : if (processing_template_decl)
6422 : return false;
6423 : /* Need to evaluate side effects in the length expressions
6424 : if any. */
6425 750 : while (TREE_CODE (t) == TREE_LIST)
6426 : {
6427 0 : if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t)))
6428 : {
6429 0 : if (tem == NULL_TREE)
6430 : tem = TREE_VALUE (t);
6431 : else
6432 0 : tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem),
6433 0 : TREE_VALUE (t), tem);
6434 : }
6435 0 : t = TREE_CHAIN (t);
6436 : }
6437 750 : if (tem)
6438 0 : first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
6439 750 : *tp = first;
6440 : }
6441 : else
6442 : {
6443 6658 : unsigned int num = types.length (), i;
6444 6658 : tree t, side_effects = NULL_TREE, size = NULL_TREE;
6445 6658 : tree condition = NULL_TREE;
6446 :
6447 6658 : if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
6448 3 : maybe_zero_len = true;
6449 6658 : if (processing_template_decl && maybe_zero_len)
6450 : return false;
6451 :
6452 14006 : for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
6453 7426 : t = TREE_OPERAND (t, 0))
6454 : {
6455 7497 : gcc_assert (TREE_CODE (t) == OMP_ARRAY_SECTION);
6456 :
6457 7497 : tree low_bound = TREE_OPERAND (t, 1);
6458 7497 : tree length = TREE_OPERAND (t, 2);
6459 :
6460 7497 : i--;
6461 7497 : if (low_bound
6462 6114 : && TREE_CODE (low_bound) == INTEGER_CST
6463 13000 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6464 5503 : > TYPE_PRECISION (sizetype))
6465 0 : low_bound = fold_convert (sizetype, low_bound);
6466 7497 : if (length
6467 6978 : && TREE_CODE (length) == INTEGER_CST
6468 12583 : && TYPE_PRECISION (TREE_TYPE (length))
6469 5086 : > TYPE_PRECISION (sizetype))
6470 0 : length = fold_convert (sizetype, length);
6471 7497 : if (low_bound == NULL_TREE)
6472 1383 : low_bound = integer_zero_node;
6473 7497 : if (!maybe_zero_len && i > first_non_one)
6474 : {
6475 629 : if (integer_nonzerop (low_bound))
6476 34 : goto do_warn_noncontiguous;
6477 595 : if (length != NULL_TREE
6478 273 : && TREE_CODE (length) == INTEGER_CST
6479 273 : && TYPE_DOMAIN (types[i])
6480 273 : && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))
6481 868 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])))
6482 : == INTEGER_CST)
6483 : {
6484 273 : tree size;
6485 273 : size = size_binop (PLUS_EXPR,
6486 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6487 : size_one_node);
6488 273 : if (!tree_int_cst_equal (length, size))
6489 : {
6490 37 : do_warn_noncontiguous:
6491 142 : error_at (OMP_CLAUSE_LOCATION (c),
6492 : "array section is not contiguous in %qs "
6493 : "clause",
6494 71 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6495 71 : return true;
6496 : }
6497 : }
6498 558 : if (!processing_template_decl
6499 390 : && length != NULL_TREE
6500 723 : && TREE_SIDE_EFFECTS (length))
6501 : {
6502 0 : if (side_effects == NULL_TREE)
6503 : side_effects = length;
6504 : else
6505 0 : side_effects = build2 (COMPOUND_EXPR,
6506 0 : TREE_TYPE (side_effects),
6507 : length, side_effects);
6508 : }
6509 : }
6510 6868 : else if (processing_template_decl)
6511 698 : continue;
6512 : else
6513 : {
6514 6170 : tree l;
6515 :
6516 6170 : if (i > first_non_one
6517 6170 : && ((length && integer_nonzerop (length))
6518 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6519 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6520 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION))
6521 0 : continue;
6522 6170 : if (length)
6523 6053 : l = fold_convert (sizetype, length);
6524 : else
6525 : {
6526 117 : l = size_binop (PLUS_EXPR,
6527 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6528 : size_one_node);
6529 117 : l = size_binop (MINUS_EXPR, l,
6530 : fold_convert (sizetype, low_bound));
6531 : }
6532 6170 : if (i > first_non_one)
6533 : {
6534 0 : l = fold_build2 (NE_EXPR, boolean_type_node, l,
6535 : size_zero_node);
6536 0 : if (condition == NULL_TREE)
6537 : condition = l;
6538 : else
6539 0 : condition = fold_build2 (BIT_AND_EXPR, boolean_type_node,
6540 : l, condition);
6541 : }
6542 6170 : else if (size == NULL_TREE)
6543 : {
6544 5892 : size = size_in_bytes (TREE_TYPE (types[i]));
6545 5892 : tree eltype = TREE_TYPE (types[num - 1]);
6546 5961 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6547 69 : eltype = TREE_TYPE (eltype);
6548 5892 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6549 5142 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6550 10281 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6551 1599 : size = size_binop (EXACT_DIV_EXPR, size,
6552 : size_in_bytes (eltype));
6553 5892 : size = size_binop (MULT_EXPR, size, l);
6554 5892 : if (condition)
6555 0 : size = fold_build3 (COND_EXPR, sizetype, condition,
6556 : size, size_zero_node);
6557 : }
6558 : else
6559 278 : size = size_binop (MULT_EXPR, size, l);
6560 : }
6561 : }
6562 6509 : if (!processing_template_decl)
6563 : {
6564 5892 : if (side_effects)
6565 0 : size = build2 (COMPOUND_EXPR, sizetype, side_effects, size);
6566 5892 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6567 5142 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6568 10281 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6569 : {
6570 1599 : size = size_binop (MINUS_EXPR, size, size_one_node);
6571 1599 : size = save_expr (size);
6572 1599 : tree index_type = build_index_type (size);
6573 1599 : tree eltype = TREE_TYPE (first);
6574 1628 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6575 29 : eltype = TREE_TYPE (eltype);
6576 1599 : tree type = build_array_type (eltype, index_type);
6577 1599 : tree ptype = build_pointer_type (eltype);
6578 1599 : if (TYPE_REF_P (TREE_TYPE (t))
6579 1599 : && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
6580 152 : t = convert_from_reference (t);
6581 1447 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6582 629 : t = build_fold_addr_expr (t);
6583 1599 : tree t2 = build_fold_addr_expr (first);
6584 1599 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6585 : ptrdiff_type_node, t2);
6586 1599 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
6587 : ptrdiff_type_node, t2,
6588 1599 : fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6589 : ptrdiff_type_node, t));
6590 1599 : if (tree_fits_shwi_p (t2))
6591 1261 : t = build2 (MEM_REF, type, t,
6592 1261 : build_int_cst (ptype, tree_to_shwi (t2)));
6593 : else
6594 : {
6595 338 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6596 : sizetype, t2);
6597 338 : t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR,
6598 338 : TREE_TYPE (t), t, t2);
6599 338 : t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
6600 : }
6601 1599 : OMP_CLAUSE_DECL (c) = t;
6602 7491 : return false;
6603 : }
6604 4293 : OMP_CLAUSE_DECL (c) = first;
6605 4293 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
6606 : return false;
6607 4267 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
6608 4267 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
6609 3727 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
6610 3715 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH))
6611 4243 : OMP_CLAUSE_SIZE (c) = size;
6612 4267 : if (TREE_CODE (t) == FIELD_DECL)
6613 3 : t = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6614 :
6615 4267 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
6616 : return false;
6617 :
6618 3739 : if (TREE_CODE (first) == INDIRECT_REF)
6619 : {
6620 : /* Detect and skip adding extra nodes for pointer-to-member
6621 : mappings. These are unsupported for now. */
6622 2404 : tree tmp = TREE_OPERAND (first, 0);
6623 :
6624 2404 : if (TREE_CODE (tmp) == NON_LVALUE_EXPR)
6625 1911 : tmp = TREE_OPERAND (tmp, 0);
6626 :
6627 2404 : if (TREE_CODE (tmp) == INDIRECT_REF)
6628 158 : tmp = TREE_OPERAND (tmp, 0);
6629 :
6630 2404 : if (TREE_CODE (tmp) == POINTER_PLUS_EXPR)
6631 : {
6632 463 : tree offset = TREE_OPERAND (tmp, 1);
6633 463 : STRIP_NOPS (offset);
6634 463 : if (TYPE_PTRMEM_P (TREE_TYPE (offset)))
6635 : {
6636 36 : sorry_at (OMP_CLAUSE_LOCATION (c),
6637 : "pointer-to-member mapping %qE not supported",
6638 18 : OMP_CLAUSE_DECL (c));
6639 18 : return true;
6640 : }
6641 : }
6642 : }
6643 :
6644 : /* FIRST represents the first item of data that we are mapping.
6645 : E.g. if we're mapping an array, FIRST might resemble
6646 : "foo.bar.myarray[0]". */
6647 :
6648 3721 : auto_vec<omp_addr_token *, 10> addr_tokens;
6649 :
6650 3721 : if (!omp_parse_expr (addr_tokens, first))
6651 : return true;
6652 :
6653 3721 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6654 :
6655 3721 : tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
6656 3721 : if (nc != error_mark_node)
6657 : {
6658 3721 : using namespace omp_addr_tokenizer;
6659 :
6660 3721 : if (ai.maybe_zero_length_array_section (c))
6661 3697 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
6662 :
6663 : /* !!! If we're accessing a base decl via chained access
6664 : methods (e.g. multiple indirections), duplicate clause
6665 : detection won't work properly. Skip it in that case. */
6666 3721 : if ((addr_tokens[0]->type == STRUCTURE_BASE
6667 2704 : || addr_tokens[0]->type == ARRAY_BASE)
6668 3721 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
6669 3710 : && addr_tokens[1]->type == ACCESS_METHOD
6670 7431 : && omp_access_chain_p (addr_tokens, 1))
6671 216 : c = nc;
6672 :
6673 3721 : return false;
6674 : }
6675 7442 : }
6676 : }
6677 : return false;
6678 9270 : }
6679 :
6680 : /* Return identifier to look up for omp declare reduction. */
6681 :
6682 : tree
6683 7085 : omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type)
6684 : {
6685 7085 : const char *p = NULL;
6686 7085 : const char *m = NULL;
6687 7085 : switch (reduction_code)
6688 : {
6689 4188 : case PLUS_EXPR:
6690 4188 : case MULT_EXPR:
6691 4188 : case MINUS_EXPR:
6692 4188 : case BIT_AND_EXPR:
6693 4188 : case BIT_XOR_EXPR:
6694 4188 : case BIT_IOR_EXPR:
6695 4188 : case TRUTH_ANDIF_EXPR:
6696 4188 : case TRUTH_ORIF_EXPR:
6697 4188 : reduction_id = ovl_op_identifier (false, reduction_code);
6698 4188 : break;
6699 : case MIN_EXPR:
6700 : p = "min";
6701 : break;
6702 : case MAX_EXPR:
6703 : p = "max";
6704 : break;
6705 : default:
6706 : break;
6707 : }
6708 :
6709 4188 : if (p == NULL)
6710 : {
6711 6921 : if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
6712 0 : return error_mark_node;
6713 6921 : p = IDENTIFIER_POINTER (reduction_id);
6714 : }
6715 :
6716 7085 : if (type != NULL_TREE)
6717 2033 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6718 :
6719 7085 : const char prefix[] = "omp declare reduction ";
6720 7085 : size_t lenp = sizeof (prefix);
6721 7085 : if (strncmp (p, prefix, lenp - 1) == 0)
6722 2033 : lenp = 1;
6723 7085 : size_t len = strlen (p);
6724 7085 : size_t lenm = m ? strlen (m) + 1 : 0;
6725 7085 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6726 7085 : if (lenp > 1)
6727 5052 : memcpy (name, prefix, lenp - 1);
6728 7085 : memcpy (name + lenp - 1, p, len + 1);
6729 7085 : if (m)
6730 : {
6731 2033 : name[lenp + len - 1] = '~';
6732 2033 : memcpy (name + lenp + len, m, lenm);
6733 : }
6734 7085 : return get_identifier (name);
6735 : }
6736 :
6737 : /* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial
6738 : FUNCTION_DECL or NULL_TREE if not found. */
6739 :
6740 : static tree
6741 1288 : omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
6742 : vec<tree> *ambiguousp)
6743 : {
6744 1288 : tree orig_id = id;
6745 1288 : tree baselink = NULL_TREE;
6746 1288 : if (identifier_p (id))
6747 : {
6748 1260 : cp_id_kind idk;
6749 1260 : bool nonint_cst_expression_p;
6750 1260 : const char *error_msg;
6751 1260 : id = omp_reduction_id (ERROR_MARK, id, type);
6752 1260 : tree decl = lookup_name (id);
6753 1260 : if (decl == NULL_TREE)
6754 80 : decl = error_mark_node;
6755 1260 : id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
6756 : &nonint_cst_expression_p, false, true, false,
6757 : false, &error_msg, loc);
6758 1260 : if (idk == CP_ID_KIND_UNQUALIFIED
6759 1340 : && identifier_p (id))
6760 : {
6761 80 : vec<tree, va_gc> *args = NULL;
6762 80 : vec_safe_push (args, build_reference_type (type));
6763 80 : id = perform_koenig_lookup (id, args, tf_none);
6764 : }
6765 : }
6766 28 : else if (TREE_CODE (id) == SCOPE_REF)
6767 28 : id = lookup_qualified_name (TREE_OPERAND (id, 0),
6768 : omp_reduction_id (ERROR_MARK,
6769 28 : TREE_OPERAND (id, 1),
6770 : type),
6771 : LOOK_want::NORMAL, false);
6772 1288 : tree fns = id;
6773 1288 : id = NULL_TREE;
6774 1288 : if (fns && is_overloaded_fn (fns))
6775 : {
6776 1214 : for (lkp_iterator iter (get_fns (fns)); iter; ++iter)
6777 : {
6778 1214 : tree fndecl = *iter;
6779 1214 : if (TREE_CODE (fndecl) == FUNCTION_DECL)
6780 : {
6781 1214 : tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
6782 1214 : if (same_type_p (TREE_TYPE (argtype), type))
6783 : {
6784 1214 : id = fndecl;
6785 1214 : break;
6786 : }
6787 : }
6788 : }
6789 :
6790 1214 : if (id && BASELINK_P (fns))
6791 : {
6792 74 : if (baselinkp)
6793 0 : *baselinkp = fns;
6794 : else
6795 74 : baselink = fns;
6796 : }
6797 : }
6798 :
6799 1288 : if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type))
6800 : {
6801 35 : auto_vec<tree> ambiguous;
6802 35 : tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
6803 35 : unsigned int ix;
6804 35 : if (ambiguousp == NULL)
6805 19 : ambiguousp = &ambiguous;
6806 73 : for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
6807 : {
6808 52 : id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo),
6809 : baselinkp ? baselinkp : &baselink,
6810 : ambiguousp);
6811 38 : if (id == NULL_TREE)
6812 14 : continue;
6813 24 : if (!ambiguousp->is_empty ())
6814 3 : ambiguousp->safe_push (id);
6815 21 : else if (ret != NULL_TREE)
6816 : {
6817 6 : ambiguousp->safe_push (ret);
6818 6 : ambiguousp->safe_push (id);
6819 6 : ret = NULL_TREE;
6820 : }
6821 : else
6822 15 : ret = id;
6823 : }
6824 35 : if (ambiguousp != &ambiguous)
6825 16 : return ret;
6826 19 : if (!ambiguous.is_empty ())
6827 : {
6828 6 : auto_diagnostic_group d;
6829 6 : const char *str = _("candidates are:");
6830 6 : unsigned int idx;
6831 6 : tree udr;
6832 6 : error_at (loc, "user defined reduction lookup is ambiguous");
6833 27 : FOR_EACH_VEC_ELT (ambiguous, idx, udr)
6834 : {
6835 15 : inform (DECL_SOURCE_LOCATION (udr), "%s %#qD", str, udr);
6836 15 : if (idx == 0)
6837 6 : str = get_spaces (str);
6838 : }
6839 6 : ret = error_mark_node;
6840 6 : baselink = NULL_TREE;
6841 6 : }
6842 19 : id = ret;
6843 35 : }
6844 1272 : if (id && baselink)
6845 74 : perform_or_defer_access_check (BASELINK_BINFO (baselink),
6846 : id, id, tf_warning_or_error);
6847 : return id;
6848 : }
6849 :
6850 : /* Return identifier to look up for omp declare mapper. */
6851 :
6852 : tree
6853 3868 : omp_mapper_id (tree mapper_id, tree type)
6854 : {
6855 3868 : const char *p = NULL;
6856 3868 : const char *m = NULL;
6857 :
6858 3868 : if (mapper_id == NULL_TREE)
6859 : p = "";
6860 68 : else if (TREE_CODE (mapper_id) == IDENTIFIER_NODE)
6861 68 : p = IDENTIFIER_POINTER (mapper_id);
6862 : else
6863 0 : return error_mark_node;
6864 :
6865 3868 : if (type != NULL_TREE)
6866 3866 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6867 :
6868 3868 : const char prefix[] = "omp declare mapper ";
6869 3868 : size_t lenp = sizeof (prefix);
6870 3868 : if (strncmp (p, prefix, lenp - 1) == 0)
6871 2 : lenp = 1;
6872 3868 : size_t len = strlen (p);
6873 3868 : size_t lenm = m ? strlen (m) + 1 : 0;
6874 3868 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6875 3868 : memcpy (name, prefix, lenp - 1);
6876 3868 : memcpy (name + lenp - 1, p, len + 1);
6877 3868 : if (m)
6878 : {
6879 3866 : name[lenp + len - 1] = '~';
6880 3866 : memcpy (name + lenp + len, m, lenm);
6881 : }
6882 3868 : return get_identifier (name);
6883 : }
6884 :
6885 : tree
6886 6947 : cxx_omp_mapper_lookup (tree id, tree type)
6887 : {
6888 6947 : if (!RECORD_OR_UNION_TYPE_P (type))
6889 : return NULL_TREE;
6890 3655 : id = omp_mapper_id (id, type);
6891 3655 : return lookup_name (id);
6892 : }
6893 :
6894 : tree
6895 273 : cxx_omp_extract_mapper_directive (tree vardecl)
6896 : {
6897 273 : gcc_assert (TREE_CODE (vardecl) == VAR_DECL);
6898 :
6899 : /* Instantiate the decl if we haven't already. */
6900 273 : mark_used (vardecl);
6901 273 : tree body = DECL_INITIAL (vardecl);
6902 :
6903 273 : if (TREE_CODE (body) == STATEMENT_LIST)
6904 : {
6905 0 : tree_stmt_iterator tsi = tsi_start (body);
6906 0 : gcc_assert (TREE_CODE (tsi_stmt (tsi)) == DECL_EXPR);
6907 0 : tsi_next (&tsi);
6908 0 : body = tsi_stmt (tsi);
6909 : }
6910 :
6911 273 : gcc_assert (TREE_CODE (body) == OMP_DECLARE_MAPPER);
6912 :
6913 273 : return body;
6914 : }
6915 :
6916 : /* For now we can handle singleton OMP_ARRAY_SECTIONs with custom mappers, but
6917 : nothing more complicated. */
6918 :
6919 : tree
6920 1510 : cxx_omp_map_array_section (location_t loc, tree t)
6921 : {
6922 1510 : tree low = TREE_OPERAND (t, 1);
6923 1510 : tree len = TREE_OPERAND (t, 2);
6924 :
6925 1510 : if (len && integer_onep (len))
6926 : {
6927 237 : t = TREE_OPERAND (t, 0);
6928 :
6929 237 : if (!low)
6930 9 : low = integer_zero_node;
6931 :
6932 237 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
6933 5 : t = convert_from_reference (t);
6934 :
6935 237 : t = build_array_ref (loc, t, low);
6936 : }
6937 :
6938 1510 : return t;
6939 : }
6940 :
6941 : /* Helper function for cp_parser_omp_declare_reduction_exprs
6942 : and tsubst_omp_udr.
6943 : Remove CLEANUP_STMT for data (omp_priv variable).
6944 : Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
6945 : DECL_EXPR. */
6946 :
6947 : tree
6948 4395 : cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data)
6949 : {
6950 4395 : if (TYPE_P (*tp))
6951 227 : *walk_subtrees = 0;
6952 4168 : else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data)
6953 52 : *tp = CLEANUP_BODY (*tp);
6954 4116 : else if (TREE_CODE (*tp) == DECL_EXPR)
6955 : {
6956 307 : tree decl = DECL_EXPR_DECL (*tp);
6957 307 : if (!processing_template_decl
6958 258 : && decl == (tree) data
6959 258 : && DECL_INITIAL (decl)
6960 399 : && DECL_INITIAL (decl) != error_mark_node)
6961 : {
6962 92 : tree list = NULL_TREE;
6963 92 : append_to_statement_list_force (*tp, &list);
6964 92 : tree init_expr = build2 (INIT_EXPR, void_type_node,
6965 92 : decl, DECL_INITIAL (decl));
6966 92 : DECL_INITIAL (decl) = NULL_TREE;
6967 92 : append_to_statement_list_force (init_expr, &list);
6968 92 : *tp = list;
6969 : }
6970 : }
6971 4395 : return NULL_TREE;
6972 : }
6973 :
6974 : /* Data passed from cp_check_omp_declare_reduction to
6975 : cp_check_omp_declare_reduction_r. */
6976 :
6977 : struct cp_check_omp_declare_reduction_data
6978 : {
6979 : location_t loc;
6980 : tree stmts[7];
6981 : bool combiner_p;
6982 : };
6983 :
6984 : /* Helper function for cp_check_omp_declare_reduction, called via
6985 : cp_walk_tree. */
6986 :
6987 : static tree
6988 14952 : cp_check_omp_declare_reduction_r (tree *tp, int *, void *data)
6989 : {
6990 14952 : struct cp_check_omp_declare_reduction_data *udr_data
6991 : = (struct cp_check_omp_declare_reduction_data *) data;
6992 14952 : if (SSA_VAR_P (*tp)
6993 2687 : && !DECL_ARTIFICIAL (*tp)
6994 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3])
6995 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4]))
6996 : {
6997 135 : location_t loc = udr_data->loc;
6998 135 : if (udr_data->combiner_p)
6999 45 : error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
7000 : "variable %qD which is not %<omp_out%> nor %<omp_in%>",
7001 : *tp);
7002 : else
7003 90 : error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
7004 : "to variable %qD which is not %<omp_priv%> nor "
7005 : "%<omp_orig%>",
7006 : *tp);
7007 135 : return *tp;
7008 : }
7009 : return NULL_TREE;
7010 : }
7011 :
7012 : /* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */
7013 :
7014 : bool
7015 1100 : cp_check_omp_declare_reduction (tree udr)
7016 : {
7017 1100 : tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
7018 1100 : gcc_assert (TYPE_REF_P (type));
7019 1100 : type = TREE_TYPE (type);
7020 1100 : int i;
7021 1100 : location_t loc = DECL_SOURCE_LOCATION (udr);
7022 :
7023 1100 : if (type == error_mark_node)
7024 : return false;
7025 1100 : if (ARITHMETIC_TYPE_P (type))
7026 : {
7027 : static enum tree_code predef_codes[]
7028 : = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR,
7029 : BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR };
7030 3276 : for (i = 0; i < 8; i++)
7031 : {
7032 2918 : tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE);
7033 2918 : const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr));
7034 2918 : const char *n2 = IDENTIFIER_POINTER (id);
7035 2918 : if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0
7036 2918 : && (n1[IDENTIFIER_LENGTH (id)] == '~'
7037 0 : || n1[IDENTIFIER_LENGTH (id)] == '\0'))
7038 : break;
7039 : }
7040 :
7041 376 : if (i == 8
7042 358 : && TREE_CODE (type) != COMPLEX_EXPR)
7043 : {
7044 358 : const char prefix_minmax[] = "omp declare reduction m";
7045 358 : size_t prefix_size = sizeof (prefix_minmax) - 1;
7046 358 : const char *n = IDENTIFIER_POINTER (DECL_NAME (udr));
7047 358 : if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)),
7048 : prefix_minmax, prefix_size) == 0
7049 10 : && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n')
7050 4 : || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x'))
7051 368 : && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0'))
7052 6 : i = 0;
7053 : }
7054 376 : if (i < 8)
7055 : {
7056 24 : error_at (loc, "predeclared arithmetic type %qT in "
7057 : "%<#pragma omp declare reduction%>", type);
7058 24 : return false;
7059 : }
7060 : }
7061 : else if (FUNC_OR_METHOD_TYPE_P (type)
7062 : || TREE_CODE (type) == ARRAY_TYPE)
7063 : {
7064 24 : error_at (loc, "function or array type %qT in "
7065 : "%<#pragma omp declare reduction%>", type);
7066 24 : return false;
7067 : }
7068 : else if (TYPE_REF_P (type))
7069 : {
7070 0 : error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
7071 : type);
7072 0 : return false;
7073 : }
7074 700 : else if (TYPE_QUALS_NO_ADDR_SPACE (type))
7075 : {
7076 24 : error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
7077 : "type %qT in %<#pragma omp declare reduction%>", type);
7078 24 : return false;
7079 : }
7080 :
7081 1028 : tree body = DECL_SAVED_TREE (udr);
7082 1028 : if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST)
7083 : return true;
7084 :
7085 842 : tree_stmt_iterator tsi;
7086 842 : struct cp_check_omp_declare_reduction_data data;
7087 842 : memset (data.stmts, 0, sizeof data.stmts);
7088 842 : for (i = 0, tsi = tsi_start (body);
7089 4679 : i < 7 && !tsi_end_p (tsi);
7090 3837 : i++, tsi_next (&tsi))
7091 3837 : data.stmts[i] = tsi_stmt (tsi);
7092 842 : data.loc = loc;
7093 842 : gcc_assert (tsi_end_p (tsi));
7094 842 : if (i >= 3)
7095 : {
7096 842 : gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
7097 : && TREE_CODE (data.stmts[1]) == DECL_EXPR);
7098 842 : if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */))
7099 : return true;
7100 797 : data.combiner_p = true;
7101 797 : if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
7102 : &data, NULL))
7103 45 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */);
7104 : }
7105 797 : if (i >= 6)
7106 : {
7107 336 : gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR
7108 : && TREE_CODE (data.stmts[4]) == DECL_EXPR);
7109 336 : data.combiner_p = false;
7110 336 : if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r,
7111 : &data, NULL)
7112 336 : || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
7113 : cp_check_omp_declare_reduction_r, &data, NULL))
7114 90 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */);
7115 336 : if (i == 7)
7116 198 : gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
7117 : }
7118 : return true;
7119 : }
7120 :
7121 : /* Helper function of finish_omp_clauses. Clone STMT as if we were making
7122 : an inline call. But, remap
7123 : the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER
7124 : and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */
7125 :
7126 : static tree
7127 2198 : clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
7128 : tree decl, tree placeholder)
7129 : {
7130 2198 : copy_body_data id;
7131 2198 : hash_map<tree, tree> decl_map;
7132 :
7133 2198 : decl_map.put (omp_decl1, placeholder);
7134 2198 : decl_map.put (omp_decl2, decl);
7135 2198 : memset (&id, 0, sizeof (id));
7136 2198 : id.src_fn = DECL_CONTEXT (omp_decl1);
7137 2198 : id.dst_fn = current_function_decl;
7138 2198 : id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
7139 2198 : id.decl_map = &decl_map;
7140 :
7141 2198 : id.copy_decl = copy_decl_no_change;
7142 2198 : id.transform_call_graph_edges = CB_CGE_DUPLICATE;
7143 2198 : id.transform_new_cfg = true;
7144 2198 : id.transform_return_to_modify = false;
7145 2198 : id.eh_lp_nr = 0;
7146 2198 : walk_tree (&stmt, copy_tree_body_r, &id, NULL);
7147 2198 : return stmt;
7148 2198 : }
7149 :
7150 : /* Helper function of finish_omp_clauses, called via cp_walk_tree.
7151 : Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */
7152 :
7153 : static tree
7154 15438 : find_omp_placeholder_r (tree *tp, int *, void *data)
7155 : {
7156 15438 : if (*tp == (tree) data)
7157 265 : return *tp;
7158 : return NULL_TREE;
7159 : }
7160 :
7161 : /* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C.
7162 : Return true if there is some error and the clause should be removed. */
7163 :
7164 : static bool
7165 8855 : finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
7166 : {
7167 8855 : tree t = OMP_CLAUSE_DECL (c);
7168 8855 : bool predefined = false;
7169 8855 : if (TREE_CODE (t) == TREE_LIST)
7170 : {
7171 0 : gcc_assert (processing_template_decl);
7172 : return false;
7173 : }
7174 8855 : tree type = TREE_TYPE (t);
7175 8855 : if (TREE_CODE (t) == MEM_REF)
7176 1596 : type = TREE_TYPE (type);
7177 8855 : if (TYPE_REF_P (type))
7178 527 : type = TREE_TYPE (type);
7179 8855 : if (TREE_CODE (type) == ARRAY_TYPE)
7180 : {
7181 350 : tree oatype = type;
7182 350 : gcc_assert (TREE_CODE (t) != MEM_REF);
7183 703 : while (TREE_CODE (type) == ARRAY_TYPE)
7184 353 : type = TREE_TYPE (type);
7185 350 : if (!processing_template_decl)
7186 : {
7187 255 : t = require_complete_type (t);
7188 255 : if (t == error_mark_node
7189 255 : || !complete_type_or_else (oatype, NULL_TREE))
7190 9 : return true;
7191 246 : tree size = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (oatype),
7192 : TYPE_SIZE_UNIT (type));
7193 246 : if (integer_zerop (size))
7194 : {
7195 6 : error_at (OMP_CLAUSE_LOCATION (c),
7196 : "%qE in %<reduction%> clause is a zero size array",
7197 : omp_clause_printable_decl (t));
7198 3 : return true;
7199 : }
7200 243 : size = size_binop (MINUS_EXPR, size, size_one_node);
7201 243 : size = save_expr (size);
7202 243 : tree index_type = build_index_type (size);
7203 243 : tree atype = build_array_type (type, index_type);
7204 243 : tree ptype = build_pointer_type (type);
7205 243 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7206 146 : t = build_fold_addr_expr (t);
7207 243 : t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0));
7208 243 : OMP_CLAUSE_DECL (c) = t;
7209 : }
7210 : }
7211 8843 : if (type == error_mark_node)
7212 : return true;
7213 8840 : else if (ARITHMETIC_TYPE_P (type))
7214 7590 : switch (OMP_CLAUSE_REDUCTION_CODE (c))
7215 : {
7216 : case PLUS_EXPR:
7217 : case MULT_EXPR:
7218 : case MINUS_EXPR:
7219 : case TRUTH_ANDIF_EXPR:
7220 : case TRUTH_ORIF_EXPR:
7221 : predefined = true;
7222 : break;
7223 246 : case MIN_EXPR:
7224 246 : case MAX_EXPR:
7225 246 : if (TREE_CODE (type) == COMPLEX_TYPE)
7226 : break;
7227 : predefined = true;
7228 : break;
7229 111 : case BIT_AND_EXPR:
7230 111 : case BIT_IOR_EXPR:
7231 111 : case BIT_XOR_EXPR:
7232 111 : if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
7233 : break;
7234 : predefined = true;
7235 : break;
7236 : default:
7237 : break;
7238 : }
7239 1250 : else if (TYPE_READONLY (type))
7240 : {
7241 18 : error_at (OMP_CLAUSE_LOCATION (c),
7242 : "%qE has const type for %<reduction%>",
7243 : omp_clause_printable_decl (t));
7244 9 : return true;
7245 : }
7246 1241 : else if (!processing_template_decl)
7247 : {
7248 1037 : t = require_complete_type (t);
7249 1037 : if (t == error_mark_node)
7250 : return true;
7251 1037 : OMP_CLAUSE_DECL (c) = t;
7252 : }
7253 :
7254 1037 : if (predefined)
7255 : {
7256 7368 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7257 7368 : return false;
7258 : }
7259 1463 : else if (processing_template_decl)
7260 : {
7261 213 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
7262 : return true;
7263 : return false;
7264 : }
7265 :
7266 1250 : tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
7267 :
7268 1250 : type = TYPE_MAIN_VARIANT (type);
7269 1250 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7270 1250 : if (id == NULL_TREE)
7271 924 : id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c),
7272 : NULL_TREE, NULL_TREE);
7273 1250 : id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL);
7274 1250 : if (id)
7275 : {
7276 1205 : if (id == error_mark_node)
7277 : return true;
7278 1199 : mark_used (id);
7279 1199 : tree body = DECL_SAVED_TREE (id);
7280 1199 : if (!body)
7281 : return true;
7282 1196 : if (TREE_CODE (body) == STATEMENT_LIST)
7283 : {
7284 1196 : tree_stmt_iterator tsi;
7285 1196 : tree placeholder = NULL_TREE, decl_placeholder = NULL_TREE;
7286 1196 : int i;
7287 1196 : tree stmts[7];
7288 1196 : tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id)));
7289 1196 : atype = TREE_TYPE (atype);
7290 1196 : bool need_static_cast = !same_type_p (type, atype);
7291 1196 : memset (stmts, 0, sizeof stmts);
7292 1196 : for (i = 0, tsi = tsi_start (body);
7293 8518 : i < 7 && !tsi_end_p (tsi);
7294 7322 : i++, tsi_next (&tsi))
7295 7322 : stmts[i] = tsi_stmt (tsi);
7296 1196 : gcc_assert (tsi_end_p (tsi));
7297 :
7298 1196 : if (i >= 3)
7299 : {
7300 1196 : gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
7301 : && TREE_CODE (stmts[1]) == DECL_EXPR);
7302 1196 : placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type);
7303 1196 : DECL_ARTIFICIAL (placeholder) = 1;
7304 1196 : DECL_IGNORED_P (placeholder) = 1;
7305 1196 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder;
7306 1196 : if (TREE_CODE (t) == MEM_REF)
7307 : {
7308 600 : decl_placeholder = build_lang_decl (VAR_DECL, NULL_TREE,
7309 : type);
7310 600 : DECL_ARTIFICIAL (decl_placeholder) = 1;
7311 600 : DECL_IGNORED_P (decl_placeholder) = 1;
7312 600 : OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = decl_placeholder;
7313 : }
7314 1196 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
7315 285 : cxx_mark_addressable (placeholder);
7316 1196 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
7317 1196 : && (decl_placeholder
7318 149 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7319 372 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7320 118 : : OMP_CLAUSE_DECL (c));
7321 1196 : tree omp_out = placeholder;
7322 1196 : tree omp_in = decl_placeholder ? decl_placeholder
7323 596 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7324 1196 : if (need_static_cast)
7325 : {
7326 7 : tree rtype = build_reference_type (atype);
7327 7 : omp_out = build_static_cast (input_location,
7328 : rtype, omp_out,
7329 : tf_warning_or_error);
7330 7 : omp_in = build_static_cast (input_location,
7331 : rtype, omp_in,
7332 : tf_warning_or_error);
7333 7 : if (omp_out == error_mark_node || omp_in == error_mark_node)
7334 3 : return true;
7335 7 : omp_out = convert_from_reference (omp_out);
7336 7 : omp_in = convert_from_reference (omp_in);
7337 : }
7338 1196 : OMP_CLAUSE_REDUCTION_MERGE (c)
7339 1196 : = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]),
7340 1196 : DECL_EXPR_DECL (stmts[1]), omp_in, omp_out);
7341 : }
7342 1196 : if (i >= 6)
7343 : {
7344 1005 : gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
7345 : && TREE_CODE (stmts[4]) == DECL_EXPR);
7346 1005 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3]))
7347 1005 : && (decl_placeholder
7348 232 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7349 844 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7350 170 : : OMP_CLAUSE_DECL (c));
7351 1005 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
7352 216 : cxx_mark_addressable (placeholder);
7353 1005 : tree omp_priv = decl_placeholder ? decl_placeholder
7354 429 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7355 1005 : tree omp_orig = placeholder;
7356 1005 : if (need_static_cast)
7357 : {
7358 5 : if (i == 7)
7359 : {
7360 3 : error_at (OMP_CLAUSE_LOCATION (c),
7361 : "user defined reduction with constructor "
7362 : "initializer for base class %qT", atype);
7363 3 : return true;
7364 : }
7365 2 : tree rtype = build_reference_type (atype);
7366 2 : omp_priv = build_static_cast (input_location,
7367 : rtype, omp_priv,
7368 : tf_warning_or_error);
7369 2 : omp_orig = build_static_cast (input_location,
7370 : rtype, omp_orig,
7371 : tf_warning_or_error);
7372 2 : if (omp_priv == error_mark_node
7373 2 : || omp_orig == error_mark_node)
7374 : return true;
7375 2 : omp_priv = convert_from_reference (omp_priv);
7376 2 : omp_orig = convert_from_reference (omp_orig);
7377 : }
7378 1002 : if (i == 6)
7379 286 : *need_default_ctor = true;
7380 1002 : OMP_CLAUSE_REDUCTION_INIT (c)
7381 1002 : = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]),
7382 1002 : DECL_EXPR_DECL (stmts[3]),
7383 : omp_priv, omp_orig);
7384 1002 : if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7385 : find_omp_placeholder_r, placeholder, NULL))
7386 238 : OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
7387 : }
7388 191 : else if (i >= 3)
7389 : {
7390 191 : if (CLASS_TYPE_P (type) && !pod_type_p (type))
7391 175 : *need_default_ctor = true;
7392 : else
7393 : {
7394 16 : tree init;
7395 16 : tree v = decl_placeholder ? decl_placeholder
7396 16 : : convert_from_reference (t);
7397 16 : if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
7398 7 : init = build_constructor (TREE_TYPE (v), NULL);
7399 : else
7400 9 : init = fold_convert (TREE_TYPE (v), integer_zero_node);
7401 32 : OMP_CLAUSE_REDUCTION_INIT (c)
7402 32 : = cp_build_init_expr (v, init);
7403 : }
7404 : }
7405 : }
7406 : }
7407 1238 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7408 1193 : *need_dtor = true;
7409 : else
7410 : {
7411 90 : error_at (OMP_CLAUSE_LOCATION (c),
7412 : "user defined reduction not found for %qE",
7413 : omp_clause_printable_decl (t));
7414 45 : return true;
7415 : }
7416 1193 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
7417 600 : gcc_assert (TYPE_SIZE_UNIT (type)
7418 : && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
7419 : return false;
7420 : }
7421 :
7422 : /* Check an instance of an "omp declare mapper" function. */
7423 :
7424 : bool
7425 179 : cp_check_omp_declare_mapper (tree udm)
7426 : {
7427 179 : tree type = TREE_TYPE (udm);
7428 179 : location_t loc = DECL_SOURCE_LOCATION (udm);
7429 :
7430 179 : if (type == error_mark_node)
7431 : return false;
7432 :
7433 179 : if (!processing_template_decl && !RECORD_OR_UNION_TYPE_P (type))
7434 : {
7435 15 : error_at (loc, "%qT is not a struct, union or class type in "
7436 : "%<#pragma omp declare mapper%>", type);
7437 15 : return false;
7438 : }
7439 164 : if (!processing_template_decl && CLASSTYPE_VBASECLASSES (type))
7440 : {
7441 3 : error_at (loc, "%qT must not be a virtual base class in "
7442 : "%<#pragma omp declare mapper%>", type);
7443 3 : return false;
7444 : }
7445 :
7446 : return true;
7447 : }
7448 :
7449 : /* Called from finish_struct_1. linear(this) or linear(this:step)
7450 : clauses might not be finalized yet because the class has been incomplete
7451 : when parsing #pragma omp declare simd methods. Fix those up now. */
7452 :
7453 : void
7454 117856 : finish_omp_declare_simd_methods (tree t)
7455 : {
7456 117856 : if (processing_template_decl)
7457 : return;
7458 :
7459 804087 : for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
7460 : {
7461 1135523 : if (TREE_CODE (x) == USING_DECL
7462 686231 : || !DECL_IOBJ_MEMBER_FUNCTION_P (x))
7463 449292 : continue;
7464 236939 : tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x));
7465 237047 : if (!ods || !TREE_VALUE (ods))
7466 236831 : continue;
7467 366 : for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c))
7468 258 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7469 66 : && integer_zerop (OMP_CLAUSE_DECL (c))
7470 18 : && OMP_CLAUSE_LINEAR_STEP (c)
7471 276 : && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c))))
7472 : {
7473 18 : tree s = OMP_CLAUSE_LINEAR_STEP (c);
7474 18 : s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
7475 18 : s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
7476 18 : sizetype, s, TYPE_SIZE_UNIT (t));
7477 18 : OMP_CLAUSE_LINEAR_STEP (c) = s;
7478 : }
7479 : }
7480 : }
7481 :
7482 : /* Adjust sink depend/doacross clause to take into account pointer offsets.
7483 :
7484 : Return TRUE if there was a problem processing the offset, and the
7485 : whole clause should be removed. */
7486 :
7487 : static bool
7488 298 : cp_finish_omp_clause_doacross_sink (tree sink_clause)
7489 : {
7490 298 : tree t = OMP_CLAUSE_DECL (sink_clause);
7491 298 : gcc_assert (TREE_CODE (t) == TREE_LIST);
7492 :
7493 : /* Make sure we don't adjust things twice for templates. */
7494 298 : if (processing_template_decl)
7495 : return false;
7496 :
7497 671 : for (; t; t = TREE_CHAIN (t))
7498 : {
7499 391 : tree decl = TREE_VALUE (t);
7500 391 : if (TYPE_PTR_P (TREE_TYPE (decl)))
7501 : {
7502 6 : tree offset = TREE_PURPOSE (t);
7503 6 : bool neg = wi::neg_p (wi::to_wide (offset));
7504 6 : offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset);
7505 6 : decl = mark_rvalue_use (decl);
7506 6 : decl = convert_from_reference (decl);
7507 12 : tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause),
7508 : neg ? MINUS_EXPR : PLUS_EXPR,
7509 : decl, offset);
7510 6 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
7511 : MINUS_EXPR, sizetype,
7512 : fold_convert (sizetype, t2),
7513 : fold_convert (sizetype, decl));
7514 6 : if (t2 == error_mark_node)
7515 : return true;
7516 6 : TREE_PURPOSE (t) = t2;
7517 : }
7518 : }
7519 : return false;
7520 : }
7521 :
7522 : /* Finish OpenMP iterators ITER. Return true if they are errorneous
7523 : and clauses containing them should be removed. */
7524 :
7525 : static bool
7526 610 : cp_omp_finish_iterators (tree iter)
7527 : {
7528 610 : bool ret = false;
7529 1385 : for (tree it = iter; it; it = TREE_CHAIN (it))
7530 : {
7531 775 : tree var = TREE_VEC_ELT (it, 0);
7532 775 : tree begin = TREE_VEC_ELT (it, 1);
7533 775 : tree end = TREE_VEC_ELT (it, 2);
7534 775 : tree step = TREE_VEC_ELT (it, 3);
7535 775 : tree orig_step;
7536 775 : tree type = TREE_TYPE (var);
7537 775 : location_t loc = DECL_SOURCE_LOCATION (var);
7538 775 : if (type == error_mark_node)
7539 : {
7540 0 : ret = true;
7541 218 : continue;
7542 : }
7543 775 : if (type_dependent_expression_p (var))
7544 59 : continue;
7545 716 : if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
7546 : {
7547 27 : error_at (loc, "iterator %qD has neither integral nor pointer type",
7548 : var);
7549 27 : ret = true;
7550 27 : continue;
7551 : }
7552 689 : else if (TYPE_READONLY (type))
7553 : {
7554 24 : error_at (loc, "iterator %qD has const qualified type", var);
7555 24 : ret = true;
7556 24 : continue;
7557 : }
7558 665 : if (type_dependent_expression_p (begin)
7559 656 : || type_dependent_expression_p (end)
7560 1321 : || type_dependent_expression_p (step))
7561 15 : continue;
7562 650 : else if (error_operand_p (step))
7563 : {
7564 0 : ret = true;
7565 0 : continue;
7566 : }
7567 650 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
7568 : {
7569 33 : error_at (EXPR_LOC_OR_LOC (step, loc),
7570 : "iterator step with non-integral type");
7571 21 : ret = true;
7572 21 : continue;
7573 : }
7574 :
7575 629 : begin = mark_rvalue_use (begin);
7576 629 : end = mark_rvalue_use (end);
7577 629 : step = mark_rvalue_use (step);
7578 629 : begin = cp_build_c_cast (input_location, type, begin,
7579 : tf_warning_or_error);
7580 629 : end = cp_build_c_cast (input_location, type, end,
7581 : tf_warning_or_error);
7582 629 : orig_step = step;
7583 629 : if (!processing_template_decl)
7584 552 : step = orig_step = save_expr (step);
7585 629 : tree stype = POINTER_TYPE_P (type) ? sizetype : type;
7586 629 : step = cp_build_c_cast (input_location, stype, step,
7587 : tf_warning_or_error);
7588 629 : if (POINTER_TYPE_P (type) && !processing_template_decl)
7589 : {
7590 66 : begin = save_expr (begin);
7591 66 : step = pointer_int_sum (loc, PLUS_EXPR, begin, step);
7592 66 : step = fold_build2_loc (loc, MINUS_EXPR, sizetype,
7593 : fold_convert (sizetype, step),
7594 : fold_convert (sizetype, begin));
7595 66 : step = fold_convert (ssizetype, step);
7596 : }
7597 629 : if (!processing_template_decl)
7598 : {
7599 552 : begin = maybe_constant_value (begin);
7600 552 : end = maybe_constant_value (end);
7601 552 : step = maybe_constant_value (step);
7602 552 : orig_step = maybe_constant_value (orig_step);
7603 : }
7604 629 : if (integer_zerop (step))
7605 : {
7606 27 : error_at (loc, "iterator %qD has zero step", var);
7607 27 : ret = true;
7608 27 : continue;
7609 : }
7610 :
7611 602 : if (begin == error_mark_node
7612 593 : || end == error_mark_node
7613 584 : || step == error_mark_node
7614 584 : || orig_step == error_mark_node)
7615 : {
7616 18 : ret = true;
7617 18 : continue;
7618 : }
7619 :
7620 584 : if (!processing_template_decl)
7621 : {
7622 507 : begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin);
7623 507 : end = fold_build_cleanup_point_expr (TREE_TYPE (end), end);
7624 507 : step = fold_build_cleanup_point_expr (TREE_TYPE (step), step);
7625 507 : orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step),
7626 : orig_step);
7627 : }
7628 584 : hash_set<tree> pset;
7629 584 : tree it2;
7630 740 : for (it2 = TREE_CHAIN (it); it2; it2 = TREE_CHAIN (it2))
7631 : {
7632 183 : tree var2 = TREE_VEC_ELT (it2, 0);
7633 183 : tree begin2 = TREE_VEC_ELT (it2, 1);
7634 183 : tree end2 = TREE_VEC_ELT (it2, 2);
7635 183 : tree step2 = TREE_VEC_ELT (it2, 3);
7636 183 : location_t loc2 = DECL_SOURCE_LOCATION (var2);
7637 183 : if (cp_walk_tree (&begin2, find_omp_placeholder_r, var, &pset))
7638 : {
7639 9 : error_at (EXPR_LOC_OR_LOC (begin2, loc2),
7640 : "begin expression refers to outer iterator %qD", var);
7641 36 : break;
7642 : }
7643 174 : else if (cp_walk_tree (&end2, find_omp_placeholder_r, var, &pset))
7644 : {
7645 9 : error_at (EXPR_LOC_OR_LOC (end2, loc2),
7646 : "end expression refers to outer iterator %qD", var);
7647 9 : break;
7648 : }
7649 165 : else if (cp_walk_tree (&step2, find_omp_placeholder_r, var, &pset))
7650 : {
7651 9 : error_at (EXPR_LOC_OR_LOC (step2, loc2),
7652 : "step expression refers to outer iterator %qD", var);
7653 9 : break;
7654 : }
7655 : }
7656 584 : if (it2)
7657 : {
7658 27 : ret = true;
7659 27 : continue;
7660 : }
7661 557 : TREE_VEC_ELT (it, 1) = begin;
7662 557 : TREE_VEC_ELT (it, 2) = end;
7663 557 : if (processing_template_decl)
7664 71 : TREE_VEC_ELT (it, 3) = orig_step;
7665 : else
7666 : {
7667 486 : TREE_VEC_ELT (it, 3) = step;
7668 486 : TREE_VEC_ELT (it, 4) = orig_step;
7669 : }
7670 584 : }
7671 610 : return ret;
7672 : }
7673 :
7674 : /* Ensure that pointers are used in OpenACC attach and detach clauses.
7675 : Return true if an error has been detected. */
7676 :
7677 : static bool
7678 18298 : cp_oacc_check_attachments (tree c)
7679 : {
7680 18298 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
7681 : return false;
7682 :
7683 : /* OpenACC attach / detach clauses must be pointers. */
7684 14403 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
7685 14403 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
7686 : {
7687 196 : tree t = OMP_CLAUSE_DECL (c);
7688 196 : tree type;
7689 :
7690 232 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7691 36 : t = TREE_OPERAND (t, 0);
7692 :
7693 196 : type = TREE_TYPE (t);
7694 :
7695 196 : if (TREE_CODE (type) == REFERENCE_TYPE)
7696 36 : type = TREE_TYPE (type);
7697 :
7698 196 : if (TREE_CODE (type) != POINTER_TYPE)
7699 : {
7700 36 : error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause",
7701 : user_omp_clause_code_name (c, true));
7702 36 : return true;
7703 : }
7704 : }
7705 :
7706 : return false;
7707 : }
7708 :
7709 : /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution
7710 : happened. */
7711 :
7712 : tree
7713 813 : cp_finish_omp_init_prefer_type (tree pref_type)
7714 : {
7715 813 : if (processing_template_decl
7716 741 : || pref_type == NULL_TREE
7717 356 : || TREE_CODE (pref_type) != TREE_LIST)
7718 : return pref_type;
7719 :
7720 81 : tree t = TREE_PURPOSE (pref_type);
7721 81 : char *str = const_cast<char *> (TREE_STRING_POINTER (t));
7722 81 : tree fr_list = TREE_VALUE (pref_type);
7723 81 : int len = TREE_VEC_LENGTH (fr_list);
7724 81 : int cnt = 0;
7725 :
7726 270 : while (str[0] == (char) GOMP_INTEROP_IFR_SEPARATOR)
7727 : {
7728 270 : str++;
7729 270 : if (str[0] == (char) GOMP_INTEROP_IFR_UNKNOWN)
7730 : {
7731 : /* Assume a no or a single 'fr'. */
7732 150 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7733 150 : location_t loc = UNKNOWN_LOCATION;
7734 150 : tree value = TREE_VEC_ELT (fr_list, cnt);
7735 150 : if (value != NULL_TREE && value != error_mark_node)
7736 : {
7737 126 : loc = EXPR_LOCATION (value);
7738 126 : if (value && TREE_CODE (value) == NOP_EXPR)
7739 39 : value = TREE_OPERAND (value, 0);
7740 126 : value = cp_fully_fold (value);
7741 : }
7742 126 : if (value != NULL_TREE && value != error_mark_node)
7743 : {
7744 126 : if (TREE_CODE (value) != INTEGER_CST
7745 126 : || !tree_fits_shwi_p (value))
7746 0 : error_at (loc,
7747 : "expected string literal or "
7748 : "constant integer expression instead of %qE", value);
7749 : else
7750 : {
7751 126 : HOST_WIDE_INT n = tree_to_shwi (value);
7752 126 : if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
7753 : {
7754 48 : warning_at (loc, OPT_Wopenmp,
7755 : "unknown foreign runtime identifier %qwd", n);
7756 48 : n = GOMP_INTEROP_IFR_UNKNOWN;
7757 : }
7758 126 : str[0] = (char) n;
7759 : }
7760 : }
7761 150 : str++;
7762 : }
7763 120 : else if (str[0] != (char) GOMP_INTEROP_IFR_SEPARATOR)
7764 : {
7765 : /* Assume a no or a single 'fr'. */
7766 120 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7767 120 : str++;
7768 : }
7769 270 : str++;
7770 294 : while (str[0] != '\0')
7771 24 : str += strlen (str) + 1;
7772 270 : str++;
7773 270 : cnt++;
7774 270 : if (cnt >= len)
7775 : break;
7776 : }
7777 : return t;
7778 : }
7779 :
7780 : /* For all elements of CLAUSES, validate them vs OpenMP constraints.
7781 : Remove any elements from the list that are invalid. */
7782 :
7783 : tree
7784 62504 : finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
7785 : {
7786 62504 : bitmap_head generic_head, firstprivate_head, lastprivate_head;
7787 62504 : bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head;
7788 62504 : bitmap_head oacc_reduction_head, is_on_device_head;
7789 62504 : tree c, t, *pc;
7790 62504 : tree safelen = NULL_TREE;
7791 62504 : bool openacc = (ort & C_ORT_ACC) != 0;
7792 62504 : bool branch_seen = false;
7793 62504 : bool copyprivate_seen = false;
7794 62504 : bool ordered_seen = false;
7795 62504 : bool order_seen = false;
7796 62504 : bool schedule_seen = false;
7797 62504 : bool oacc_async = false;
7798 62504 : bool indir_component_ref_p = false;
7799 62504 : tree last_iterators = NULL_TREE;
7800 62504 : bool last_iterators_remove = false;
7801 : /* 1 if normal/task reduction has been seen, -1 if inscan reduction
7802 : has been seen, -2 if mixed inscan/normal reduction diagnosed. */
7803 62504 : int reduction_seen = 0;
7804 62504 : bool allocate_seen = false;
7805 62504 : tree detach_seen = NULL_TREE;
7806 62504 : bool mergeable_seen = false;
7807 62504 : bool implicit_moved = false;
7808 62504 : bool target_in_reduction_seen = false;
7809 62504 : bool num_tasks_seen = false;
7810 62504 : bool partial_seen = false;
7811 62504 : bool init_seen = false;
7812 62504 : bool init_use_destroy_seen = false;
7813 62504 : tree init_no_targetsync_clause = NULL_TREE;
7814 62504 : tree depend_clause = NULL_TREE;
7815 :
7816 62504 : bitmap_obstack_initialize (NULL);
7817 62504 : bitmap_initialize (&generic_head, &bitmap_default_obstack);
7818 62504 : bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
7819 62504 : bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
7820 62504 : bitmap_initialize (&aligned_head, &bitmap_default_obstack);
7821 : /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
7822 62504 : bitmap_initialize (&map_head, &bitmap_default_obstack);
7823 62504 : bitmap_initialize (&map_field_head, &bitmap_default_obstack);
7824 62504 : bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack);
7825 : /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
7826 : instead and for ort == C_ORT_OMP_TARGET used as in_reduction_head. */
7827 62504 : bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
7828 62504 : bitmap_initialize (&is_on_device_head, &bitmap_default_obstack);
7829 :
7830 62504 : if (openacc)
7831 28277 : for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
7832 15933 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
7833 : {
7834 : oacc_async = true;
7835 : break;
7836 : }
7837 :
7838 62504 : tree *grp_start_p = NULL, grp_sentinel = NULL_TREE;
7839 :
7840 160097 : for (pc = &clauses, c = clauses; c ; c = *pc)
7841 : {
7842 97593 : bool remove = false;
7843 97593 : bool field_ok = false;
7844 :
7845 : /* We've reached the end of a list of expanded nodes. Reset the group
7846 : start pointer. */
7847 97593 : if (c == grp_sentinel)
7848 : {
7849 5481 : if (grp_start_p
7850 5481 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
7851 96 : for (tree gc = *grp_start_p; gc != grp_sentinel;
7852 66 : gc = OMP_CLAUSE_CHAIN (gc))
7853 66 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
7854 : grp_start_p = NULL;
7855 : }
7856 :
7857 97593 : switch (OMP_CLAUSE_CODE (c))
7858 : {
7859 2100 : case OMP_CLAUSE_SHARED:
7860 2100 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7861 2100 : goto check_dup_generic;
7862 2576 : case OMP_CLAUSE_PRIVATE:
7863 2576 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7864 2576 : goto check_dup_generic;
7865 7337 : case OMP_CLAUSE_REDUCTION:
7866 7337 : if (reduction_seen == 0)
7867 6233 : reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
7868 1104 : else if (reduction_seen != -2
7869 2208 : && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
7870 1104 : ? -1 : 1))
7871 : {
7872 6 : error_at (OMP_CLAUSE_LOCATION (c),
7873 : "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
7874 : "on the same construct");
7875 6 : reduction_seen = -2;
7876 : }
7877 : /* FALLTHRU */
7878 9482 : case OMP_CLAUSE_IN_REDUCTION:
7879 9482 : case OMP_CLAUSE_TASK_REDUCTION:
7880 9482 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7881 9482 : t = OMP_CLAUSE_DECL (c);
7882 9482 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
7883 : {
7884 2207 : if (handle_omp_array_sections (c, ort))
7885 : {
7886 : remove = true;
7887 : break;
7888 : }
7889 2165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
7890 2165 : && OMP_CLAUSE_REDUCTION_INSCAN (c))
7891 : {
7892 3 : error_at (OMP_CLAUSE_LOCATION (c),
7893 : "%<inscan%> %<reduction%> clause with array "
7894 : "section");
7895 3 : remove = true;
7896 3 : break;
7897 : }
7898 2162 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
7899 : {
7900 4672 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7901 2510 : t = TREE_OPERAND (t, 0);
7902 : }
7903 : else
7904 : {
7905 0 : gcc_assert (TREE_CODE (t) == MEM_REF);
7906 0 : t = TREE_OPERAND (t, 0);
7907 0 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
7908 0 : t = TREE_OPERAND (t, 0);
7909 0 : if (TREE_CODE (t) == ADDR_EXPR
7910 0 : || INDIRECT_REF_P (t))
7911 0 : t = TREE_OPERAND (t, 0);
7912 : }
7913 2162 : tree n = omp_clause_decl_field (t);
7914 2162 : if (n)
7915 59 : t = n;
7916 2162 : goto check_dup_generic_t;
7917 : }
7918 7275 : if (oacc_async)
7919 7 : cxx_mark_addressable (t);
7920 7275 : goto check_dup_generic;
7921 98 : case OMP_CLAUSE_COPYPRIVATE:
7922 98 : copyprivate_seen = true;
7923 98 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7924 98 : goto check_dup_generic;
7925 277 : case OMP_CLAUSE_COPYIN:
7926 277 : goto check_dup_generic;
7927 1631 : case OMP_CLAUSE_LINEAR:
7928 1631 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7929 1631 : t = OMP_CLAUSE_DECL (c);
7930 1631 : if (ort != C_ORT_OMP_DECLARE_SIMD
7931 1631 : && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
7932 : {
7933 84 : if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
7934 : {
7935 42 : error_at (OMP_CLAUSE_LOCATION (c),
7936 : "modifier should not be specified in %<linear%> "
7937 : "clause on %<simd%> or %<for%> constructs when "
7938 : "not using OpenMP 5.2 modifiers");
7939 42 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
7940 : }
7941 42 : else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_VAL)
7942 : {
7943 18 : error_at (OMP_CLAUSE_LOCATION (c),
7944 : "modifier other than %<val%> specified in "
7945 : "%<linear%> clause on %<simd%> or %<for%> "
7946 : "constructs when using OpenMP 5.2 modifiers");
7947 18 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
7948 : }
7949 : }
7950 1011 : if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
7951 2571 : && !type_dependent_expression_p (t))
7952 : {
7953 1529 : tree type = TREE_TYPE (t);
7954 1529 : if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
7955 1448 : || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL)
7956 1598 : && !TYPE_REF_P (type))
7957 : {
7958 12 : error_at (OMP_CLAUSE_LOCATION (c),
7959 : "linear clause with %qs modifier applied to "
7960 : "non-reference variable with %qT type",
7961 12 : OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
7962 12 : ? "ref" : "uval", TREE_TYPE (t));
7963 12 : remove = true;
7964 12 : break;
7965 : }
7966 1517 : if (TYPE_REF_P (type))
7967 281 : type = TREE_TYPE (type);
7968 1517 : if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
7969 : {
7970 1442 : if (!INTEGRAL_TYPE_P (type)
7971 85 : && !TYPE_PTR_P (type))
7972 : {
7973 18 : error_at (OMP_CLAUSE_LOCATION (c),
7974 : "linear clause applied to non-integral "
7975 : "non-pointer variable with %qT type",
7976 18 : TREE_TYPE (t));
7977 18 : remove = true;
7978 18 : break;
7979 : }
7980 : }
7981 : }
7982 1601 : t = OMP_CLAUSE_LINEAR_STEP (c);
7983 1601 : if (t == NULL_TREE)
7984 6 : t = integer_one_node;
7985 1601 : if (t == error_mark_node)
7986 : {
7987 : remove = true;
7988 : break;
7989 : }
7990 1601 : else if (!type_dependent_expression_p (t)
7991 1599 : && !INTEGRAL_TYPE_P (TREE_TYPE (t))
7992 1613 : && (ort != C_ORT_OMP_DECLARE_SIMD
7993 9 : || TREE_CODE (t) != PARM_DECL
7994 6 : || !TYPE_REF_P (TREE_TYPE (t))
7995 6 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
7996 : {
7997 6 : error_at (OMP_CLAUSE_LOCATION (c),
7998 : "linear step expression must be integral");
7999 6 : remove = true;
8000 6 : break;
8001 : }
8002 : else
8003 : {
8004 1595 : t = mark_rvalue_use (t);
8005 1595 : if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL)
8006 : {
8007 42 : OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
8008 42 : goto check_dup_generic;
8009 : }
8010 1553 : if (!processing_template_decl
8011 1553 : && (VAR_P (OMP_CLAUSE_DECL (c))
8012 835 : || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
8013 : {
8014 1372 : if (ort == C_ORT_OMP_DECLARE_SIMD)
8015 : {
8016 589 : t = maybe_constant_value (t);
8017 589 : if (TREE_CODE (t) != INTEGER_CST)
8018 : {
8019 6 : error_at (OMP_CLAUSE_LOCATION (c),
8020 : "%<linear%> clause step %qE is neither "
8021 : "constant nor a parameter", t);
8022 6 : remove = true;
8023 6 : break;
8024 : }
8025 : }
8026 1366 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8027 1366 : tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
8028 1366 : if (TYPE_REF_P (type))
8029 257 : type = TREE_TYPE (type);
8030 1366 : if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
8031 : {
8032 66 : type = build_pointer_type (type);
8033 66 : tree d = fold_convert (type, OMP_CLAUSE_DECL (c));
8034 66 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8035 : d, t);
8036 66 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8037 : MINUS_EXPR, sizetype,
8038 : fold_convert (sizetype, t),
8039 : fold_convert (sizetype, d));
8040 66 : if (t == error_mark_node)
8041 : {
8042 : remove = true;
8043 : break;
8044 : }
8045 : }
8046 1300 : else if (TYPE_PTR_P (type)
8047 : /* Can't multiply the step yet if *this
8048 : is still incomplete type. */
8049 1300 : && (ort != C_ORT_OMP_DECLARE_SIMD
8050 45 : || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
8051 45 : || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
8052 30 : || DECL_NAME (OMP_CLAUSE_DECL (c))
8053 30 : != this_identifier
8054 30 : || !TYPE_BEING_DEFINED (TREE_TYPE (type))))
8055 : {
8056 37 : tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
8057 37 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8058 : d, t);
8059 37 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8060 : MINUS_EXPR, sizetype,
8061 : fold_convert (sizetype, t),
8062 : fold_convert (sizetype, d));
8063 37 : if (t == error_mark_node)
8064 : {
8065 : remove = true;
8066 : break;
8067 : }
8068 : }
8069 : else
8070 1263 : t = fold_convert (type, t);
8071 : }
8072 1547 : OMP_CLAUSE_LINEAR_STEP (c) = t;
8073 : }
8074 1547 : goto check_dup_generic;
8075 14881 : check_dup_generic:
8076 14881 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8077 14881 : if (t)
8078 : {
8079 101 : if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED)
8080 101 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8081 : }
8082 : else
8083 14780 : t = OMP_CLAUSE_DECL (c);
8084 17310 : check_dup_generic_t:
8085 17310 : if (t == current_class_ptr
8086 17310 : && ((ort != C_ORT_OMP_DECLARE_SIMD && !openacc)
8087 102 : || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
8088 72 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
8089 : {
8090 24 : error_at (OMP_CLAUSE_LOCATION (c),
8091 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8092 : " clauses");
8093 24 : remove = true;
8094 24 : break;
8095 : }
8096 17286 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8097 586 : && (!field_ok || TREE_CODE (t) != FIELD_DECL))
8098 : {
8099 59 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8100 : break;
8101 39 : if (DECL_P (t))
8102 30 : error_at (OMP_CLAUSE_LOCATION (c),
8103 : "%qD is not a variable in clause %qs", t,
8104 15 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8105 : else
8106 48 : error_at (OMP_CLAUSE_LOCATION (c),
8107 : "%qE is not a variable in clause %qs", t,
8108 24 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8109 : remove = true;
8110 : }
8111 17227 : else if ((openacc
8112 2707 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
8113 14758 : || (ort == C_ORT_OMP
8114 12427 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
8115 12396 : || (OMP_CLAUSE_CODE (c)
8116 : == OMP_CLAUSE_USE_DEVICE_ADDR)))
8117 31878 : || (ort == C_ORT_OMP_TARGET
8118 936 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION))
8119 : {
8120 2854 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8121 2854 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8122 275 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))))
8123 : {
8124 6 : error_at (OMP_CLAUSE_LOCATION (c),
8125 : "%qD appears more than once in data-sharing "
8126 : "clauses", t);
8127 6 : remove = true;
8128 6 : break;
8129 : }
8130 2848 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
8131 272 : target_in_reduction_seen = true;
8132 2848 : if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8133 : {
8134 12 : error_at (OMP_CLAUSE_LOCATION (c),
8135 : openacc
8136 : ? "%qD appears more than once in reduction clauses"
8137 : : "%qD appears more than once in data clauses",
8138 : t);
8139 6 : remove = true;
8140 : }
8141 : else
8142 2842 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8143 : }
8144 14373 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8145 14298 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8146 14295 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t))
8147 28668 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8148 : {
8149 78 : error_at (OMP_CLAUSE_LOCATION (c),
8150 : "%qD appears more than once in data clauses", t);
8151 78 : remove = true;
8152 : }
8153 14295 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
8154 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
8155 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
8156 3115 : && bitmap_bit_p (&map_head, DECL_UID (t)))
8157 : {
8158 9 : if (openacc)
8159 0 : error_at (OMP_CLAUSE_LOCATION (c),
8160 : "%qD appears more than once in data clauses", t);
8161 : else
8162 9 : error_at (OMP_CLAUSE_LOCATION (c),
8163 : "%qD appears both in data and map clauses", t);
8164 : remove = true;
8165 : }
8166 : else
8167 14286 : bitmap_set_bit (&generic_head, DECL_UID (t));
8168 17260 : if (!field_ok)
8169 : break;
8170 12852 : handle_field_decl:
8171 21366 : if (!remove
8172 21169 : && TREE_CODE (t) == FIELD_DECL
8173 16494 : && t == OMP_CLAUSE_DECL (c))
8174 : {
8175 795 : OMP_CLAUSE_DECL (c)
8176 795 : = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
8177 : == OMP_CLAUSE_SHARED));
8178 795 : if (OMP_CLAUSE_DECL (c) == error_mark_node)
8179 97092 : remove = true;
8180 : }
8181 : break;
8182 :
8183 3473 : case OMP_CLAUSE_FIRSTPRIVATE:
8184 3473 : if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved)
8185 : {
8186 447 : move_implicit:
8187 447 : implicit_moved = true;
8188 : /* Move firstprivate and map clauses with
8189 : OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of
8190 : clauses chain. */
8191 447 : tree cl1 = NULL_TREE, cl2 = NULL_TREE;
8192 447 : tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2;
8193 2804 : while (*pc1)
8194 2357 : if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE
8195 2357 : && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1))
8196 : {
8197 275 : *pc3 = *pc1;
8198 275 : pc3 = &OMP_CLAUSE_CHAIN (*pc3);
8199 275 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8200 : }
8201 2082 : else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP
8202 2082 : && OMP_CLAUSE_MAP_IMPLICIT (*pc1))
8203 : {
8204 403 : *pc2 = *pc1;
8205 403 : pc2 = &OMP_CLAUSE_CHAIN (*pc2);
8206 403 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8207 : }
8208 : else
8209 1679 : pc1 = &OMP_CLAUSE_CHAIN (*pc1);
8210 447 : *pc3 = NULL;
8211 447 : *pc2 = cl2;
8212 447 : *pc1 = cl1;
8213 447 : continue;
8214 447 : }
8215 3216 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8216 3216 : if (t)
8217 69 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8218 : else
8219 3147 : t = OMP_CLAUSE_DECL (c);
8220 3216 : if (!openacc && t == current_class_ptr)
8221 : {
8222 6 : error_at (OMP_CLAUSE_LOCATION (c),
8223 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8224 : " clauses");
8225 6 : remove = true;
8226 6 : break;
8227 : }
8228 3210 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8229 333 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8230 333 : || TREE_CODE (t) != FIELD_DECL))
8231 : {
8232 41 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8233 : break;
8234 18 : if (DECL_P (t))
8235 12 : error_at (OMP_CLAUSE_LOCATION (c),
8236 : "%qD is not a variable in clause %<firstprivate%>",
8237 : t);
8238 : else
8239 6 : error_at (OMP_CLAUSE_LOCATION (c),
8240 : "%qE is not a variable in clause %<firstprivate%>",
8241 : t);
8242 18 : remove = true;
8243 : }
8244 3169 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8245 275 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c)
8246 3423 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8247 : remove = true;
8248 3169 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8249 3160 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8250 6326 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8251 : {
8252 15 : error_at (OMP_CLAUSE_LOCATION (c),
8253 : "%qD appears more than once in data clauses", t);
8254 15 : remove = true;
8255 : }
8256 3154 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
8257 3154 : || bitmap_bit_p (&map_field_head, DECL_UID (t)))
8258 : {
8259 21 : if (openacc)
8260 0 : error_at (OMP_CLAUSE_LOCATION (c),
8261 : "%qD appears more than once in data clauses", t);
8262 21 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8263 21 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c))
8264 : /* Silently drop the clause. */;
8265 : else
8266 18 : error_at (OMP_CLAUSE_LOCATION (c),
8267 : "%qD appears both in data and map clauses", t);
8268 21 : remove = true;
8269 : }
8270 : else
8271 3133 : bitmap_set_bit (&firstprivate_head, DECL_UID (t));
8272 3187 : goto handle_field_decl;
8273 :
8274 2790 : case OMP_CLAUSE_LASTPRIVATE:
8275 2790 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8276 2790 : if (t)
8277 35 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8278 : else
8279 2755 : t = OMP_CLAUSE_DECL (c);
8280 2790 : if (!openacc && t == current_class_ptr)
8281 : {
8282 6 : error_at (OMP_CLAUSE_LOCATION (c),
8283 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8284 : " clauses");
8285 6 : remove = true;
8286 6 : break;
8287 : }
8288 2784 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8289 259 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8290 259 : || TREE_CODE (t) != FIELD_DECL))
8291 : {
8292 35 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8293 : break;
8294 9 : if (DECL_P (t))
8295 3 : error_at (OMP_CLAUSE_LOCATION (c),
8296 : "%qD is not a variable in clause %<lastprivate%>",
8297 : t);
8298 : else
8299 6 : error_at (OMP_CLAUSE_LOCATION (c),
8300 : "%qE is not a variable in clause %<lastprivate%>",
8301 : t);
8302 9 : remove = true;
8303 : }
8304 2749 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8305 2749 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8306 : {
8307 12 : error_at (OMP_CLAUSE_LOCATION (c),
8308 : "%qD appears more than once in data clauses", t);
8309 12 : remove = true;
8310 : }
8311 : else
8312 2737 : bitmap_set_bit (&lastprivate_head, DECL_UID (t));
8313 2758 : goto handle_field_decl;
8314 :
8315 2218 : case OMP_CLAUSE_IF:
8316 2218 : case OMP_CLAUSE_SELF:
8317 2218 : t = OMP_CLAUSE_OPERAND (c, 0);
8318 2218 : t = maybe_convert_cond (t);
8319 2218 : if (t == error_mark_node)
8320 : remove = true;
8321 2203 : else if (!processing_template_decl)
8322 2142 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8323 2218 : OMP_CLAUSE_OPERAND (c, 0) = t;
8324 2218 : break;
8325 :
8326 289 : case OMP_CLAUSE_FINAL:
8327 289 : t = OMP_CLAUSE_FINAL_EXPR (c);
8328 289 : t = maybe_convert_cond (t);
8329 289 : if (t == error_mark_node)
8330 : remove = true;
8331 289 : else if (!processing_template_decl)
8332 283 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8333 289 : OMP_CLAUSE_FINAL_EXPR (c) = t;
8334 289 : break;
8335 :
8336 92 : case OMP_CLAUSE_NOCONTEXT:
8337 92 : t = OMP_CLAUSE_NOCONTEXT_EXPR (c);
8338 92 : t = maybe_convert_cond (t);
8339 92 : if (t == error_mark_node)
8340 : remove = true;
8341 89 : else if (!processing_template_decl)
8342 83 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8343 92 : OMP_CLAUSE_NOCONTEXT_EXPR (c) = t;
8344 92 : break;
8345 :
8346 80 : case OMP_CLAUSE_NOVARIANTS:
8347 80 : t = OMP_CLAUSE_NOVARIANTS_EXPR (c);
8348 80 : t = maybe_convert_cond (t);
8349 80 : if (t == error_mark_node)
8350 : remove = true;
8351 77 : else if (!processing_template_decl)
8352 71 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8353 80 : OMP_CLAUSE_NOVARIANTS_EXPR (c) = t;
8354 80 : break;
8355 :
8356 1249 : case OMP_CLAUSE_GANG:
8357 : /* Operand 1 is the gang static: argument. */
8358 1249 : t = OMP_CLAUSE_OPERAND (c, 1);
8359 1249 : if (t != NULL_TREE)
8360 : {
8361 129 : if (t == error_mark_node)
8362 : remove = true;
8363 129 : else if (!type_dependent_expression_p (t)
8364 129 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8365 : {
8366 6 : error_at (OMP_CLAUSE_LOCATION (c),
8367 : "%<gang%> static expression must be integral");
8368 6 : remove = true;
8369 : }
8370 : else
8371 : {
8372 123 : t = mark_rvalue_use (t);
8373 123 : if (!processing_template_decl)
8374 : {
8375 123 : t = maybe_constant_value (t);
8376 123 : if (TREE_CODE (t) == INTEGER_CST
8377 109 : && tree_int_cst_sgn (t) != 1
8378 176 : && t != integer_minus_one_node)
8379 : {
8380 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8381 : "%<gang%> static value must be "
8382 : "positive");
8383 0 : t = integer_one_node;
8384 : }
8385 123 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8386 : }
8387 : }
8388 129 : OMP_CLAUSE_OPERAND (c, 1) = t;
8389 : }
8390 : /* Check operand 0, the num argument. */
8391 : /* FALLTHRU */
8392 :
8393 3480 : case OMP_CLAUSE_WORKER:
8394 3480 : case OMP_CLAUSE_VECTOR:
8395 3480 : if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
8396 : break;
8397 : /* FALLTHRU */
8398 :
8399 484 : case OMP_CLAUSE_NUM_TASKS:
8400 484 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TASKS)
8401 136 : num_tasks_seen = true;
8402 : /* FALLTHRU */
8403 :
8404 3034 : case OMP_CLAUSE_NUM_TEAMS:
8405 3034 : case OMP_CLAUSE_NUM_THREADS:
8406 3034 : case OMP_CLAUSE_NUM_GANGS:
8407 3034 : case OMP_CLAUSE_NUM_WORKERS:
8408 3034 : case OMP_CLAUSE_DYN_GROUPPRIVATE:
8409 3034 : case OMP_CLAUSE_VECTOR_LENGTH:
8410 3034 : t = OMP_CLAUSE_OPERAND (c, 0);
8411 3034 : if (t == error_mark_node)
8412 : remove = true;
8413 3034 : else if (!type_dependent_expression_p (t)
8414 3034 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8415 : {
8416 99 : switch (OMP_CLAUSE_CODE (c))
8417 : {
8418 12 : case OMP_CLAUSE_GANG:
8419 12 : error_at (OMP_CLAUSE_LOCATION (c),
8420 12 : "%<gang%> num expression must be integral"); break;
8421 12 : case OMP_CLAUSE_VECTOR:
8422 12 : error_at (OMP_CLAUSE_LOCATION (c),
8423 : "%<vector%> length expression must be integral");
8424 12 : break;
8425 12 : case OMP_CLAUSE_WORKER:
8426 12 : error_at (OMP_CLAUSE_LOCATION (c),
8427 : "%<worker%> num expression must be integral");
8428 12 : break;
8429 63 : default:
8430 63 : error_at (OMP_CLAUSE_LOCATION (c),
8431 : "%qs expression must be integral",
8432 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8433 : }
8434 : remove = true;
8435 : }
8436 : else
8437 : {
8438 2935 : t = mark_rvalue_use (t);
8439 2935 : if (!processing_template_decl)
8440 : {
8441 2687 : t = maybe_constant_value (t);
8442 2687 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
8443 2652 : && TREE_CODE (t) == INTEGER_CST
8444 4142 : && tree_int_cst_sgn (t) != 1)
8445 : {
8446 85 : switch (OMP_CLAUSE_CODE (c))
8447 : {
8448 3 : case OMP_CLAUSE_GANG:
8449 3 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8450 : "%<gang%> num value must be positive");
8451 3 : break;
8452 0 : case OMP_CLAUSE_VECTOR:
8453 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8454 : "%<vector%> length value must be "
8455 : "positive");
8456 0 : break;
8457 0 : case OMP_CLAUSE_WORKER:
8458 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8459 : "%<worker%> num value must be "
8460 : "positive");
8461 0 : break;
8462 82 : default:
8463 82 : warning_at (OMP_CLAUSE_LOCATION (c),
8464 46 : (flag_openmp || flag_openmp_simd)
8465 82 : ? OPT_Wopenmp : 0,
8466 : "%qs value must be positive",
8467 : omp_clause_code_name
8468 82 : [OMP_CLAUSE_CODE (c)]);
8469 : }
8470 85 : t = integer_one_node;
8471 : }
8472 2602 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
8473 35 : && TREE_CODE (t) == INTEGER_CST
8474 2625 : && tree_int_cst_sgn (t) < 0)
8475 : {
8476 8 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8477 : "%<dyn_groupprivate%> value must be "
8478 : "non-negative");
8479 8 : t = integer_zero_node;
8480 : }
8481 2687 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8482 : }
8483 2935 : OMP_CLAUSE_OPERAND (c, 0) = t;
8484 : }
8485 3034 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
8486 752 : && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
8487 3313 : && !remove)
8488 : {
8489 279 : t = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
8490 279 : if (t == error_mark_node)
8491 : remove = true;
8492 279 : else if (!type_dependent_expression_p (t)
8493 279 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8494 : {
8495 0 : error_at (OMP_CLAUSE_LOCATION (c),
8496 : "%qs expression must be integral",
8497 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8498 0 : remove = true;
8499 : }
8500 : else
8501 : {
8502 279 : t = mark_rvalue_use (t);
8503 279 : if (!processing_template_decl)
8504 : {
8505 213 : t = maybe_constant_value (t);
8506 213 : if (TREE_CODE (t) == INTEGER_CST
8507 213 : && tree_int_cst_sgn (t) != 1)
8508 : {
8509 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8510 : "%qs value must be positive",
8511 : omp_clause_code_name
8512 18 : [OMP_CLAUSE_CODE (c)]);
8513 18 : t = NULL_TREE;
8514 : }
8515 : else
8516 195 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8517 213 : tree upper = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
8518 213 : if (t
8519 195 : && TREE_CODE (t) == INTEGER_CST
8520 43 : && TREE_CODE (upper) == INTEGER_CST
8521 250 : && tree_int_cst_lt (upper, t))
8522 : {
8523 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8524 : "%<num_teams%> lower bound %qE bigger "
8525 : "than upper bound %qE", t, upper);
8526 18 : t = NULL_TREE;
8527 : }
8528 : }
8529 279 : OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = t;
8530 : }
8531 : }
8532 : break;
8533 :
8534 3862 : case OMP_CLAUSE_SCHEDULE:
8535 3862 : t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
8536 3862 : if (t == NULL)
8537 : ;
8538 2078 : else if (t == error_mark_node)
8539 : remove = true;
8540 2078 : else if (!type_dependent_expression_p (t)
8541 2078 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8542 : {
8543 9 : error_at (OMP_CLAUSE_LOCATION (c),
8544 : "schedule chunk size expression must be integral");
8545 9 : remove = true;
8546 : }
8547 : else
8548 : {
8549 2069 : t = mark_rvalue_use (t);
8550 2069 : if (!processing_template_decl)
8551 : {
8552 2029 : t = maybe_constant_value (t);
8553 2029 : if (TREE_CODE (t) == INTEGER_CST
8554 2029 : && tree_int_cst_sgn (t) != 1)
8555 : {
8556 6 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8557 : "chunk size value must be positive");
8558 6 : t = integer_one_node;
8559 : }
8560 2029 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8561 : }
8562 2069 : OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
8563 : }
8564 2078 : if (!remove)
8565 : schedule_seen = true;
8566 : break;
8567 :
8568 1268 : case OMP_CLAUSE_SIMDLEN:
8569 1268 : case OMP_CLAUSE_SAFELEN:
8570 1268 : t = OMP_CLAUSE_OPERAND (c, 0);
8571 1268 : if (t == error_mark_node)
8572 : remove = true;
8573 1268 : else if (!type_dependent_expression_p (t)
8574 1268 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8575 : {
8576 0 : error_at (OMP_CLAUSE_LOCATION (c),
8577 : "%qs length expression must be integral",
8578 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8579 0 : remove = true;
8580 : }
8581 : else
8582 : {
8583 1268 : t = mark_rvalue_use (t);
8584 1268 : if (!processing_template_decl)
8585 : {
8586 1219 : t = maybe_constant_value (t);
8587 1219 : if (TREE_CODE (t) != INTEGER_CST
8588 1219 : || tree_int_cst_sgn (t) != 1)
8589 : {
8590 0 : error_at (OMP_CLAUSE_LOCATION (c),
8591 : "%qs length expression must be positive "
8592 : "constant integer expression",
8593 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8594 0 : remove = true;
8595 : }
8596 : }
8597 1268 : OMP_CLAUSE_OPERAND (c, 0) = t;
8598 1268 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN)
8599 470 : safelen = c;
8600 : }
8601 : break;
8602 :
8603 388 : case OMP_CLAUSE_ASYNC:
8604 388 : t = OMP_CLAUSE_ASYNC_EXPR (c);
8605 388 : if (t == error_mark_node)
8606 : remove = true;
8607 373 : else if (!type_dependent_expression_p (t)
8608 373 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8609 : {
8610 12 : error_at (OMP_CLAUSE_LOCATION (c),
8611 : "%<async%> expression must be integral");
8612 12 : remove = true;
8613 : }
8614 : else
8615 : {
8616 361 : t = mark_rvalue_use (t);
8617 361 : if (!processing_template_decl)
8618 352 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8619 361 : OMP_CLAUSE_ASYNC_EXPR (c) = t;
8620 : }
8621 : break;
8622 :
8623 204 : case OMP_CLAUSE_WAIT:
8624 204 : t = OMP_CLAUSE_WAIT_EXPR (c);
8625 204 : if (t == error_mark_node)
8626 : remove = true;
8627 204 : else if (!processing_template_decl)
8628 196 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8629 204 : OMP_CLAUSE_WAIT_EXPR (c) = t;
8630 204 : break;
8631 :
8632 637 : case OMP_CLAUSE_THREAD_LIMIT:
8633 637 : t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
8634 637 : if (t == error_mark_node)
8635 : remove = true;
8636 637 : else if (!type_dependent_expression_p (t)
8637 637 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8638 : {
8639 0 : error_at (OMP_CLAUSE_LOCATION (c),
8640 : "%<thread_limit%> expression must be integral");
8641 0 : remove = true;
8642 : }
8643 : else
8644 : {
8645 637 : t = mark_rvalue_use (t);
8646 637 : if (!processing_template_decl)
8647 : {
8648 583 : t = maybe_constant_value (t);
8649 583 : if (TREE_CODE (t) == INTEGER_CST
8650 583 : && tree_int_cst_sgn (t) != 1)
8651 : {
8652 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8653 : "%<thread_limit%> value must be positive");
8654 0 : t = integer_one_node;
8655 : }
8656 583 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8657 : }
8658 637 : OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
8659 : }
8660 : break;
8661 :
8662 770 : case OMP_CLAUSE_DEVICE:
8663 770 : t = OMP_CLAUSE_DEVICE_ID (c);
8664 770 : if (t == error_mark_node)
8665 : remove = true;
8666 770 : else if (!type_dependent_expression_p (t)
8667 770 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8668 : {
8669 6 : error_at (OMP_CLAUSE_LOCATION (c),
8670 : "%<device%> id must be integral");
8671 6 : remove = true;
8672 : }
8673 764 : else if (OMP_CLAUSE_DEVICE_ANCESTOR (c)
8674 66 : && TREE_CODE (t) == INTEGER_CST
8675 824 : && !integer_onep (t))
8676 : {
8677 3 : error_at (OMP_CLAUSE_LOCATION (c),
8678 : "the %<device%> clause expression must evaluate to "
8679 : "%<1%>");
8680 3 : remove = true;
8681 : }
8682 : else
8683 : {
8684 761 : t = mark_rvalue_use (t);
8685 761 : if (!processing_template_decl)
8686 750 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8687 761 : OMP_CLAUSE_DEVICE_ID (c) = t;
8688 : }
8689 : break;
8690 :
8691 1836 : case OMP_CLAUSE_DIST_SCHEDULE:
8692 1836 : t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c);
8693 1836 : if (t == NULL)
8694 : ;
8695 1815 : else if (t == error_mark_node)
8696 : remove = true;
8697 1815 : else if (!type_dependent_expression_p (t)
8698 1815 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8699 : {
8700 0 : error_at (OMP_CLAUSE_LOCATION (c),
8701 : "%<dist_schedule%> chunk size expression must be "
8702 : "integral");
8703 0 : remove = true;
8704 : }
8705 : else
8706 : {
8707 1815 : t = mark_rvalue_use (t);
8708 1815 : if (!processing_template_decl)
8709 1815 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8710 1815 : OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
8711 : }
8712 : break;
8713 :
8714 807 : case OMP_CLAUSE_ALIGNED:
8715 807 : t = OMP_CLAUSE_DECL (c);
8716 807 : if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD)
8717 : {
8718 0 : error_at (OMP_CLAUSE_LOCATION (c),
8719 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8720 : " clauses");
8721 0 : remove = true;
8722 0 : break;
8723 : }
8724 807 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8725 : {
8726 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8727 : break;
8728 0 : if (DECL_P (t))
8729 0 : error_at (OMP_CLAUSE_LOCATION (c),
8730 : "%qD is not a variable in %<aligned%> clause", t);
8731 : else
8732 0 : error_at (OMP_CLAUSE_LOCATION (c),
8733 : "%qE is not a variable in %<aligned%> clause", t);
8734 : remove = true;
8735 : }
8736 807 : else if (!type_dependent_expression_p (t)
8737 789 : && !TYPE_PTR_P (TREE_TYPE (t))
8738 111 : && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
8739 864 : && (!TYPE_REF_P (TREE_TYPE (t))
8740 39 : || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
8741 30 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
8742 : != ARRAY_TYPE))))
8743 : {
8744 33 : error_at (OMP_CLAUSE_LOCATION (c),
8745 : "%qE in %<aligned%> clause is neither a pointer nor "
8746 : "an array nor a reference to pointer or array", t);
8747 33 : remove = true;
8748 : }
8749 774 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8750 : {
8751 0 : error_at (OMP_CLAUSE_LOCATION (c),
8752 : "%qD appears more than once in %<aligned%> clauses",
8753 : t);
8754 0 : remove = true;
8755 : }
8756 : else
8757 774 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8758 807 : t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c);
8759 807 : if (t == error_mark_node)
8760 : remove = true;
8761 807 : else if (t == NULL_TREE)
8762 : break;
8763 744 : else if (!type_dependent_expression_p (t)
8764 744 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8765 : {
8766 0 : error_at (OMP_CLAUSE_LOCATION (c),
8767 : "%<aligned%> clause alignment expression must "
8768 : "be integral");
8769 0 : remove = true;
8770 : }
8771 : else
8772 : {
8773 744 : t = mark_rvalue_use (t);
8774 744 : if (!processing_template_decl)
8775 : {
8776 690 : t = maybe_constant_value (t);
8777 690 : if (TREE_CODE (t) != INTEGER_CST
8778 690 : || tree_int_cst_sgn (t) != 1)
8779 : {
8780 0 : error_at (OMP_CLAUSE_LOCATION (c),
8781 : "%<aligned%> clause alignment expression must "
8782 : "be positive constant integer expression");
8783 0 : remove = true;
8784 : }
8785 : }
8786 744 : OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t;
8787 : }
8788 : break;
8789 :
8790 369 : case OMP_CLAUSE_NONTEMPORAL:
8791 369 : t = OMP_CLAUSE_DECL (c);
8792 369 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8793 : {
8794 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8795 : break;
8796 0 : if (DECL_P (t))
8797 0 : error_at (OMP_CLAUSE_LOCATION (c),
8798 : "%qD is not a variable in %<nontemporal%> clause",
8799 : t);
8800 : else
8801 0 : error_at (OMP_CLAUSE_LOCATION (c),
8802 : "%qE is not a variable in %<nontemporal%> clause",
8803 : t);
8804 : remove = true;
8805 : }
8806 369 : else if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8807 : {
8808 6 : error_at (OMP_CLAUSE_LOCATION (c),
8809 : "%qD appears more than once in %<nontemporal%> "
8810 : "clauses", t);
8811 6 : remove = true;
8812 : }
8813 : else
8814 363 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8815 : break;
8816 :
8817 2585 : case OMP_CLAUSE_ALLOCATE:
8818 2585 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8819 2585 : if (t)
8820 14 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8821 : else
8822 2571 : t = OMP_CLAUSE_DECL (c);
8823 2585 : if (t == current_class_ptr)
8824 : {
8825 0 : error_at (OMP_CLAUSE_LOCATION (c),
8826 : "%<this%> not allowed in %<allocate%> clause");
8827 0 : remove = true;
8828 0 : break;
8829 : }
8830 2585 : if (!VAR_P (t)
8831 558 : && TREE_CODE (t) != PARM_DECL
8832 45 : && TREE_CODE (t) != FIELD_DECL)
8833 : {
8834 3 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8835 : break;
8836 3 : if (DECL_P (t))
8837 3 : error_at (OMP_CLAUSE_LOCATION (c),
8838 : "%qD is not a variable in %<allocate%> clause", t);
8839 : else
8840 0 : error_at (OMP_CLAUSE_LOCATION (c),
8841 : "%qE is not a variable in %<allocate%> clause", t);
8842 : remove = true;
8843 : }
8844 2582 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8845 : {
8846 12 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8847 : "%qD appears more than once in %<allocate%> clauses",
8848 : t);
8849 12 : remove = true;
8850 : }
8851 : else
8852 : {
8853 2570 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8854 2570 : allocate_seen = true;
8855 : }
8856 2585 : tree allocator, align;
8857 2585 : align = OMP_CLAUSE_ALLOCATE_ALIGN (c);
8858 2585 : if (error_operand_p (align))
8859 : {
8860 : remove = true;
8861 : break;
8862 : }
8863 2585 : if (align)
8864 : {
8865 207 : if (!type_dependent_expression_p (align)
8866 207 : && !INTEGRAL_TYPE_P (TREE_TYPE (align)))
8867 : {
8868 4 : error_at (OMP_CLAUSE_LOCATION (c),
8869 : "%<allocate%> clause %<align%> modifier "
8870 : "argument needs to be positive constant "
8871 : "power of two integer expression");
8872 4 : remove = true;
8873 : }
8874 : else
8875 : {
8876 203 : align = mark_rvalue_use (align);
8877 203 : if (!processing_template_decl)
8878 : {
8879 188 : align = maybe_constant_value (align);
8880 188 : if (TREE_CODE (align) != INTEGER_CST
8881 185 : || !tree_fits_uhwi_p (align)
8882 373 : || !integer_pow2p (align))
8883 : {
8884 10 : error_at (OMP_CLAUSE_LOCATION (c),
8885 : "%<allocate%> clause %<align%> modifier "
8886 : "argument needs to be positive constant "
8887 : "power of two integer expression");
8888 10 : remove = true;
8889 : }
8890 : }
8891 : }
8892 207 : OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
8893 : }
8894 2585 : allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
8895 2585 : if (error_operand_p (allocator))
8896 : {
8897 : remove = true;
8898 : break;
8899 : }
8900 2585 : if (allocator == NULL_TREE)
8901 1537 : goto handle_field_decl;
8902 1048 : tree allocatort;
8903 1048 : allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator));
8904 1048 : if (!type_dependent_expression_p (allocator)
8905 1048 : && (TREE_CODE (allocatort) != ENUMERAL_TYPE
8906 1029 : || TYPE_NAME (allocatort) == NULL_TREE
8907 1029 : || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL
8908 2058 : || (DECL_NAME (TYPE_NAME (allocatort))
8909 1029 : != get_identifier ("omp_allocator_handle_t"))
8910 1029 : || (TYPE_CONTEXT (allocatort)
8911 1029 : != DECL_CONTEXT (global_namespace))))
8912 : {
8913 16 : error_at (OMP_CLAUSE_LOCATION (c),
8914 : "%<allocate%> clause allocator expression has "
8915 : "type %qT rather than %<omp_allocator_handle_t%>",
8916 16 : TREE_TYPE (allocator));
8917 16 : remove = true;
8918 16 : break;
8919 : }
8920 : else
8921 : {
8922 1032 : allocator = mark_rvalue_use (allocator);
8923 1032 : if (!processing_template_decl)
8924 1013 : allocator = maybe_constant_value (allocator);
8925 1032 : OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
8926 : }
8927 1032 : goto handle_field_decl;
8928 :
8929 654 : case OMP_CLAUSE_DOACROSS:
8930 654 : t = OMP_CLAUSE_DECL (c);
8931 654 : if (t == NULL_TREE)
8932 : break;
8933 298 : if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
8934 : {
8935 298 : if (cp_finish_omp_clause_doacross_sink (c))
8936 12 : remove = true;
8937 : break;
8938 : }
8939 0 : gcc_unreachable ();
8940 141 : case OMP_CLAUSE_USES_ALLOCATORS:
8941 141 : t = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
8942 141 : t = convert_from_reference (t);
8943 141 : if (t == error_mark_node)
8944 : {
8945 : remove = true;
8946 : break;
8947 : }
8948 129 : if (DECL_P (t)
8949 129 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8950 120 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8951 117 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
8952 : {
8953 3 : error_at (OMP_CLAUSE_LOCATION (c),
8954 : "%qE appears more than once in data clauses", t);
8955 3 : remove = true;
8956 : }
8957 126 : else if (DECL_P (t))
8958 117 : bitmap_set_bit (&generic_head, DECL_UID (t));
8959 129 : if (type_dependent_expression_p (t))
8960 : break;
8961 114 : if (TREE_CODE (t) == FIELD_DECL)
8962 : {
8963 0 : sorry_at (OMP_CLAUSE_LOCATION (c), "class member %qE not yet "
8964 : "supported in %<uses_allocators%> clause", t);
8965 0 : remove = true;
8966 0 : break;
8967 : }
8968 114 : if (TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
8969 219 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
8970 : "omp_allocator_handle_t") != 0)
8971 : {
8972 9 : error_at (OMP_CLAUSE_LOCATION (c),
8973 : "allocator %qE must be of %<omp_allocator_handle_t%> "
8974 : "type", t);
8975 9 : remove = true;
8976 9 : break;
8977 : }
8978 105 : tree init;
8979 105 : if (TREE_CODE (t) == CONST_DECL)
8980 15 : init = DECL_INITIAL(t);
8981 : else
8982 : init = t;
8983 105 : if (!DECL_P (t)
8984 105 : && (init == NULL_TREE
8985 9 : || TREE_CODE (init) != INTEGER_CST
8986 9 : || ((wi::to_widest (init) < 0
8987 9 : || wi::to_widest (init) > GOMP_OMP_PREDEF_ALLOC_MAX)
8988 3 : && (wi::to_widest (init) < GOMP_OMPX_PREDEF_ALLOC_MIN
8989 3 : || (wi::to_widest (init)
8990 6 : > GOMP_OMPX_PREDEF_ALLOC_MAX)))))
8991 : {
8992 3 : remove = true;
8993 3 : error_at (OMP_CLAUSE_LOCATION (c),
8994 : "allocator %qE must be either a variable or a "
8995 : "predefined allocator", t);
8996 3 : break;
8997 : }
8998 102 : else if (TREE_CODE (t) == CONST_DECL)
8999 : {
9000 : /* omp_null_allocator is ignored and for predefined allocators,
9001 : not special handling is required; thus, remove them removed. */
9002 15 : remove = true;
9003 :
9004 15 : if (OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c)
9005 15 : || OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c))
9006 : {
9007 0 : error_at (OMP_CLAUSE_LOCATION (c),
9008 : "modifiers cannot be used with predefined "
9009 : "allocators");
9010 0 : break;
9011 : }
9012 : }
9013 102 : t = OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c);
9014 102 : if (t == error_mark_node)
9015 : {
9016 : remove = true;
9017 : break;
9018 : }
9019 99 : if (t != NULL_TREE
9020 18 : && !type_dependent_expression_p (t)
9021 117 : && ((TREE_CODE (t) != CONST_DECL && TREE_CODE (t) != INTEGER_CST)
9022 15 : || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9023 24 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9024 : "omp_memspace_handle_t") != 0))
9025 : {
9026 6 : error_at (OMP_CLAUSE_LOCATION (c), "memspace modifier %qE must be"
9027 : " constant enum of %<omp_memspace_handle_t%> type", t);
9028 6 : remove = true;
9029 6 : break;
9030 : }
9031 93 : t = OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c);
9032 93 : if (t == error_mark_node)
9033 : {
9034 : remove = true;
9035 : break;
9036 : }
9037 90 : if (type_dependent_expression_p (t))
9038 : break;
9039 90 : if (t != NULL_TREE
9040 39 : && t != error_mark_node
9041 39 : && !type_dependent_expression_p (t)
9042 129 : && (!DECL_P (t)
9043 39 : || DECL_EXTERNAL (t)
9044 33 : || TREE_CODE (t) == PARM_DECL))
9045 : {
9046 12 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must be "
9047 : "defined in same scope as the construct on which the "
9048 : "clause appears", t);
9049 12 : remove = true;
9050 : }
9051 90 : if (t != NULL_TREE)
9052 : {
9053 39 : bool type_err = false;
9054 :
9055 39 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
9056 33 : || DECL_SIZE (t) == NULL_TREE
9057 69 : || !COMPLETE_TYPE_P (TREE_TYPE (t)))
9058 : type_err = true;
9059 : else
9060 : {
9061 30 : tree elem_t = TREE_TYPE (TREE_TYPE (t));
9062 30 : if (TREE_CODE (elem_t) != RECORD_TYPE
9063 60 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (elem_t)),
9064 : "omp_alloctrait_t") != 0
9065 60 : || !TYPE_READONLY (elem_t))
9066 : type_err = true;
9067 : }
9068 27 : if (type_err)
9069 : {
9070 12 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must "
9071 : "be of %<const omp_alloctrait_t []%> type", t);
9072 12 : remove = true;
9073 : }
9074 27 : else if (TREE_CODE (array_type_nelts_top (TREE_TYPE (t)))
9075 : != INTEGER_CST)
9076 : {
9077 3 : error_at (OMP_CLAUSE_LOCATION (c), "variable length traits "
9078 : "arrays are not supported");
9079 3 : remove = true;
9080 : }
9081 : else
9082 : {
9083 24 : tree cst_val = decl_constant_value (t);
9084 24 : if (cst_val == t)
9085 : {
9086 3 : error_at (OMP_CLAUSE_LOCATION (c), "traits array must be "
9087 : "initialized with constants");
9088 3 : remove = true;
9089 : }
9090 : }
9091 : }
9092 90 : if (remove)
9093 : break;
9094 54 : pc = &OMP_CLAUSE_CHAIN (c);
9095 54 : continue;
9096 1803 : case OMP_CLAUSE_DEPEND:
9097 1803 : depend_clause = c;
9098 : /* FALLTHRU */
9099 2169 : case OMP_CLAUSE_AFFINITY:
9100 2169 : t = OMP_CLAUSE_DECL (c);
9101 2169 : if (OMP_ITERATOR_DECL_P (t))
9102 : {
9103 621 : if (TREE_PURPOSE (t) != last_iterators)
9104 523 : last_iterators_remove
9105 523 : = cp_omp_finish_iterators (TREE_PURPOSE (t));
9106 621 : last_iterators = TREE_PURPOSE (t);
9107 621 : t = TREE_VALUE (t);
9108 621 : if (last_iterators_remove)
9109 144 : t = error_mark_node;
9110 : }
9111 : else
9112 : last_iterators = NULL_TREE;
9113 :
9114 2169 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9115 : {
9116 1163 : if (handle_omp_array_sections (c, ort))
9117 : remove = true;
9118 912 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9119 912 : && (OMP_CLAUSE_DEPEND_KIND (c)
9120 : == OMP_CLAUSE_DEPEND_DEPOBJ))
9121 : {
9122 6 : error_at (OMP_CLAUSE_LOCATION (c),
9123 : "%<depend%> clause with %<depobj%> dependence "
9124 : "type on array section");
9125 6 : remove = true;
9126 : }
9127 : break;
9128 : }
9129 1006 : if (t == error_mark_node)
9130 : remove = true;
9131 844 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9132 844 : && t == ridpointers[RID_OMP_ALL_MEMORY])
9133 : {
9134 33 : if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_OUT
9135 33 : && OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_INOUT)
9136 : {
9137 9 : error_at (OMP_CLAUSE_LOCATION (c),
9138 : "%<omp_all_memory%> used with %<depend%> kind "
9139 : "other than %<out%> or %<inout%>");
9140 9 : remove = true;
9141 : }
9142 33 : if (processing_template_decl)
9143 : break;
9144 : }
9145 811 : else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9146 : break;
9147 619 : else if (!lvalue_p (t))
9148 : {
9149 19 : if (DECL_P (t))
9150 24 : error_at (OMP_CLAUSE_LOCATION (c),
9151 : "%qD is not lvalue expression nor array section "
9152 : "in %qs clause", t,
9153 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9154 : else
9155 14 : error_at (OMP_CLAUSE_LOCATION (c),
9156 : "%qE is not lvalue expression nor array section "
9157 : "in %qs clause", t,
9158 7 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9159 : remove = true;
9160 : }
9161 600 : else if (TREE_CODE (t) == COMPONENT_REF
9162 24 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
9163 624 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
9164 : {
9165 8 : error_at (OMP_CLAUSE_LOCATION (c),
9166 : "bit-field %qE in %qs clause", t,
9167 4 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9168 4 : remove = true;
9169 : }
9170 596 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9171 596 : && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ)
9172 : {
9173 130 : if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9174 8 : ? TREE_TYPE (TREE_TYPE (t))
9175 57 : : TREE_TYPE (t)))
9176 : {
9177 12 : error_at (OMP_CLAUSE_LOCATION (c),
9178 : "%qE does not have %<omp_depend_t%> type in "
9179 : "%<depend%> clause with %<depobj%> dependence "
9180 : "type", t);
9181 12 : remove = true;
9182 : }
9183 : }
9184 531 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9185 970 : && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9186 4 : ? TREE_TYPE (TREE_TYPE (t))
9187 435 : : TREE_TYPE (t)))
9188 : {
9189 15 : error_at (OMP_CLAUSE_LOCATION (c),
9190 : "%qE should not have %<omp_depend_t%> type in "
9191 : "%<depend%> clause with dependence type other than "
9192 : "%<depobj%>", t);
9193 15 : remove = true;
9194 : }
9195 64 : if (!remove)
9196 : {
9197 593 : if (t == ridpointers[RID_OMP_ALL_MEMORY])
9198 24 : t = null_pointer_node;
9199 : else
9200 : {
9201 569 : tree addr = cp_build_addr_expr (t, tf_warning_or_error);
9202 569 : if (addr == error_mark_node)
9203 : {
9204 : remove = true;
9205 : break;
9206 : }
9207 569 : t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c),
9208 : addr, RO_UNARY_STAR,
9209 : tf_warning_or_error);
9210 569 : if (t == error_mark_node)
9211 : {
9212 : remove = true;
9213 : break;
9214 : }
9215 : }
9216 593 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST
9217 135 : && TREE_PURPOSE (OMP_CLAUSE_DECL (c))
9218 728 : && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c)))
9219 : == TREE_VEC))
9220 135 : TREE_VALUE (OMP_CLAUSE_DECL (c)) = t;
9221 : else
9222 458 : OMP_CLAUSE_DECL (c) = t;
9223 : }
9224 : break;
9225 69 : case OMP_CLAUSE_DETACH:
9226 69 : t = OMP_CLAUSE_DECL (c);
9227 69 : if (detach_seen)
9228 : {
9229 3 : error_at (OMP_CLAUSE_LOCATION (c),
9230 : "too many %qs clauses on a task construct",
9231 : "detach");
9232 3 : remove = true;
9233 3 : break;
9234 : }
9235 66 : else if (error_operand_p (t))
9236 : {
9237 : remove = true;
9238 : break;
9239 : }
9240 : else
9241 : {
9242 63 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
9243 63 : if (!type_dependent_expression_p (t)
9244 63 : && (!INTEGRAL_TYPE_P (type)
9245 : || TREE_CODE (type) != ENUMERAL_TYPE
9246 51 : || TYPE_NAME (type) == NULL_TREE
9247 102 : || (DECL_NAME (TYPE_NAME (type))
9248 51 : != get_identifier ("omp_event_handle_t"))))
9249 : {
9250 6 : error_at (OMP_CLAUSE_LOCATION (c),
9251 : "%<detach%> clause event handle "
9252 : "has type %qT rather than "
9253 : "%<omp_event_handle_t%>",
9254 : type);
9255 6 : remove = true;
9256 : }
9257 63 : detach_seen = c;
9258 63 : cxx_mark_addressable (t);
9259 : }
9260 63 : break;
9261 :
9262 15934 : case OMP_CLAUSE_MAP:
9263 15934 : if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved)
9264 190 : goto move_implicit;
9265 15744 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME
9266 15744 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POP_MAPPER_NAME)
9267 : {
9268 : remove = true;
9269 : break;
9270 : }
9271 : /* FALLTHRU */
9272 18862 : case OMP_CLAUSE_TO:
9273 18862 : case OMP_CLAUSE_FROM:
9274 18862 : if (OMP_CLAUSE_ITERATORS (c)
9275 18862 : && cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
9276 : {
9277 97092 : t = error_mark_node;
9278 : break;
9279 : }
9280 : /* FALLTHRU */
9281 19698 : case OMP_CLAUSE__CACHE_:
9282 19698 : {
9283 19698 : using namespace omp_addr_tokenizer;
9284 19698 : auto_vec<omp_addr_token *, 10> addr_tokens;
9285 :
9286 19698 : t = OMP_CLAUSE_DECL (c);
9287 19698 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9288 : {
9289 5872 : grp_start_p = pc;
9290 5872 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9291 :
9292 5872 : if (handle_omp_array_sections (c, ort))
9293 : remove = true;
9294 : else
9295 : {
9296 5106 : t = OMP_CLAUSE_DECL (c);
9297 5106 : if (TREE_CODE (t) != OMP_ARRAY_SECTION
9298 4249 : && !type_dependent_expression_p (t)
9299 9355 : && !omp_mappable_type (TREE_TYPE (t)))
9300 : {
9301 3 : auto_diagnostic_group d;
9302 6 : error_at (OMP_CLAUSE_LOCATION (c),
9303 : "array section does not have mappable type "
9304 : "in %qs clause",
9305 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9306 3 : if (TREE_TYPE (t) != error_mark_node
9307 3 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9308 3 : cxx_incomplete_type_inform (TREE_TYPE (t));
9309 3 : remove = true;
9310 3 : }
9311 6956 : while (TREE_CODE (t) == ARRAY_REF)
9312 1850 : t = TREE_OPERAND (t, 0);
9313 :
9314 5106 : if (type_dependent_expression_p (t))
9315 : break;
9316 :
9317 4632 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9318 :
9319 4632 : if (!ai.map_supported_p ()
9320 4632 : || !omp_parse_expr (addr_tokens, t))
9321 : {
9322 18 : sorry_at (OMP_CLAUSE_LOCATION (c),
9323 : "unsupported map expression %qE",
9324 9 : OMP_CLAUSE_DECL (c));
9325 9 : remove = true;
9326 9 : break;
9327 : }
9328 :
9329 : /* This check is to determine if this will be the only map
9330 : node created for this clause. Otherwise, we'll check
9331 : the following FIRSTPRIVATE_POINTER,
9332 : FIRSTPRIVATE_REFERENCE or ATTACH_DETACH node on the next
9333 : iteration(s) of the loop. */
9334 9197 : if (addr_tokens.length () >= 4
9335 1063 : && addr_tokens[0]->type == STRUCTURE_BASE
9336 1057 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
9337 1057 : && addr_tokens[1]->type == ACCESS_METHOD
9338 1057 : && addr_tokens[2]->type == COMPONENT_SELECTOR
9339 977 : && addr_tokens[3]->type == ACCESS_METHOD
9340 5337 : && (addr_tokens[3]->u.access_kind == ACCESS_DIRECT
9341 551 : || (addr_tokens[3]->u.access_kind
9342 : == ACCESS_INDEXED_ARRAY)))
9343 : {
9344 165 : tree rt = addr_tokens[1]->expr;
9345 :
9346 165 : gcc_assert (DECL_P (rt));
9347 :
9348 165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9349 154 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9350 165 : && (bitmap_bit_p (&map_head, DECL_UID (rt))
9351 0 : || bitmap_bit_p (&map_field_head, DECL_UID (rt))
9352 0 : || bitmap_bit_p (&map_firstprivate_head,
9353 0 : DECL_UID (rt))))
9354 : {
9355 : remove = true;
9356 : break;
9357 : }
9358 165 : if (bitmap_bit_p (&map_field_head, DECL_UID (rt)))
9359 : break;
9360 116 : if (bitmap_bit_p (&map_head, DECL_UID (rt)))
9361 : {
9362 0 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9363 0 : error_at (OMP_CLAUSE_LOCATION (c),
9364 : "%qD appears more than once in motion"
9365 : " clauses", rt);
9366 0 : else if (openacc)
9367 0 : error_at (OMP_CLAUSE_LOCATION (c),
9368 : "%qD appears more than once in data"
9369 : " clauses", rt);
9370 : else
9371 0 : error_at (OMP_CLAUSE_LOCATION (c),
9372 : "%qD appears more than once in map"
9373 : " clauses", rt);
9374 : remove = true;
9375 : }
9376 : else
9377 : {
9378 116 : bitmap_set_bit (&map_head, DECL_UID (rt));
9379 116 : bitmap_set_bit (&map_field_head, DECL_UID (rt));
9380 : }
9381 : }
9382 4632 : }
9383 5340 : if (cp_oacc_check_attachments (c))
9384 12 : remove = true;
9385 5340 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9386 4406 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9387 4342 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9388 5438 : && !OMP_CLAUSE_SIZE (c))
9389 : /* In this case, we have a single array element which is a
9390 : pointer, and we already set OMP_CLAUSE_SIZE in
9391 : handle_omp_array_sections above. For attach/detach
9392 : clauses, reset the OMP_CLAUSE_SIZE (representing a bias)
9393 : to zero here. */
9394 60 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9395 : break;
9396 : }
9397 13826 : else if (type_dependent_expression_p (t))
9398 : break;
9399 13052 : else if (!omp_parse_expr (addr_tokens, t))
9400 : {
9401 0 : sorry_at (OMP_CLAUSE_LOCATION (c),
9402 : "unsupported map expression %qE",
9403 0 : OMP_CLAUSE_DECL (c));
9404 0 : remove = true;
9405 0 : break;
9406 : }
9407 13052 : if (t == error_mark_node)
9408 : {
9409 : remove = true;
9410 : break;
9411 : }
9412 : /* OpenACC attach / detach clauses must be pointers. */
9413 12958 : if (cp_oacc_check_attachments (c))
9414 : {
9415 : remove = true;
9416 : break;
9417 : }
9418 12934 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9419 9973 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9420 9924 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9421 13008 : && !OMP_CLAUSE_SIZE (c))
9422 : /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a
9423 : bias) to zero here, so it is not set erroneously to the
9424 : pointer size later on in gimplify.cc. */
9425 66 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9426 :
9427 12934 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9428 :
9429 12934 : if (!ai.check_clause (c))
9430 : {
9431 : remove = true;
9432 : break;
9433 : }
9434 :
9435 12913 : if (!ai.map_supported_p ())
9436 : {
9437 88 : sorry_at (OMP_CLAUSE_LOCATION (c),
9438 : "unsupported map expression %qE",
9439 44 : OMP_CLAUSE_DECL (c));
9440 44 : remove = true;
9441 44 : break;
9442 : }
9443 :
9444 25738 : gcc_assert ((addr_tokens[0]->type == ARRAY_BASE
9445 : || addr_tokens[0]->type == STRUCTURE_BASE)
9446 : && addr_tokens[1]->type == ACCESS_METHOD);
9447 :
9448 12869 : t = addr_tokens[1]->expr;
9449 :
9450 : /* This is used to prevent cxx_mark_addressable from being called
9451 : on 'this' for expressions like 'this->a', i.e. typical member
9452 : accesses. */
9453 12869 : indir_component_ref_p
9454 25738 : = (addr_tokens[0]->type == STRUCTURE_BASE
9455 12869 : && addr_tokens[1]->u.access_kind != ACCESS_DIRECT);
9456 :
9457 12869 : if (addr_tokens[0]->u.structure_base_kind != BASE_DECL)
9458 1 : goto skip_decl_checks;
9459 :
9460 : /* For OpenMP, we can access a struct "t" and "t.d" on the same
9461 : mapping. OpenACC allows multiple fields of the same structure
9462 : to be written. */
9463 12868 : if (addr_tokens[0]->type == STRUCTURE_BASE
9464 12868 : && (bitmap_bit_p (&map_field_head, DECL_UID (t))
9465 1197 : || (!openacc && bitmap_bit_p (&map_head, DECL_UID (t)))))
9466 1168 : goto skip_decl_checks;
9467 :
9468 11700 : if (!processing_template_decl && TREE_CODE (t) == FIELD_DECL)
9469 : {
9470 0 : OMP_CLAUSE_DECL (c)
9471 0 : = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
9472 0 : break;
9473 : }
9474 11700 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
9475 : {
9476 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9477 : break;
9478 0 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9479 0 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9480 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9481 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9482 0 : || (!openacc && EXPR_P (t))))
9483 : break;
9484 0 : if (DECL_P (t))
9485 0 : error_at (OMP_CLAUSE_LOCATION (c),
9486 : "%qD is not a variable in %qs clause", t,
9487 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9488 : else
9489 0 : error_at (OMP_CLAUSE_LOCATION (c),
9490 : "%qE is not a variable in %qs clause", t,
9491 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9492 : remove = true;
9493 : }
9494 11700 : else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
9495 : {
9496 0 : error_at (OMP_CLAUSE_LOCATION (c),
9497 : "%qD is threadprivate variable in %qs clause", t,
9498 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9499 0 : remove = true;
9500 : }
9501 11700 : else if (!processing_template_decl
9502 11524 : && !TYPE_REF_P (TREE_TYPE (t))
9503 10851 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9504 7940 : || (OMP_CLAUSE_MAP_KIND (c)
9505 : != GOMP_MAP_FIRSTPRIVATE_POINTER))
9506 8893 : && !indir_component_ref_p
9507 8529 : && (t != current_class_ptr
9508 18 : || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9509 6 : || OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
9510 20229 : && !cxx_mark_addressable (t))
9511 : remove = true;
9512 11700 : else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9513 8771 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9514 8771 : || (OMP_CLAUSE_MAP_KIND (c)
9515 : == GOMP_MAP_FIRSTPRIVATE_POINTER)
9516 6813 : || (OMP_CLAUSE_MAP_KIND (c)
9517 : == GOMP_MAP_ATTACH_DETACH)))
9518 9090 : && t == OMP_CLAUSE_DECL (c)
9519 8458 : && !type_dependent_expression_p (t)
9520 28616 : && !omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
9521 274 : ? TREE_TYPE (TREE_TYPE (t))
9522 8184 : : TREE_TYPE (t)))
9523 : {
9524 42 : auto_diagnostic_group d;
9525 84 : error_at (OMP_CLAUSE_LOCATION (c),
9526 : "%qD does not have a mappable type in %qs clause", t,
9527 42 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9528 42 : if (TREE_TYPE (t) != error_mark_node
9529 42 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9530 39 : cxx_incomplete_type_inform (TREE_TYPE (t));
9531 42 : remove = true;
9532 42 : }
9533 11658 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9534 8735 : && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR
9535 93 : && !type_dependent_expression_p (t)
9536 11751 : && !INDIRECT_TYPE_P (TREE_TYPE (t)))
9537 : {
9538 6 : error_at (OMP_CLAUSE_LOCATION (c),
9539 : "%qD is not a pointer variable", t);
9540 6 : remove = true;
9541 : }
9542 11652 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9543 8729 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9544 12055 : && (bitmap_bit_p (&map_head, DECL_UID (t))
9545 367 : || bitmap_bit_p (&map_field_head, DECL_UID (t))
9546 367 : || bitmap_bit_p (&map_firstprivate_head,
9547 367 : DECL_UID (t))))
9548 : remove = true;
9549 11613 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9550 11613 : && (OMP_CLAUSE_MAP_KIND (c)
9551 : == GOMP_MAP_FIRSTPRIVATE_POINTER))
9552 : {
9553 1952 : if (bitmap_bit_p (&generic_head, DECL_UID (t))
9554 1952 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9555 3901 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
9556 : {
9557 15 : error_at (OMP_CLAUSE_LOCATION (c),
9558 : "%qD appears more than once in data clauses", t);
9559 15 : remove = true;
9560 : }
9561 1937 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9562 12 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9563 1945 : && openacc)
9564 : {
9565 3 : error_at (OMP_CLAUSE_LOCATION (c),
9566 : "%qD appears more than once in data clauses", t);
9567 3 : remove = true;
9568 : }
9569 : else
9570 1934 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9571 : }
9572 9661 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9573 9661 : && (OMP_CLAUSE_MAP_KIND (c)
9574 : == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9575 115 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9576 9546 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9577 171 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9578 28 : && ort != C_ORT_OMP
9579 9574 : && ort != C_ORT_OMP_EXIT_DATA)
9580 : {
9581 18 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9582 0 : error_at (OMP_CLAUSE_LOCATION (c),
9583 : "%qD appears more than once in motion clauses", t);
9584 18 : else if (openacc)
9585 9 : error_at (OMP_CLAUSE_LOCATION (c),
9586 : "%qD appears more than once in data clauses", t);
9587 : else
9588 9 : error_at (OMP_CLAUSE_LOCATION (c),
9589 : "%qD appears more than once in map clauses", t);
9590 : remove = true;
9591 : }
9592 9528 : else if (openacc && bitmap_bit_p (&generic_head, DECL_UID (t)))
9593 : {
9594 0 : error_at (OMP_CLAUSE_LOCATION (c),
9595 : "%qD appears more than once in data clauses", t);
9596 0 : remove = true;
9597 : }
9598 9528 : else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9599 9528 : || bitmap_bit_p (&is_on_device_head, DECL_UID (t)))
9600 : {
9601 27 : if (openacc)
9602 0 : error_at (OMP_CLAUSE_LOCATION (c),
9603 : "%qD appears more than once in data clauses", t);
9604 : else
9605 27 : error_at (OMP_CLAUSE_LOCATION (c),
9606 : "%qD appears both in data and map clauses", t);
9607 : remove = true;
9608 : }
9609 9501 : else if (!omp_access_chain_p (addr_tokens, 1))
9610 : {
9611 9421 : bitmap_set_bit (&map_head, DECL_UID (t));
9612 :
9613 9421 : tree decl = OMP_CLAUSE_DECL (c);
9614 9421 : if (t != decl
9615 9421 : && (TREE_CODE (decl) == COMPONENT_REF
9616 162 : || (INDIRECT_REF_P (decl)
9617 162 : && (TREE_CODE (TREE_OPERAND (decl, 0))
9618 : == COMPONENT_REF)
9619 150 : && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (decl,
9620 : 0))))))
9621 1099 : bitmap_set_bit (&map_field_head, DECL_UID (t));
9622 : }
9623 :
9624 4383 : skip_decl_checks:
9625 : /* If we call ai.expand_map_clause in handle_omp_array_sections,
9626 : the containing loop (here) iterates through the new nodes
9627 : created by that expansion. Avoid expanding those again (just
9628 : by checking the node type). */
9629 4383 : if (!remove
9630 12719 : && !processing_template_decl
9631 12546 : && ort != C_ORT_DECLARE_SIMD
9632 12546 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9633 9603 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9634 7669 : && (OMP_CLAUSE_MAP_KIND (c)
9635 : != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9636 7554 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9637 7554 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9638 6563 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9639 6514 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)))
9640 : {
9641 9432 : grp_start_p = pc;
9642 9432 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9643 9432 : tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
9644 : addr_tokens, ort);
9645 9432 : if (nc != error_mark_node)
9646 9432 : c = nc;
9647 : }
9648 19763 : }
9649 12869 : break;
9650 :
9651 596 : case OMP_CLAUSE_ENTER:
9652 596 : case OMP_CLAUSE_LINK:
9653 596 : t = OMP_CLAUSE_DECL (c);
9654 596 : const char *cname;
9655 596 : cname = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9656 596 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER
9657 596 : && OMP_CLAUSE_ENTER_TO (c))
9658 : cname = "to";
9659 596 : if (TREE_CODE (t) == FUNCTION_DECL
9660 596 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9661 : ;
9662 379 : else if (!VAR_P (t))
9663 : {
9664 12 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9665 : {
9666 9 : if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
9667 6 : error_at (OMP_CLAUSE_LOCATION (c),
9668 : "template %qE in clause %qs", t, cname);
9669 3 : else if (really_overloaded_fn (t))
9670 3 : error_at (OMP_CLAUSE_LOCATION (c),
9671 : "overloaded function name %qE in clause %qs", t,
9672 : cname);
9673 : else
9674 0 : error_at (OMP_CLAUSE_LOCATION (c),
9675 : "%qE is neither a variable nor a function name "
9676 : "in clause %qs", t, cname);
9677 : }
9678 : else
9679 3 : error_at (OMP_CLAUSE_LOCATION (c),
9680 : "%qE is not a variable in clause %qs", t, cname);
9681 : remove = true;
9682 : }
9683 367 : else if (DECL_THREAD_LOCAL_P (t))
9684 : {
9685 6 : error_at (OMP_CLAUSE_LOCATION (c),
9686 : "%qD is threadprivate variable in %qs clause", t,
9687 : cname);
9688 6 : remove = true;
9689 : }
9690 361 : else if (!omp_mappable_type (TREE_TYPE (t)))
9691 : {
9692 18 : auto_diagnostic_group d;
9693 18 : error_at (OMP_CLAUSE_LOCATION (c),
9694 : "%qD does not have a mappable type in %qs clause", t,
9695 : cname);
9696 18 : if (TREE_TYPE (t) != error_mark_node
9697 18 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9698 18 : cxx_incomplete_type_inform (TREE_TYPE (t));
9699 18 : remove = true;
9700 18 : }
9701 24 : if (remove)
9702 : break;
9703 560 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
9704 : {
9705 24 : error_at (OMP_CLAUSE_LOCATION (c),
9706 : "%qE appears more than once on the same "
9707 : "%<declare target%> directive", t);
9708 24 : remove = true;
9709 : }
9710 : else
9711 536 : bitmap_set_bit (&generic_head, DECL_UID (t));
9712 : break;
9713 :
9714 457 : case OMP_CLAUSE_UNIFORM:
9715 457 : t = OMP_CLAUSE_DECL (c);
9716 457 : if (TREE_CODE (t) != PARM_DECL)
9717 : {
9718 0 : if (processing_template_decl)
9719 : break;
9720 0 : if (DECL_P (t))
9721 0 : error_at (OMP_CLAUSE_LOCATION (c),
9722 : "%qD is not an argument in %<uniform%> clause", t);
9723 : else
9724 0 : error_at (OMP_CLAUSE_LOCATION (c),
9725 : "%qE is not an argument in %<uniform%> clause", t);
9726 : remove = true;
9727 : break;
9728 : }
9729 : /* map_head bitmap is used as uniform_head if declare_simd. */
9730 457 : bitmap_set_bit (&map_head, DECL_UID (t));
9731 457 : goto check_dup_generic;
9732 :
9733 165 : case OMP_CLAUSE_GRAINSIZE:
9734 165 : t = OMP_CLAUSE_GRAINSIZE_EXPR (c);
9735 165 : if (t == error_mark_node)
9736 : remove = true;
9737 165 : else if (!type_dependent_expression_p (t)
9738 165 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9739 : {
9740 0 : error_at (OMP_CLAUSE_LOCATION (c),
9741 : "%<grainsize%> expression must be integral");
9742 0 : remove = true;
9743 : }
9744 : else
9745 : {
9746 165 : t = mark_rvalue_use (t);
9747 165 : if (!processing_template_decl)
9748 : {
9749 164 : t = maybe_constant_value (t);
9750 164 : if (TREE_CODE (t) == INTEGER_CST
9751 164 : && tree_int_cst_sgn (t) != 1)
9752 : {
9753 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9754 : "%<grainsize%> value must be positive");
9755 0 : t = integer_one_node;
9756 : }
9757 164 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9758 : }
9759 165 : OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
9760 : }
9761 : break;
9762 :
9763 276 : case OMP_CLAUSE_PRIORITY:
9764 276 : t = OMP_CLAUSE_PRIORITY_EXPR (c);
9765 276 : if (t == error_mark_node)
9766 : remove = true;
9767 276 : else if (!type_dependent_expression_p (t)
9768 276 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9769 : {
9770 0 : error_at (OMP_CLAUSE_LOCATION (c),
9771 : "%<priority%> expression must be integral");
9772 0 : remove = true;
9773 : }
9774 : else
9775 : {
9776 276 : t = mark_rvalue_use (t);
9777 276 : if (!processing_template_decl)
9778 : {
9779 276 : t = maybe_constant_value (t);
9780 276 : if (TREE_CODE (t) == INTEGER_CST
9781 276 : && tree_int_cst_sgn (t) == -1)
9782 : {
9783 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9784 : "%<priority%> value must be non-negative");
9785 0 : t = integer_one_node;
9786 : }
9787 276 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9788 : }
9789 276 : OMP_CLAUSE_PRIORITY_EXPR (c) = t;
9790 : }
9791 : break;
9792 :
9793 228 : case OMP_CLAUSE_HINT:
9794 228 : t = OMP_CLAUSE_HINT_EXPR (c);
9795 228 : if (t == error_mark_node)
9796 : remove = true;
9797 228 : else if (!type_dependent_expression_p (t)
9798 228 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9799 : {
9800 9 : error_at (OMP_CLAUSE_LOCATION (c),
9801 : "%<hint%> expression must be integral");
9802 9 : remove = true;
9803 : }
9804 : else
9805 : {
9806 219 : t = mark_rvalue_use (t);
9807 219 : if (!processing_template_decl)
9808 : {
9809 171 : t = maybe_constant_value (t);
9810 171 : if (TREE_CODE (t) != INTEGER_CST)
9811 : {
9812 16 : error_at (OMP_CLAUSE_LOCATION (c),
9813 : "%<hint%> expression must be constant integer "
9814 : "expression");
9815 16 : remove = true;
9816 : }
9817 : }
9818 219 : OMP_CLAUSE_HINT_EXPR (c) = t;
9819 : }
9820 : break;
9821 :
9822 186 : case OMP_CLAUSE_FILTER:
9823 186 : t = OMP_CLAUSE_FILTER_EXPR (c);
9824 186 : if (t == error_mark_node)
9825 : remove = true;
9826 186 : else if (!type_dependent_expression_p (t)
9827 186 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9828 : {
9829 6 : error_at (OMP_CLAUSE_LOCATION (c),
9830 : "%<filter%> expression must be integral");
9831 6 : remove = true;
9832 : }
9833 : else
9834 : {
9835 180 : t = mark_rvalue_use (t);
9836 180 : if (!processing_template_decl)
9837 : {
9838 177 : t = maybe_constant_value (t);
9839 177 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9840 : }
9841 180 : OMP_CLAUSE_FILTER_EXPR (c) = t;
9842 : }
9843 : break;
9844 :
9845 433 : case OMP_CLAUSE_IS_DEVICE_PTR:
9846 433 : case OMP_CLAUSE_USE_DEVICE_PTR:
9847 433 : field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
9848 433 : t = OMP_CLAUSE_DECL (c);
9849 433 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
9850 329 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
9851 433 : if (!type_dependent_expression_p (t))
9852 : {
9853 431 : tree type = TREE_TYPE (t);
9854 431 : if (!TYPE_PTR_P (type)
9855 431 : && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
9856 : {
9857 57 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
9858 57 : && ort == C_ORT_OMP)
9859 : {
9860 3 : error_at (OMP_CLAUSE_LOCATION (c),
9861 : "%qs variable is neither a pointer "
9862 : "nor reference to pointer",
9863 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9864 3 : remove = true;
9865 : }
9866 54 : else if (TREE_CODE (type) != ARRAY_TYPE
9867 54 : && (!TYPE_REF_P (type)
9868 2 : || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
9869 : {
9870 12 : error_at (OMP_CLAUSE_LOCATION (c),
9871 : "%qs variable is neither a pointer, nor an "
9872 : "array nor reference to pointer or array",
9873 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9874 12 : remove = true;
9875 : }
9876 : }
9877 : }
9878 433 : goto check_dup_generic;
9879 :
9880 267 : case OMP_CLAUSE_HAS_DEVICE_ADDR:
9881 267 : t = OMP_CLAUSE_DECL (c);
9882 267 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9883 : {
9884 28 : if (handle_omp_array_sections (c, ort))
9885 : remove = true;
9886 : else
9887 : {
9888 28 : t = OMP_CLAUSE_DECL (c);
9889 30 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
9890 2 : t = TREE_OPERAND (t, 0);
9891 64 : while (INDIRECT_REF_P (t)
9892 64 : || TREE_CODE (t) == ARRAY_REF)
9893 36 : t = TREE_OPERAND (t, 0);
9894 : }
9895 : }
9896 267 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
9897 : {
9898 267 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
9899 267 : if (!processing_template_decl
9900 267 : && !cxx_mark_addressable (t))
9901 : remove = true;
9902 : }
9903 267 : goto check_dup_generic_t;
9904 :
9905 76 : case OMP_CLAUSE_USE_DEVICE_ADDR:
9906 76 : field_ok = true;
9907 76 : t = OMP_CLAUSE_DECL (c);
9908 76 : if (!processing_template_decl
9909 74 : && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
9910 74 : && !TYPE_REF_P (TREE_TYPE (t))
9911 143 : && !cxx_mark_addressable (t))
9912 : remove = true;
9913 76 : goto check_dup_generic;
9914 :
9915 : case OMP_CLAUSE_NOWAIT:
9916 : case OMP_CLAUSE_DEFAULT:
9917 : case OMP_CLAUSE_UNTIED:
9918 : case OMP_CLAUSE_COLLAPSE:
9919 : case OMP_CLAUSE_PARALLEL:
9920 : case OMP_CLAUSE_FOR:
9921 : case OMP_CLAUSE_SECTIONS:
9922 : case OMP_CLAUSE_TASKGROUP:
9923 : case OMP_CLAUSE_PROC_BIND:
9924 : case OMP_CLAUSE_DEVICE_TYPE:
9925 : case OMP_CLAUSE_NOGROUP:
9926 : case OMP_CLAUSE_THREADS:
9927 : case OMP_CLAUSE_SIMD:
9928 : case OMP_CLAUSE_DEFAULTMAP:
9929 : case OMP_CLAUSE_BIND:
9930 : case OMP_CLAUSE_AUTO:
9931 : case OMP_CLAUSE_INDEPENDENT:
9932 : case OMP_CLAUSE_SEQ:
9933 : case OMP_CLAUSE_IF_PRESENT:
9934 : case OMP_CLAUSE_FINALIZE:
9935 : case OMP_CLAUSE_NOHOST:
9936 : case OMP_CLAUSE_INDIRECT:
9937 : break;
9938 :
9939 231 : case OMP_CLAUSE_MERGEABLE:
9940 231 : mergeable_seen = true;
9941 231 : break;
9942 :
9943 322 : case OMP_CLAUSE_TILE:
9944 754 : for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
9945 432 : list = TREE_CHAIN (list))
9946 : {
9947 432 : t = TREE_VALUE (list);
9948 :
9949 432 : if (t == error_mark_node)
9950 : remove = true;
9951 403 : else if (!type_dependent_expression_p (t)
9952 403 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9953 : {
9954 3 : error_at (OMP_CLAUSE_LOCATION (c),
9955 : "%<tile%> argument needs integral type");
9956 3 : remove = true;
9957 : }
9958 : else
9959 : {
9960 400 : t = mark_rvalue_use (t);
9961 400 : if (!processing_template_decl)
9962 : {
9963 : /* Zero is used to indicate '*', we permit you
9964 : to get there via an ICE of value zero. */
9965 385 : t = maybe_constant_value (t);
9966 385 : if (!tree_fits_shwi_p (t)
9967 369 : || tree_to_shwi (t) < 0)
9968 : {
9969 40 : error_at (OMP_CLAUSE_LOCATION (c),
9970 : "%<tile%> argument needs positive "
9971 : "integral constant");
9972 40 : remove = true;
9973 : }
9974 : }
9975 : }
9976 :
9977 : /* Update list item. */
9978 432 : TREE_VALUE (list) = t;
9979 : }
9980 : break;
9981 :
9982 1027 : case OMP_CLAUSE_SIZES:
9983 1027 : for (tree list = OMP_CLAUSE_SIZES_LIST (c);
9984 2688 : !remove && list; list = TREE_CHAIN (list))
9985 : {
9986 1661 : t = TREE_VALUE (list);
9987 :
9988 1661 : if (t == error_mark_node)
9989 0 : t = integer_one_node;
9990 1661 : else if (!type_dependent_expression_p (t)
9991 1661 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9992 : {
9993 8 : error_at (OMP_CLAUSE_LOCATION (c),
9994 : "%<sizes%> argument needs positive integral "
9995 : "constant");
9996 8 : t = integer_one_node;
9997 : }
9998 : else
9999 : {
10000 1653 : t = mark_rvalue_use (t);
10001 1653 : if (!processing_template_decl)
10002 : {
10003 1636 : t = maybe_constant_value (t);
10004 1636 : HOST_WIDE_INT n;
10005 1636 : if (!tree_fits_shwi_p (t)
10006 1632 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
10007 1632 : || (n = tree_to_shwi (t)) <= 0
10008 3240 : || (int)n != n)
10009 : {
10010 32 : error_at (OMP_CLAUSE_LOCATION (c),
10011 : "%<sizes%> argument needs positive "
10012 : "integral constant");
10013 32 : t = integer_one_node;
10014 : }
10015 : }
10016 : }
10017 :
10018 : /* Update list item. */
10019 1661 : TREE_VALUE (list) = t;
10020 : }
10021 : break;
10022 :
10023 630 : case OMP_CLAUSE_ORDERED:
10024 630 : ordered_seen = true;
10025 630 : break;
10026 :
10027 1549 : case OMP_CLAUSE_ORDER:
10028 1549 : if (order_seen)
10029 : remove = true;
10030 : else
10031 : order_seen = true;
10032 : break;
10033 :
10034 638 : case OMP_CLAUSE_INBRANCH:
10035 638 : case OMP_CLAUSE_NOTINBRANCH:
10036 638 : if (branch_seen)
10037 : {
10038 3 : error_at (OMP_CLAUSE_LOCATION (c),
10039 : "%<inbranch%> clause is incompatible with "
10040 : "%<notinbranch%>");
10041 3 : remove = true;
10042 : }
10043 : branch_seen = true;
10044 : break;
10045 :
10046 297 : case OMP_CLAUSE_INCLUSIVE:
10047 297 : case OMP_CLAUSE_EXCLUSIVE:
10048 297 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10049 297 : if (!t)
10050 297 : t = OMP_CLAUSE_DECL (c);
10051 297 : if (t == current_class_ptr)
10052 : {
10053 0 : error_at (OMP_CLAUSE_LOCATION (c),
10054 : "%<this%> allowed in OpenMP only in %<declare simd%>"
10055 : " clauses");
10056 0 : remove = true;
10057 0 : break;
10058 : }
10059 297 : if (!VAR_P (t)
10060 : && TREE_CODE (t) != PARM_DECL
10061 : && TREE_CODE (t) != FIELD_DECL)
10062 : {
10063 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
10064 : break;
10065 0 : if (DECL_P (t))
10066 0 : error_at (OMP_CLAUSE_LOCATION (c),
10067 : "%qD is not a variable in clause %qs", t,
10068 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10069 : else
10070 0 : error_at (OMP_CLAUSE_LOCATION (c),
10071 : "%qE is not a variable in clause %qs", t,
10072 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10073 : remove = true;
10074 : }
10075 : break;
10076 :
10077 : case OMP_CLAUSE_FULL:
10078 : break;
10079 :
10080 470 : case OMP_CLAUSE_PARTIAL:
10081 470 : partial_seen = true;
10082 470 : t = OMP_CLAUSE_PARTIAL_EXPR (c);
10083 470 : if (!t)
10084 : break;
10085 :
10086 313 : if (t == error_mark_node)
10087 : t = NULL_TREE;
10088 313 : else if (!type_dependent_expression_p (t)
10089 313 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10090 : {
10091 3 : error_at (OMP_CLAUSE_LOCATION (c),
10092 : "%<partial%> argument needs positive constant "
10093 : "integer expression");
10094 3 : t = NULL_TREE;
10095 : }
10096 : else
10097 : {
10098 310 : t = mark_rvalue_use (t);
10099 310 : if (!processing_template_decl)
10100 : {
10101 292 : t = maybe_constant_value (t);
10102 :
10103 292 : HOST_WIDE_INT n;
10104 584 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
10105 292 : || !tree_fits_shwi_p (t)
10106 286 : || (n = tree_to_shwi (t)) <= 0
10107 560 : || (int)n != n)
10108 : {
10109 24 : error_at (OMP_CLAUSE_LOCATION (c),
10110 : "%<partial%> argument needs positive "
10111 : "constant integer expression");
10112 24 : t = NULL_TREE;
10113 : }
10114 : }
10115 : }
10116 :
10117 313 : OMP_CLAUSE_PARTIAL_EXPR (c) = t;
10118 313 : break;
10119 549 : case OMP_CLAUSE_INIT:
10120 549 : init_seen = true;
10121 549 : OMP_CLAUSE_INIT_PREFER_TYPE (c)
10122 549 : = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c));
10123 549 : if (!OMP_CLAUSE_INIT_TARGETSYNC (c))
10124 271 : init_no_targetsync_clause = c;
10125 : /* FALLTHRU */
10126 844 : case OMP_CLAUSE_DESTROY:
10127 844 : case OMP_CLAUSE_USE:
10128 844 : init_use_destroy_seen = true;
10129 844 : t = OMP_CLAUSE_DECL (c);
10130 844 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
10131 : {
10132 9 : error_at (OMP_CLAUSE_LOCATION (c),
10133 : "%qD appears more than once in action clauses", t);
10134 9 : remove = true;
10135 9 : break;
10136 : }
10137 835 : bitmap_set_bit (&generic_head, DECL_UID (t));
10138 : /* FALLTHRU */
10139 1099 : case OMP_CLAUSE_INTEROP:
10140 1099 : if (!processing_template_decl)
10141 : {
10142 1003 : if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
10143 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) && */
10144 1003 : !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
10145 : {
10146 126 : error_at (OMP_CLAUSE_LOCATION (c),
10147 : "%qD must be of %<omp_interop_t%>",
10148 63 : OMP_CLAUSE_DECL (c));
10149 63 : remove = true;
10150 : }
10151 940 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
10152 481 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
10153 1058 : && TREE_READONLY (OMP_CLAUSE_DECL (c)))
10154 : {
10155 36 : error_at (OMP_CLAUSE_LOCATION (c),
10156 18 : "%qD shall not be const", OMP_CLAUSE_DECL (c));
10157 18 : remove = true;
10158 : }
10159 : }
10160 1099 : pc = &OMP_CLAUSE_CHAIN (c);
10161 1099 : break;
10162 0 : default:
10163 0 : gcc_unreachable ();
10164 54 : }
10165 :
10166 97092 : if (remove)
10167 : {
10168 2601 : if (grp_start_p)
10169 : {
10170 : /* If we found a clause to remove, we want to remove the whole
10171 : expanded group, otherwise gimplify
10172 : (omp_resolve_clause_dependencies) can get confused. */
10173 820 : *grp_start_p = grp_sentinel;
10174 820 : pc = grp_start_p;
10175 820 : grp_start_p = NULL;
10176 : }
10177 : else
10178 1781 : *pc = OMP_CLAUSE_CHAIN (c);
10179 : }
10180 : else
10181 94491 : pc = &OMP_CLAUSE_CHAIN (c);
10182 : }
10183 :
10184 62504 : if (grp_start_p
10185 62504 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
10186 131 : for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc))
10187 80 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
10188 :
10189 62504 : if (reduction_seen < 0 && (ordered_seen || schedule_seen))
10190 62504 : reduction_seen = -2;
10191 :
10192 157952 : for (pc = &clauses, c = clauses; c ; c = *pc)
10193 : {
10194 95448 : enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
10195 95448 : bool remove = false;
10196 95448 : bool need_complete_type = false;
10197 95448 : bool need_default_ctor = false;
10198 95448 : bool need_copy_ctor = false;
10199 95448 : bool need_copy_assignment = false;
10200 95448 : bool need_implicitly_determined = false;
10201 95448 : bool need_dtor = false;
10202 95448 : tree type, inner_type;
10203 :
10204 95448 : switch (c_kind)
10205 : {
10206 : case OMP_CLAUSE_SHARED:
10207 : need_implicitly_determined = true;
10208 : break;
10209 2540 : case OMP_CLAUSE_PRIVATE:
10210 2540 : need_complete_type = true;
10211 2540 : need_default_ctor = true;
10212 2540 : need_dtor = true;
10213 2540 : need_implicitly_determined = true;
10214 2540 : break;
10215 3156 : case OMP_CLAUSE_FIRSTPRIVATE:
10216 3156 : need_complete_type = true;
10217 3156 : need_copy_ctor = true;
10218 3156 : need_dtor = true;
10219 3156 : need_implicitly_determined = true;
10220 3156 : break;
10221 2763 : case OMP_CLAUSE_LASTPRIVATE:
10222 2763 : need_complete_type = true;
10223 2763 : need_copy_assignment = true;
10224 2763 : need_implicitly_determined = true;
10225 2763 : break;
10226 7286 : case OMP_CLAUSE_REDUCTION:
10227 7286 : if (reduction_seen == -2)
10228 27 : OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
10229 7286 : if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10230 421 : need_copy_assignment = true;
10231 : need_implicitly_determined = true;
10232 : break;
10233 : case OMP_CLAUSE_IN_REDUCTION:
10234 : case OMP_CLAUSE_TASK_REDUCTION:
10235 : case OMP_CLAUSE_INCLUSIVE:
10236 : case OMP_CLAUSE_EXCLUSIVE:
10237 : need_implicitly_determined = true;
10238 : break;
10239 1550 : case OMP_CLAUSE_LINEAR:
10240 1550 : if (ort != C_ORT_OMP_DECLARE_SIMD)
10241 : need_implicitly_determined = true;
10242 679 : else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
10243 721 : && !bitmap_bit_p (&map_head,
10244 42 : DECL_UID (OMP_CLAUSE_LINEAR_STEP (c))))
10245 : {
10246 6 : error_at (OMP_CLAUSE_LOCATION (c),
10247 : "%<linear%> clause step is a parameter %qD not "
10248 : "specified in %<uniform%> clause",
10249 6 : OMP_CLAUSE_LINEAR_STEP (c));
10250 6 : *pc = OMP_CLAUSE_CHAIN (c);
10251 73922 : continue;
10252 : }
10253 : break;
10254 : case OMP_CLAUSE_COPYPRIVATE:
10255 366 : need_copy_assignment = true;
10256 : break;
10257 : case OMP_CLAUSE_COPYIN:
10258 366 : need_copy_assignment = true;
10259 : break;
10260 798 : case OMP_CLAUSE_SIMDLEN:
10261 798 : if (safelen
10262 345 : && !processing_template_decl
10263 1143 : && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
10264 345 : OMP_CLAUSE_SIMDLEN_EXPR (c)))
10265 : {
10266 0 : error_at (OMP_CLAUSE_LOCATION (c),
10267 : "%<simdlen%> clause value is bigger than "
10268 : "%<safelen%> clause value");
10269 0 : OMP_CLAUSE_SIMDLEN_EXPR (c)
10270 0 : = OMP_CLAUSE_SAFELEN_EXPR (safelen);
10271 : }
10272 798 : pc = &OMP_CLAUSE_CHAIN (c);
10273 798 : continue;
10274 3853 : case OMP_CLAUSE_SCHEDULE:
10275 3853 : if (ordered_seen
10276 3853 : && (OMP_CLAUSE_SCHEDULE_KIND (c)
10277 : & OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
10278 : {
10279 21 : error_at (OMP_CLAUSE_LOCATION (c),
10280 : "%<nonmonotonic%> schedule modifier specified "
10281 : "together with %<ordered%> clause");
10282 42 : OMP_CLAUSE_SCHEDULE_KIND (c)
10283 21 : = (enum omp_clause_schedule_kind)
10284 21 : (OMP_CLAUSE_SCHEDULE_KIND (c)
10285 : & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
10286 : }
10287 3853 : if (reduction_seen == -2)
10288 9 : error_at (OMP_CLAUSE_LOCATION (c),
10289 : "%qs clause specified together with %<inscan%> "
10290 : "%<reduction%> clause", "schedule");
10291 3853 : pc = &OMP_CLAUSE_CHAIN (c);
10292 3853 : continue;
10293 51 : case OMP_CLAUSE_NOGROUP:
10294 51 : if (reduction_seen)
10295 : {
10296 3 : error_at (OMP_CLAUSE_LOCATION (c),
10297 : "%<nogroup%> clause must not be used together with "
10298 : "%<reduction%> clause");
10299 3 : *pc = OMP_CLAUSE_CHAIN (c);
10300 3 : continue;
10301 : }
10302 48 : pc = &OMP_CLAUSE_CHAIN (c);
10303 48 : continue;
10304 165 : case OMP_CLAUSE_GRAINSIZE:
10305 165 : if (num_tasks_seen)
10306 : {
10307 6 : error_at (OMP_CLAUSE_LOCATION (c),
10308 : "%<grainsize%> clause must not be used together with "
10309 : "%<num_tasks%> clause");
10310 6 : *pc = OMP_CLAUSE_CHAIN (c);
10311 6 : continue;
10312 : }
10313 159 : pc = &OMP_CLAUSE_CHAIN (c);
10314 159 : continue;
10315 630 : case OMP_CLAUSE_ORDERED:
10316 630 : if (reduction_seen == -2)
10317 6 : error_at (OMP_CLAUSE_LOCATION (c),
10318 : "%qs clause specified together with %<inscan%> "
10319 : "%<reduction%> clause", "ordered");
10320 630 : pc = &OMP_CLAUSE_CHAIN (c);
10321 630 : continue;
10322 1525 : case OMP_CLAUSE_ORDER:
10323 1525 : if (ordered_seen)
10324 : {
10325 12 : error_at (OMP_CLAUSE_LOCATION (c),
10326 : "%<order%> clause must not be used together "
10327 : "with %<ordered%> clause");
10328 12 : *pc = OMP_CLAUSE_CHAIN (c);
10329 12 : continue;
10330 : }
10331 1513 : pc = &OMP_CLAUSE_CHAIN (c);
10332 1513 : continue;
10333 57 : case OMP_CLAUSE_DETACH:
10334 57 : if (mergeable_seen)
10335 : {
10336 6 : error_at (OMP_CLAUSE_LOCATION (c),
10337 : "%<detach%> clause must not be used together with "
10338 : "%<mergeable%> clause");
10339 6 : *pc = OMP_CLAUSE_CHAIN (c);
10340 6 : continue;
10341 : }
10342 51 : pc = &OMP_CLAUSE_CHAIN (c);
10343 51 : continue;
10344 15642 : case OMP_CLAUSE_MAP:
10345 15642 : if (target_in_reduction_seen && !processing_template_decl)
10346 : {
10347 684 : t = OMP_CLAUSE_DECL (c);
10348 684 : while (handled_component_p (t)
10349 : || INDIRECT_REF_P (t)
10350 : || TREE_CODE (t) == ADDR_EXPR
10351 : || TREE_CODE (t) == MEM_REF
10352 804 : || TREE_CODE (t) == NON_LVALUE_EXPR)
10353 120 : t = TREE_OPERAND (t, 0);
10354 684 : if (DECL_P (t)
10355 684 : && bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
10356 342 : OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10357 : }
10358 15642 : pc = &OMP_CLAUSE_CHAIN (c);
10359 15642 : continue;
10360 225 : case OMP_CLAUSE_FULL:
10361 225 : if (partial_seen)
10362 : {
10363 12 : error_at (OMP_CLAUSE_LOCATION (c),
10364 : "%<full%> clause must not be used together "
10365 : "with %<partial%> clause");
10366 12 : *pc = OMP_CLAUSE_CHAIN (c);
10367 12 : continue;
10368 : }
10369 213 : pc = &OMP_CLAUSE_CHAIN (c);
10370 213 : continue;
10371 6894 : case OMP_CLAUSE_NOWAIT:
10372 6894 : if (copyprivate_seen)
10373 : {
10374 6 : error_at (OMP_CLAUSE_LOCATION (c),
10375 : "%<nowait%> clause must not be used together "
10376 : "with %<copyprivate%> clause");
10377 6 : *pc = OMP_CLAUSE_CHAIN (c);
10378 6 : continue;
10379 : }
10380 : /* FALLTHRU */
10381 50326 : default:
10382 50326 : pc = &OMP_CLAUSE_CHAIN (c);
10383 50326 : continue;
10384 : }
10385 :
10386 22164 : t = OMP_CLAUSE_DECL (c);
10387 22164 : switch (c_kind)
10388 : {
10389 2763 : case OMP_CLAUSE_LASTPRIVATE:
10390 2763 : if (DECL_P (t)
10391 2763 : && !bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
10392 : {
10393 2666 : need_default_ctor = true;
10394 2666 : need_dtor = true;
10395 : }
10396 : break;
10397 :
10398 9425 : case OMP_CLAUSE_REDUCTION:
10399 9425 : case OMP_CLAUSE_IN_REDUCTION:
10400 9425 : case OMP_CLAUSE_TASK_REDUCTION:
10401 9425 : if (allocate_seen)
10402 : {
10403 1561 : if (TREE_CODE (t) == MEM_REF)
10404 : {
10405 162 : t = TREE_OPERAND (t, 0);
10406 162 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
10407 0 : t = TREE_OPERAND (t, 0);
10408 162 : if (TREE_CODE (t) == ADDR_EXPR
10409 120 : || INDIRECT_REF_P (t))
10410 80 : t = TREE_OPERAND (t, 0);
10411 162 : if (DECL_P (t))
10412 162 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10413 : }
10414 1399 : else if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10415 : {
10416 192 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10417 96 : t = TREE_OPERAND (t, 0);
10418 96 : if (DECL_P (t))
10419 96 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10420 96 : t = OMP_CLAUSE_DECL (c);
10421 : }
10422 1303 : else if (DECL_P (t))
10423 1303 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10424 1561 : t = OMP_CLAUSE_DECL (c);
10425 : }
10426 9425 : if (processing_template_decl
10427 863 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10428 : break;
10429 8855 : if (finish_omp_reduction_clause (c, &need_default_ctor,
10430 : &need_dtor))
10431 : remove = true;
10432 : else
10433 8771 : t = OMP_CLAUSE_DECL (c);
10434 : break;
10435 :
10436 274 : case OMP_CLAUSE_COPYIN:
10437 274 : if (processing_template_decl
10438 0 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10439 : break;
10440 274 : if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t))
10441 : {
10442 15 : error_at (OMP_CLAUSE_LOCATION (c),
10443 : "%qE must be %<threadprivate%> for %<copyin%>", t);
10444 15 : remove = true;
10445 : }
10446 : break;
10447 :
10448 : default:
10449 : break;
10450 : }
10451 :
10452 22164 : if (processing_template_decl
10453 1544 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10454 : {
10455 632 : pc = &OMP_CLAUSE_CHAIN (c);
10456 632 : continue;
10457 : }
10458 :
10459 21532 : if (need_complete_type || need_copy_assignment)
10460 : {
10461 9190 : t = require_complete_type (t);
10462 9190 : if (t == error_mark_node)
10463 : remove = true;
10464 9166 : else if (!processing_template_decl
10465 8783 : && TYPE_REF_P (TREE_TYPE (t))
10466 9722 : && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
10467 : remove = true;
10468 : }
10469 21532 : if (need_implicitly_determined)
10470 : {
10471 20494 : const char *share_name = NULL;
10472 :
10473 20494 : if (allocate_seen
10474 4993 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10475 24608 : && DECL_P (t))
10476 3904 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10477 :
10478 20494 : if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
10479 : share_name = "threadprivate";
10480 20452 : else switch (cxx_omp_predetermined_sharing_1 (t))
10481 : {
10482 : case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
10483 : break;
10484 47 : case OMP_CLAUSE_DEFAULT_SHARED:
10485 47 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10486 30 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10487 64 : && c_omp_predefined_variable (t))
10488 : /* The __func__ variable and similar function-local predefined
10489 : variables may be listed in a shared or firstprivate
10490 : clause. */
10491 : break;
10492 31 : if (VAR_P (t)
10493 31 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10494 9 : && TREE_STATIC (t)
10495 40 : && cxx_omp_const_qual_no_mutable (t))
10496 : {
10497 6 : tree ctx = CP_DECL_CONTEXT (t);
10498 : /* const qualified static data members without mutable
10499 : member may be specified in firstprivate clause. */
10500 6 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
10501 : break;
10502 : }
10503 : share_name = "shared";
10504 : break;
10505 : case OMP_CLAUSE_DEFAULT_PRIVATE:
10506 : share_name = "private";
10507 : break;
10508 0 : default:
10509 0 : gcc_unreachable ();
10510 : }
10511 : if (share_name)
10512 : {
10513 67 : error_at (OMP_CLAUSE_LOCATION (c),
10514 : "%qE is predetermined %qs for %qs",
10515 : omp_clause_printable_decl (t), share_name,
10516 67 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10517 67 : remove = true;
10518 : }
10519 20427 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10520 18368 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
10521 35668 : && cxx_omp_const_qual_no_mutable (t))
10522 : {
10523 126 : error_at (OMP_CLAUSE_LOCATION (c),
10524 : "%<const%> qualified %qE without %<mutable%> member "
10525 : "may appear only in %<shared%> or %<firstprivate%> "
10526 : "clauses", omp_clause_printable_decl (t));
10527 63 : remove = true;
10528 : }
10529 : }
10530 :
10531 21532 : if (detach_seen
10532 16 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10533 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
10534 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10535 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10536 21548 : && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen))
10537 : {
10538 6 : error_at (OMP_CLAUSE_LOCATION (c),
10539 : "the event handle of a %<detach%> clause "
10540 : "should not be in a data-sharing clause");
10541 6 : remove = true;
10542 : }
10543 :
10544 : /* We're interested in the base element, not arrays. */
10545 21532 : inner_type = type = TREE_TYPE (t);
10546 21532 : if ((need_complete_type
10547 : || need_copy_assignment
10548 12342 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10549 5708 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10550 4235 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10551 29966 : && TYPE_REF_P (inner_type))
10552 878 : inner_type = TREE_TYPE (inner_type);
10553 24113 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
10554 2581 : inner_type = TREE_TYPE (inner_type);
10555 :
10556 : /* Check for special function availability by building a call to one.
10557 : Save the results, because later we won't be in the right context
10558 : for making these queries. */
10559 2387 : if (CLASS_TYPE_P (inner_type)
10560 2387 : && COMPLETE_TYPE_P (inner_type)
10561 2318 : && (need_default_ctor || need_copy_ctor
10562 1081 : || need_copy_assignment || need_dtor)
10563 1994 : && !type_dependent_expression_p (t)
10564 23526 : && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
10565 : need_copy_ctor, need_copy_assignment,
10566 : need_dtor))
10567 : remove = true;
10568 :
10569 21532 : if (!remove
10570 21532 : && c_kind == OMP_CLAUSE_SHARED
10571 2056 : && processing_template_decl)
10572 : {
10573 125 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10574 125 : if (t)
10575 5 : OMP_CLAUSE_DECL (c) = t;
10576 : }
10577 :
10578 21532 : if (remove)
10579 292 : *pc = OMP_CLAUSE_CHAIN (c);
10580 : else
10581 21240 : pc = &OMP_CLAUSE_CHAIN (c);
10582 : }
10583 :
10584 62504 : if (allocate_seen)
10585 16828 : for (pc = &clauses, c = clauses; c ; c = *pc)
10586 : {
10587 14544 : bool remove = false;
10588 14544 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
10589 2540 : && !OMP_CLAUSE_ALLOCATE_COMBINED (c)
10590 2143 : && DECL_P (OMP_CLAUSE_DECL (c))
10591 16687 : && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c))))
10592 : {
10593 15 : error_at (OMP_CLAUSE_LOCATION (c),
10594 : "%qD specified in %<allocate%> clause but not in "
10595 15 : "an explicit privatization clause", OMP_CLAUSE_DECL (c));
10596 15 : remove = true;
10597 : }
10598 14544 : if (remove)
10599 15 : *pc = OMP_CLAUSE_CHAIN (c);
10600 : else
10601 14529 : pc = &OMP_CLAUSE_CHAIN (c);
10602 : }
10603 :
10604 62504 : if (ort == C_ORT_OMP_INTEROP
10605 62504 : && depend_clause
10606 60 : && (!init_use_destroy_seen
10607 57 : || (init_seen && init_no_targetsync_clause)))
10608 : {
10609 9 : error_at (OMP_CLAUSE_LOCATION (depend_clause),
10610 : "%<depend%> clause requires action clauses with "
10611 : "%<targetsync%> interop-type");
10612 9 : if (init_no_targetsync_clause)
10613 6 : inform (OMP_CLAUSE_LOCATION (init_no_targetsync_clause),
10614 : "%<init%> clause lacks the %<targetsync%> modifier");
10615 : }
10616 :
10617 62504 : bitmap_obstack_release (NULL);
10618 62504 : return clauses;
10619 : }
10620 :
10621 : /* Start processing OpenMP clauses that can include any
10622 : privatization clauses for non-static data members. */
10623 :
10624 : tree
10625 48371 : push_omp_privatization_clauses (bool ignore_next)
10626 : {
10627 48371 : if (omp_private_member_ignore_next)
10628 : {
10629 656 : omp_private_member_ignore_next = ignore_next;
10630 656 : return NULL_TREE;
10631 : }
10632 47715 : omp_private_member_ignore_next = ignore_next;
10633 47715 : if (omp_private_member_map)
10634 24 : omp_private_member_vec.safe_push (error_mark_node);
10635 47715 : return push_stmt_list ();
10636 : }
10637 :
10638 : /* Revert remapping of any non-static data members since
10639 : the last push_omp_privatization_clauses () call. */
10640 :
10641 : void
10642 48365 : pop_omp_privatization_clauses (tree stmt)
10643 : {
10644 48365 : if (stmt == NULL_TREE)
10645 : return;
10646 47709 : stmt = pop_stmt_list (stmt);
10647 47709 : if (omp_private_member_map)
10648 : {
10649 1280 : while (!omp_private_member_vec.is_empty ())
10650 : {
10651 850 : tree t = omp_private_member_vec.pop ();
10652 850 : if (t == error_mark_node)
10653 : {
10654 24 : add_stmt (stmt);
10655 24 : return;
10656 : }
10657 826 : bool no_decl_expr = t == integer_zero_node;
10658 826 : if (no_decl_expr)
10659 136 : t = omp_private_member_vec.pop ();
10660 826 : tree *v = omp_private_member_map->get (t);
10661 826 : gcc_assert (v);
10662 826 : if (!no_decl_expr)
10663 690 : add_decl_expr (*v);
10664 826 : omp_private_member_map->remove (t);
10665 : }
10666 860 : delete omp_private_member_map;
10667 430 : omp_private_member_map = NULL;
10668 : }
10669 47685 : add_stmt (stmt);
10670 : }
10671 :
10672 : /* Remember OpenMP privatization clauses mapping and clear it.
10673 : Used for lambdas. */
10674 :
10675 : void
10676 19929953 : save_omp_privatization_clauses (vec<tree> &save)
10677 : {
10678 19929953 : save = vNULL;
10679 19929953 : if (omp_private_member_ignore_next)
10680 2 : save.safe_push (integer_one_node);
10681 19929953 : omp_private_member_ignore_next = false;
10682 19929953 : if (!omp_private_member_map)
10683 : return;
10684 :
10685 0 : while (!omp_private_member_vec.is_empty ())
10686 : {
10687 0 : tree t = omp_private_member_vec.pop ();
10688 0 : if (t == error_mark_node)
10689 : {
10690 0 : save.safe_push (t);
10691 0 : continue;
10692 : }
10693 0 : tree n = t;
10694 0 : if (t == integer_zero_node)
10695 0 : t = omp_private_member_vec.pop ();
10696 0 : tree *v = omp_private_member_map->get (t);
10697 0 : gcc_assert (v);
10698 0 : save.safe_push (*v);
10699 0 : save.safe_push (t);
10700 0 : if (n != t)
10701 0 : save.safe_push (n);
10702 : }
10703 0 : delete omp_private_member_map;
10704 0 : omp_private_member_map = NULL;
10705 : }
10706 :
10707 : /* Restore OpenMP privatization clauses mapping saved by the
10708 : above function. */
10709 :
10710 : void
10711 19929953 : restore_omp_privatization_clauses (vec<tree> &save)
10712 : {
10713 19929953 : gcc_assert (omp_private_member_vec.is_empty ());
10714 19929953 : omp_private_member_ignore_next = false;
10715 19929953 : if (save.is_empty ())
10716 : return;
10717 4 : if (save.length () == 1 && save[0] == integer_one_node)
10718 : {
10719 2 : omp_private_member_ignore_next = true;
10720 2 : save.release ();
10721 2 : return;
10722 : }
10723 :
10724 0 : omp_private_member_map = new hash_map <tree, tree>;
10725 0 : while (!save.is_empty ())
10726 : {
10727 0 : tree t = save.pop ();
10728 0 : tree n = t;
10729 0 : if (t != error_mark_node)
10730 : {
10731 0 : if (t == integer_one_node)
10732 : {
10733 0 : omp_private_member_ignore_next = true;
10734 0 : gcc_assert (save.is_empty ());
10735 0 : break;
10736 : }
10737 0 : if (t == integer_zero_node)
10738 0 : t = save.pop ();
10739 0 : tree &v = omp_private_member_map->get_or_insert (t);
10740 0 : v = save.pop ();
10741 : }
10742 0 : omp_private_member_vec.safe_push (t);
10743 0 : if (n != t)
10744 0 : omp_private_member_vec.safe_push (n);
10745 : }
10746 0 : save.release ();
10747 : }
10748 :
10749 : /* For all variables in the tree_list VARS, mark them as thread local. */
10750 :
10751 : void
10752 238 : finish_omp_threadprivate (tree vars)
10753 : {
10754 238 : tree t;
10755 :
10756 : /* Mark every variable in VARS to be assigned thread local storage. */
10757 509 : for (t = vars; t; t = TREE_CHAIN (t))
10758 : {
10759 271 : tree v = TREE_PURPOSE (t);
10760 271 : location_t loc = EXPR_LOCATION (TREE_VALUE (t));
10761 :
10762 271 : if (error_operand_p (v))
10763 : ;
10764 271 : else if (!VAR_P (v))
10765 6 : error_at (loc, "%<threadprivate%> %qD is not file, namespace "
10766 : "or block scope variable", v);
10767 : /* If V had already been marked threadprivate, it doesn't matter
10768 : whether it had been used prior to this point. */
10769 265 : else if (TREE_USED (v)
10770 265 : && (DECL_LANG_SPECIFIC (v) == NULL
10771 3 : || !CP_DECL_THREADPRIVATE_P (v)))
10772 6 : error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10773 259 : else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10774 6 : error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10775 253 : else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v))))
10776 3 : error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10777 201 : else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))
10778 273 : && CP_DECL_CONTEXT (v) != current_class_type)
10779 6 : error_at (loc, "%<threadprivate%> %qE directive not "
10780 6 : "in %qT definition", v, CP_DECL_CONTEXT (v));
10781 : else
10782 : {
10783 : /* Allocate a LANG_SPECIFIC structure for V, if needed. */
10784 244 : if (DECL_LANG_SPECIFIC (v) == NULL)
10785 200 : retrofit_lang_decl (v);
10786 :
10787 244 : if (! CP_DECL_THREAD_LOCAL_P (v))
10788 : {
10789 244 : CP_DECL_THREAD_LOCAL_P (v) = true;
10790 244 : set_decl_tls_model (v, decl_default_tls_model (v));
10791 : /* If rtl has been already set for this var, call
10792 : make_decl_rtl once again, so that encode_section_info
10793 : has a chance to look at the new decl flags. */
10794 244 : if (DECL_RTL_SET_P (v))
10795 0 : make_decl_rtl (v);
10796 : }
10797 244 : CP_DECL_THREADPRIVATE_P (v) = 1;
10798 : }
10799 : }
10800 238 : }
10801 :
10802 : /* Build an OpenMP structured block. */
10803 :
10804 : tree
10805 63930 : begin_omp_structured_block (void)
10806 : {
10807 63930 : return do_pushlevel (sk_omp);
10808 : }
10809 :
10810 : tree
10811 63909 : finish_omp_structured_block (tree block)
10812 : {
10813 63909 : return do_poplevel (block);
10814 : }
10815 :
10816 : /* Similarly, except force the retention of the BLOCK. */
10817 :
10818 : tree
10819 14796 : begin_omp_parallel (void)
10820 : {
10821 14796 : keep_next_level (true);
10822 14796 : return begin_omp_structured_block ();
10823 : }
10824 :
10825 : /* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
10826 : statement. */
10827 :
10828 : tree
10829 768 : finish_oacc_data (tree clauses, tree block)
10830 : {
10831 768 : tree stmt;
10832 :
10833 768 : block = finish_omp_structured_block (block);
10834 :
10835 768 : stmt = make_node (OACC_DATA);
10836 768 : TREE_TYPE (stmt) = void_type_node;
10837 768 : OACC_DATA_CLAUSES (stmt) = clauses;
10838 768 : OACC_DATA_BODY (stmt) = block;
10839 :
10840 768 : return add_stmt (stmt);
10841 : }
10842 :
10843 : /* Generate OACC_HOST_DATA, with CLAUSES and BLOCK as its compound
10844 : statement. */
10845 :
10846 : tree
10847 55 : finish_oacc_host_data (tree clauses, tree block)
10848 : {
10849 55 : tree stmt;
10850 :
10851 55 : block = finish_omp_structured_block (block);
10852 :
10853 55 : stmt = make_node (OACC_HOST_DATA);
10854 55 : TREE_TYPE (stmt) = void_type_node;
10855 55 : OACC_HOST_DATA_CLAUSES (stmt) = clauses;
10856 55 : OACC_HOST_DATA_BODY (stmt) = block;
10857 :
10858 55 : return add_stmt (stmt);
10859 : }
10860 :
10861 : /* Generate OMP construct CODE, with BODY and CLAUSES as its compound
10862 : statement. */
10863 :
10864 : tree
10865 4653 : finish_omp_construct (enum tree_code code, tree body, tree clauses)
10866 : {
10867 4653 : body = finish_omp_structured_block (body);
10868 :
10869 4653 : tree stmt = make_node (code);
10870 4653 : TREE_TYPE (stmt) = void_type_node;
10871 4653 : OMP_BODY (stmt) = body;
10872 4653 : OMP_CLAUSES (stmt) = clauses;
10873 :
10874 4653 : return add_stmt (stmt);
10875 : }
10876 :
10877 : /* Used to walk OpenMP target directive body. */
10878 :
10879 : struct omp_target_walk_data
10880 : {
10881 : /* Holds the 'this' expression found in current function. */
10882 : tree current_object;
10883 :
10884 : /* True if the 'this' expression was accessed in the target body. */
10885 : bool this_expr_accessed;
10886 :
10887 : /* For non-static functions, record which pointer-typed members were
10888 : accessed, and the whole expression. */
10889 : hash_map<tree, tree> ptr_members_accessed;
10890 :
10891 : /* Record which lambda objects were accessed in target body. */
10892 : hash_set<tree> lambda_objects_accessed;
10893 :
10894 : /* For lambda functions, the __closure object expression of the current
10895 : function, and the set of captured variables accessed in target body. */
10896 : tree current_closure;
10897 : hash_set<tree> closure_vars_accessed;
10898 :
10899 : /* Local variables declared inside a BIND_EXPR, used to filter out such
10900 : variables when recording lambda_objects_accessed. */
10901 : hash_set<tree> local_decls;
10902 :
10903 : omp_mapper_list<tree> *mappers;
10904 : };
10905 :
10906 : /* Helper function of finish_omp_target_clauses, called via
10907 : cp_walk_tree_without_duplicates. Traverse body of OpenMP target
10908 : directive *TP, and fill out omp_target_walk_data passed in *PTR. */
10909 :
10910 : static tree
10911 226276 : finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr)
10912 : {
10913 226276 : tree t = *tp;
10914 226276 : struct omp_target_walk_data *data = (struct omp_target_walk_data *) ptr;
10915 226276 : tree current_object = data->current_object;
10916 226276 : tree current_closure = data->current_closure;
10917 226276 : omp_mapper_list<tree> *mlist = data->mappers;
10918 :
10919 : /* References inside of these expression codes shouldn't incur any
10920 : form of mapping, so return early. */
10921 226276 : if (TREE_CODE (t) == SIZEOF_EXPR
10922 226268 : || TREE_CODE (t) == ALIGNOF_EXPR)
10923 : {
10924 8 : *walk_subtrees = 0;
10925 8 : return NULL_TREE;
10926 : }
10927 :
10928 226268 : if (TREE_CODE (t) == OMP_CLAUSE)
10929 : return NULL_TREE;
10930 :
10931 213683 : if (!processing_template_decl)
10932 : {
10933 213683 : tree aggr_type = NULL_TREE;
10934 :
10935 213683 : if (TREE_CODE (t) == COMPONENT_REF
10936 213683 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
10937 2233 : aggr_type = TREE_TYPE (TREE_OPERAND (t, 0));
10938 211450 : else if ((TREE_CODE (t) == VAR_DECL
10939 : || TREE_CODE (t) == PARM_DECL
10940 : || TREE_CODE (t) == RESULT_DECL)
10941 16813 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
10942 1208 : aggr_type = TREE_TYPE (t);
10943 :
10944 3441 : if (aggr_type)
10945 : {
10946 3441 : tree mapper_fn = cxx_omp_mapper_lookup (NULL_TREE, aggr_type);
10947 3441 : if (mapper_fn)
10948 167 : mlist->add_mapper (NULL_TREE, aggr_type, mapper_fn);
10949 : }
10950 : }
10951 :
10952 213683 : if (current_object)
10953 : {
10954 2564 : tree this_expr = TREE_OPERAND (current_object, 0);
10955 :
10956 2564 : if (operand_equal_p (t, this_expr))
10957 : {
10958 35 : data->this_expr_accessed = true;
10959 35 : *walk_subtrees = 0;
10960 35 : return NULL_TREE;
10961 : }
10962 :
10963 2529 : if (TREE_CODE (t) == COMPONENT_REF
10964 115 : && POINTER_TYPE_P (TREE_TYPE (t))
10965 36 : && operand_equal_p (TREE_OPERAND (t, 0), current_object)
10966 2563 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL)
10967 : {
10968 34 : data->this_expr_accessed = true;
10969 34 : tree fld = TREE_OPERAND (t, 1);
10970 34 : if (data->ptr_members_accessed.get (fld) == NULL)
10971 : {
10972 14 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
10973 4 : t = convert_from_reference (t);
10974 14 : data->ptr_members_accessed.put (fld, t);
10975 : }
10976 34 : *walk_subtrees = 0;
10977 34 : return NULL_TREE;
10978 : }
10979 : }
10980 :
10981 : /* When the current_function_decl is a lambda function, the closure object
10982 : argument's type seems to not yet have fields layed out, so a recording
10983 : of DECL_VALUE_EXPRs during the target body walk seems the only way to
10984 : find them. */
10985 213614 : if (current_closure
10986 300 : && (VAR_P (t)
10987 : || TREE_CODE (t) == PARM_DECL
10988 : || TREE_CODE (t) == RESULT_DECL)
10989 24 : && DECL_HAS_VALUE_EXPR_P (t)
10990 10 : && TREE_CODE (DECL_VALUE_EXPR (t)) == COMPONENT_REF
10991 213624 : && operand_equal_p (current_closure,
10992 10 : TREE_OPERAND (DECL_VALUE_EXPR (t), 0)))
10993 : {
10994 9 : if (!data->closure_vars_accessed.contains (t))
10995 9 : data->closure_vars_accessed.add (t);
10996 9 : *walk_subtrees = 0;
10997 9 : return NULL_TREE;
10998 : }
10999 :
11000 213605 : if (TREE_CODE (t) == BIND_EXPR)
11001 : {
11002 19903 : if (tree block = BIND_EXPR_BLOCK (t))
11003 22296 : for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
11004 2397 : if (!data->local_decls.contains (var))
11005 2397 : data->local_decls.add (var);
11006 19903 : return NULL_TREE;
11007 : }
11008 :
11009 198274 : if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
11010 : {
11011 39 : tree lt = TREE_TYPE (t);
11012 39 : gcc_assert (CLASS_TYPE_P (lt));
11013 :
11014 39 : if (!data->lambda_objects_accessed.contains (t)
11015 : /* Do not prepare to create target maps for locally declared
11016 : lambdas or anonymous ones. */
11017 39 : && !data->local_decls.contains (t)
11018 72 : && TREE_CODE (t) != TARGET_EXPR)
11019 13 : data->lambda_objects_accessed.add (t);
11020 39 : *walk_subtrees = 0;
11021 39 : return NULL_TREE;
11022 : }
11023 :
11024 : return NULL_TREE;
11025 : }
11026 :
11027 : /* Helper function for finish_omp_target, and also from tsubst_expr.
11028 : Create additional clauses for mapping of non-static members, lambda objects,
11029 : etc. */
11030 :
11031 : void
11032 6933 : finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr)
11033 : {
11034 6933 : omp_target_walk_data data;
11035 6933 : data.this_expr_accessed = false;
11036 6933 : data.current_object = NULL_TREE;
11037 :
11038 6933 : if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr)
11039 96 : if (tree ct = current_nonlambda_class_type ())
11040 : {
11041 95 : tree object = maybe_dummy_object (ct, NULL);
11042 95 : object = maybe_resolve_dummy (object, true);
11043 95 : data.current_object = object;
11044 : }
11045 :
11046 6933 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11047 : {
11048 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11049 8 : data.current_closure = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11050 : }
11051 : else
11052 6925 : data.current_closure = NULL_TREE;
11053 :
11054 6933 : auto_vec<tree, 16> new_clauses;
11055 :
11056 6933 : if (!processing_template_decl)
11057 : {
11058 6933 : hash_set<omp_name_type<tree> > seen_types;
11059 6933 : auto_vec<tree> mapper_fns;
11060 6933 : omp_mapper_list<tree> mlist (&seen_types, &mapper_fns);
11061 6933 : data.mappers = &mlist;
11062 :
11063 6933 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11064 : &data);
11065 :
11066 6933 : unsigned int i;
11067 6933 : tree mapper_fn;
11068 13952 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11069 86 : c_omp_find_nested_mappers (&mlist, mapper_fn);
11070 :
11071 7082 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11072 : {
11073 86 : tree mapper = cxx_omp_extract_mapper_directive (mapper_fn);
11074 86 : if (mapper == error_mark_node)
11075 0 : continue;
11076 86 : tree mapper_name = OMP_DECLARE_MAPPER_ID (mapper);
11077 86 : tree decl = OMP_DECLARE_MAPPER_DECL (mapper);
11078 86 : if (BASELINK_P (mapper_fn))
11079 0 : mapper_fn = BASELINK_FUNCTIONS (mapper_fn);
11080 :
11081 86 : tree c = build_omp_clause (loc, OMP_CLAUSE__MAPPER_BINDING_);
11082 86 : OMP_CLAUSE__MAPPER_BINDING__ID (c) = mapper_name;
11083 86 : OMP_CLAUSE__MAPPER_BINDING__DECL (c) = decl;
11084 86 : OMP_CLAUSE__MAPPER_BINDING__MAPPER (c) = mapper_fn;
11085 :
11086 86 : new_clauses.safe_push (c);
11087 : }
11088 6933 : }
11089 : else
11090 : {
11091 0 : data.mappers = NULL;
11092 0 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11093 : &data);
11094 : }
11095 :
11096 6933 : tree omp_target_this_expr = NULL_TREE;
11097 6933 : tree *explicit_this_deref_map = NULL;
11098 6933 : if (data.this_expr_accessed)
11099 : {
11100 31 : omp_target_this_expr = TREE_OPERAND (data.current_object, 0);
11101 :
11102 : /* See if explicit user-specified map(this[:]) clause already exists.
11103 : If not, we create an implicit map(tofrom:this[:1]) clause. */
11104 80 : for (tree *cp = clauses_ptr; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
11105 50 : if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
11106 47 : && (TREE_CODE (OMP_CLAUSE_DECL (*cp)) == INDIRECT_REF
11107 40 : || TREE_CODE (OMP_CLAUSE_DECL (*cp)) == MEM_REF)
11108 57 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*cp), 0),
11109 : omp_target_this_expr))
11110 : {
11111 : explicit_this_deref_map = cp;
11112 : break;
11113 : }
11114 : }
11115 :
11116 6933 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11117 6933 : && (data.this_expr_accessed
11118 1 : || !data.closure_vars_accessed.is_empty ()))
11119 : {
11120 : /* For lambda functions, we need to first create a copy of the
11121 : __closure object. */
11122 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11123 8 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11124 8 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11125 8 : OMP_CLAUSE_DECL (c)
11126 8 : = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11127 8 : OMP_CLAUSE_SIZE (c)
11128 8 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure)));
11129 8 : new_clauses.safe_push (c);
11130 :
11131 8 : tree closure_obj = OMP_CLAUSE_DECL (c);
11132 8 : tree closure_type = TREE_TYPE (closure_obj);
11133 :
11134 16 : gcc_assert (LAMBDA_TYPE_P (closure_type)
11135 : && CLASS_TYPE_P (closure_type));
11136 :
11137 8 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11138 8 : OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
11139 8 : OMP_CLAUSE_DECL (c2) = closure;
11140 8 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11141 8 : new_clauses.safe_push (c2);
11142 : }
11143 :
11144 6933 : if (data.this_expr_accessed)
11145 : {
11146 : /* If the this-expr was accessed, create a map(*this) clause. */
11147 31 : enum gomp_map_kind kind = GOMP_MAP_TOFROM;
11148 31 : if (explicit_this_deref_map)
11149 : {
11150 1 : tree this_map = *explicit_this_deref_map;
11151 1 : tree nc = OMP_CLAUSE_CHAIN (this_map);
11152 2 : gcc_assert (nc != NULL_TREE
11153 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11154 : && (OMP_CLAUSE_MAP_KIND (nc)
11155 : == GOMP_MAP_FIRSTPRIVATE_POINTER));
11156 1 : kind = OMP_CLAUSE_MAP_KIND (this_map);
11157 : /* Remove the original 'map(*this) map(firstprivate_ptr:this)'
11158 : two-map sequence away from the chain. */
11159 1 : *explicit_this_deref_map = OMP_CLAUSE_CHAIN (nc);
11160 : }
11161 31 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11162 31 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11163 31 : OMP_CLAUSE_DECL (c)
11164 31 : = build_indirect_ref (loc, omp_target_this_expr, RO_UNARY_STAR);
11165 31 : OMP_CLAUSE_SIZE (c)
11166 31 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (omp_target_this_expr)));
11167 31 : new_clauses.safe_push (c);
11168 :
11169 : /* If we're in a lambda function, the this-pointer will actually be
11170 : '__closure->this', a mapped member of __closure, hence always_pointer.
11171 : Otherwise it's a firstprivate pointer. */
11172 31 : enum gomp_map_kind ptr_kind
11173 31 : = (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11174 31 : ? GOMP_MAP_ALWAYS_POINTER
11175 24 : : GOMP_MAP_FIRSTPRIVATE_POINTER);
11176 31 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11177 31 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11178 31 : OMP_CLAUSE_DECL (c) = omp_target_this_expr;
11179 31 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11180 31 : new_clauses.safe_push (c);
11181 : }
11182 :
11183 6933 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11184 : {
11185 8 : if (omp_target_this_expr)
11186 : {
11187 7 : STRIP_NOPS (omp_target_this_expr);
11188 7 : gcc_assert (DECL_HAS_VALUE_EXPR_P (omp_target_this_expr));
11189 7 : omp_target_this_expr = DECL_VALUE_EXPR (omp_target_this_expr);
11190 : }
11191 :
11192 17 : for (hash_set<tree>::iterator i = data.closure_vars_accessed.begin ();
11193 34 : i != data.closure_vars_accessed.end (); ++i)
11194 : {
11195 9 : tree orig_decl = *i;
11196 9 : tree closure_expr = DECL_VALUE_EXPR (orig_decl);
11197 :
11198 9 : if (TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE
11199 9 : || TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE)
11200 : {
11201 : /* this-pointer is processed above, outside this loop. */
11202 3 : if (omp_target_this_expr
11203 3 : && operand_equal_p (closure_expr, omp_target_this_expr))
11204 0 : continue;
11205 :
11206 3 : bool ptr_p = TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE;
11207 3 : enum gomp_map_kind kind, ptr_kind, nc_kind;
11208 3 : tree size;
11209 :
11210 3 : if (ptr_p)
11211 : {
11212 : /* For pointers, default mapped as zero-length array
11213 : section. */
11214 2 : kind = GOMP_MAP_ALLOC;
11215 2 : nc_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
11216 2 : ptr_kind = GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
11217 2 : size = size_zero_node;
11218 : }
11219 : else
11220 : {
11221 : /* For references, default mapped as appearing on map
11222 : clause. */
11223 1 : kind = GOMP_MAP_TOFROM;
11224 1 : nc_kind = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
11225 1 : ptr_kind = GOMP_MAP_ALWAYS_POINTER;
11226 1 : size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure_expr)));
11227 : }
11228 :
11229 6 : for (tree *p = clauses_ptr; *p; p = &OMP_CLAUSE_CHAIN (*p))
11230 3 : if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_MAP
11231 1 : && (TREE_CODE (OMP_CLAUSE_DECL (*p)) == INDIRECT_REF
11232 1 : || TREE_CODE (OMP_CLAUSE_DECL (*p)) == MEM_REF)
11233 3 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*p), 0),
11234 : orig_decl))
11235 : {
11236 : /* If this was already specified by user as a map,
11237 : save the user specified map kind, delete the
11238 : "map(*ptr/ref), map(firstprivate ptr/ref)" sequence,
11239 : and insert our own sequence:
11240 : "map(*__closure->ptr/ref), map(<ptr_kind>:__closure->ref"
11241 : */
11242 0 : tree nc = OMP_CLAUSE_CHAIN (*p);
11243 0 : gcc_assert (nc != NULL_TREE
11244 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11245 : && OMP_CLAUSE_MAP_KIND (nc) == nc_kind);
11246 : /* Update with user specified kind and size. */
11247 0 : kind = OMP_CLAUSE_MAP_KIND (*p);
11248 0 : size = OMP_CLAUSE_SIZE (*p);
11249 0 : *p = OMP_CLAUSE_CHAIN (nc);
11250 0 : break;
11251 : }
11252 :
11253 3 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11254 3 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11255 3 : OMP_CLAUSE_DECL (c)
11256 3 : = build_indirect_ref (loc, closure_expr, RO_UNARY_STAR);
11257 3 : OMP_CLAUSE_SIZE (c) = size;
11258 3 : if (ptr_p)
11259 2 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11260 3 : new_clauses.safe_push (c);
11261 :
11262 3 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11263 3 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11264 3 : OMP_CLAUSE_DECL (c) = closure_expr;
11265 3 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11266 3 : new_clauses.safe_push (c);
11267 : }
11268 : }
11269 : }
11270 :
11271 6933 : if (!data.ptr_members_accessed.is_empty ())
11272 14 : for (hash_map<tree, tree>::iterator i = data.ptr_members_accessed.begin ();
11273 56 : i != data.ptr_members_accessed.end (); ++i)
11274 : {
11275 : /* For each referenced member that is of pointer or reference-to-pointer
11276 : type, create the equivalent of map(alloc:this->ptr[:0]). */
11277 14 : tree field_decl = (*i).first;
11278 14 : tree ptr_member = (*i).second;
11279 :
11280 26 : for (tree c = *clauses_ptr; c; c = OMP_CLAUSE_CHAIN (c))
11281 : {
11282 16 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
11283 2 : continue;
11284 : /* If map(this->ptr[:N]) already exists, avoid creating another
11285 : such map. */
11286 14 : tree decl = OMP_CLAUSE_DECL (c);
11287 14 : if ((TREE_CODE (decl) == INDIRECT_REF
11288 10 : || TREE_CODE (decl) == MEM_REF)
11289 14 : && operand_equal_p (TREE_OPERAND (decl, 0), ptr_member))
11290 4 : goto next_ptr_member;
11291 : }
11292 :
11293 10 : if (!cxx_mark_addressable (ptr_member))
11294 0 : gcc_unreachable ();
11295 :
11296 10 : if (TREE_CODE (TREE_TYPE (field_decl)) == REFERENCE_TYPE)
11297 : {
11298 : /* For reference to pointers, we need to map the referenced
11299 : pointer first for things to be correct. */
11300 4 : tree ptr_member_type = TREE_TYPE (ptr_member);
11301 :
11302 : /* Map pointer target as zero-length array section. */
11303 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11304 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11305 4 : OMP_CLAUSE_DECL (c)
11306 4 : = build1 (INDIRECT_REF, TREE_TYPE (ptr_member_type), ptr_member);
11307 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11308 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11309 :
11310 : /* Map pointer to zero-length array section. */
11311 4 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11312 4 : OMP_CLAUSE_SET_MAP_KIND
11313 : (c2, GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION);
11314 4 : OMP_CLAUSE_DECL (c2) = ptr_member;
11315 4 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11316 :
11317 : /* Attach reference-to-pointer field to pointer. */
11318 4 : tree c3 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11319 4 : OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH);
11320 4 : OMP_CLAUSE_DECL (c3) = TREE_OPERAND (ptr_member, 0);
11321 4 : OMP_CLAUSE_SIZE (c3) = size_zero_node;
11322 :
11323 4 : new_clauses.safe_push (c);
11324 4 : new_clauses.safe_push (c2);
11325 4 : new_clauses.safe_push (c3);
11326 : }
11327 6 : else if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
11328 : {
11329 : /* Map pointer target as zero-length array section. */
11330 6 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11331 6 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11332 6 : OMP_CLAUSE_DECL (c) = build_indirect_ref (loc, ptr_member,
11333 : RO_UNARY_STAR);
11334 6 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11335 6 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11336 :
11337 : /* Attach zero-length array section to pointer. */
11338 6 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11339 6 : OMP_CLAUSE_SET_MAP_KIND
11340 : (c2, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11341 6 : OMP_CLAUSE_DECL (c2) = ptr_member;
11342 6 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11343 :
11344 6 : new_clauses.safe_push (c);
11345 6 : new_clauses.safe_push (c2);
11346 : }
11347 : else
11348 0 : gcc_unreachable ();
11349 :
11350 14 : next_ptr_member:
11351 14 : ;
11352 : }
11353 :
11354 6946 : for (hash_set<tree>::iterator i = data.lambda_objects_accessed.begin ();
11355 6959 : i != data.lambda_objects_accessed.end (); ++i)
11356 : {
11357 13 : tree lobj = *i;
11358 13 : if (TREE_CODE (lobj) == TARGET_EXPR)
11359 0 : lobj = TARGET_EXPR_SLOT (lobj);
11360 :
11361 13 : tree lt = TREE_TYPE (lobj);
11362 26 : gcc_assert (LAMBDA_TYPE_P (lt) && CLASS_TYPE_P (lt));
11363 :
11364 13 : tree lc = build_omp_clause (loc, OMP_CLAUSE_MAP);
11365 13 : OMP_CLAUSE_SET_MAP_KIND (lc, GOMP_MAP_TO);
11366 13 : OMP_CLAUSE_DECL (lc) = lobj;
11367 13 : OMP_CLAUSE_SIZE (lc) = TYPE_SIZE_UNIT (lt);
11368 13 : new_clauses.safe_push (lc);
11369 :
11370 180 : for (tree fld = TYPE_FIELDS (lt); fld; fld = DECL_CHAIN (fld))
11371 : {
11372 167 : if (TREE_CODE (TREE_TYPE (fld)) == POINTER_TYPE)
11373 : {
11374 4 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11375 : lobj, fld, NULL_TREE);
11376 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11377 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11378 4 : OMP_CLAUSE_DECL (c)
11379 4 : = build_indirect_ref (loc, exp, RO_UNARY_STAR);
11380 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11381 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11382 4 : new_clauses.safe_push (c);
11383 :
11384 4 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11385 4 : OMP_CLAUSE_SET_MAP_KIND
11386 : (c, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11387 4 : OMP_CLAUSE_DECL (c) = exp;
11388 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11389 4 : new_clauses.safe_push (c);
11390 : }
11391 163 : else if (TREE_CODE (TREE_TYPE (fld)) == REFERENCE_TYPE)
11392 : {
11393 0 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11394 : lobj, fld, NULL_TREE);
11395 0 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11396 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11397 0 : OMP_CLAUSE_DECL (c)
11398 0 : = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
11399 0 : OMP_CLAUSE_SIZE (c)
11400 0 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (exp)));
11401 0 : new_clauses.safe_push (c);
11402 :
11403 0 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11404 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
11405 0 : OMP_CLAUSE_DECL (c) = exp;
11406 0 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11407 0 : new_clauses.safe_push (c);
11408 : }
11409 : }
11410 : }
11411 :
11412 6933 : tree c = *clauses_ptr;
11413 14081 : for (int i = new_clauses.length () - 1; i >= 0; i--)
11414 : {
11415 215 : OMP_CLAUSE_CHAIN (new_clauses[i]) = c;
11416 215 : c = new_clauses[i];
11417 : }
11418 6933 : *clauses_ptr = c;
11419 6933 : }
11420 :
11421 : /* Called from cp_parser_omp_target. Create additional implicit clauses for
11422 : OpenMP target directives, and do sanity checks. */
11423 :
11424 : tree
11425 6921 : finish_omp_target (location_t loc, tree clauses, tree body, bool combined_p)
11426 : {
11427 6921 : if (!processing_template_decl)
11428 6108 : finish_omp_target_clauses (loc, body, &clauses);
11429 :
11430 6921 : tree stmt = make_node (OMP_TARGET);
11431 6921 : TREE_TYPE (stmt) = void_type_node;
11432 6921 : OMP_TARGET_CLAUSES (stmt) = clauses;
11433 6921 : OMP_TARGET_BODY (stmt) = body;
11434 6921 : OMP_TARGET_COMBINED (stmt) = combined_p;
11435 6921 : SET_EXPR_LOCATION (stmt, loc);
11436 :
11437 6921 : tree c = clauses;
11438 16520 : while (c)
11439 : {
11440 9599 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11441 5532 : switch (OMP_CLAUSE_MAP_KIND (c))
11442 : {
11443 : case GOMP_MAP_TO:
11444 : case GOMP_MAP_ALWAYS_TO:
11445 : case GOMP_MAP_PRESENT_TO:
11446 : case GOMP_MAP_ALWAYS_PRESENT_TO:
11447 : case GOMP_MAP_FROM:
11448 : case GOMP_MAP_ALWAYS_FROM:
11449 : case GOMP_MAP_PRESENT_FROM:
11450 : case GOMP_MAP_ALWAYS_PRESENT_FROM:
11451 : case GOMP_MAP_TOFROM:
11452 : case GOMP_MAP_ALWAYS_TOFROM:
11453 : case GOMP_MAP_PRESENT_TOFROM:
11454 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
11455 : case GOMP_MAP_ALLOC:
11456 : case GOMP_MAP_PRESENT_ALLOC:
11457 : case GOMP_MAP_FIRSTPRIVATE_POINTER:
11458 : case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
11459 : case GOMP_MAP_ALWAYS_POINTER:
11460 : case GOMP_MAP_ATTACH_DETACH:
11461 : case GOMP_MAP_ATTACH:
11462 : case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
11463 : case GOMP_MAP_POINTER:
11464 : case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
11465 : break;
11466 3 : default:
11467 3 : error_at (OMP_CLAUSE_LOCATION (c),
11468 : "%<#pragma omp target%> with map-type other "
11469 : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
11470 : "on %<map%> clause");
11471 3 : break;
11472 : }
11473 9599 : c = OMP_CLAUSE_CHAIN (c);
11474 : }
11475 6921 : return add_stmt (stmt);
11476 : }
11477 :
11478 : tree
11479 9320 : finish_omp_parallel (tree clauses, tree body)
11480 : {
11481 9320 : tree stmt;
11482 :
11483 9320 : body = finish_omp_structured_block (body);
11484 :
11485 9320 : stmt = make_node (OMP_PARALLEL);
11486 9320 : TREE_TYPE (stmt) = void_type_node;
11487 9320 : OMP_PARALLEL_CLAUSES (stmt) = clauses;
11488 9320 : OMP_PARALLEL_BODY (stmt) = body;
11489 :
11490 9320 : return add_stmt (stmt);
11491 : }
11492 :
11493 : tree
11494 2160 : begin_omp_task (void)
11495 : {
11496 2160 : keep_next_level (true);
11497 2160 : return begin_omp_structured_block ();
11498 : }
11499 :
11500 : tree
11501 2160 : finish_omp_task (tree clauses, tree body)
11502 : {
11503 2160 : tree stmt;
11504 :
11505 2160 : body = finish_omp_structured_block (body);
11506 :
11507 2160 : stmt = make_node (OMP_TASK);
11508 2160 : TREE_TYPE (stmt) = void_type_node;
11509 2160 : OMP_TASK_CLAUSES (stmt) = clauses;
11510 2160 : OMP_TASK_BODY (stmt) = body;
11511 :
11512 2160 : return add_stmt (stmt);
11513 : }
11514 :
11515 : /* Helper function for finish_omp_for. Convert Ith random access iterator
11516 : into integral iterator. Return FALSE if successful. */
11517 :
11518 : static bool
11519 813 : handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
11520 : tree declv, tree orig_declv, tree initv,
11521 : tree condv, tree incrv, tree *body,
11522 : tree *pre_body, tree &clauses,
11523 : int collapse, int ordered)
11524 : {
11525 813 : tree diff, iter_init, iter_incr = NULL, last;
11526 813 : tree incr_var = NULL, orig_pre_body, orig_body, c;
11527 813 : tree decl = TREE_VEC_ELT (declv, i);
11528 813 : tree init = TREE_VEC_ELT (initv, i);
11529 813 : tree cond = TREE_VEC_ELT (condv, i);
11530 813 : tree incr = TREE_VEC_ELT (incrv, i);
11531 813 : tree iter = decl;
11532 813 : location_t elocus = locus;
11533 :
11534 813 : if (init && EXPR_HAS_LOCATION (init))
11535 12 : elocus = EXPR_LOCATION (init);
11536 :
11537 813 : switch (TREE_CODE (cond))
11538 : {
11539 810 : case GT_EXPR:
11540 810 : case GE_EXPR:
11541 810 : case LT_EXPR:
11542 810 : case LE_EXPR:
11543 810 : case NE_EXPR:
11544 810 : if (TREE_OPERAND (cond, 1) == iter)
11545 42 : cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
11546 42 : TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
11547 810 : if (TREE_OPERAND (cond, 0) != iter)
11548 0 : cond = error_mark_node;
11549 : else
11550 : {
11551 810 : tree tem = build_x_binary_op (EXPR_LOCATION (cond),
11552 810 : TREE_CODE (cond),
11553 : iter, ERROR_MARK,
11554 810 : TREE_OPERAND (cond, 1), ERROR_MARK,
11555 : NULL_TREE, NULL, tf_warning_or_error);
11556 810 : if (error_operand_p (tem))
11557 : return true;
11558 : }
11559 : break;
11560 3 : default:
11561 3 : cond = error_mark_node;
11562 3 : break;
11563 : }
11564 810 : if (cond == error_mark_node)
11565 : {
11566 3 : error_at (elocus, "invalid controlling predicate");
11567 3 : return true;
11568 : }
11569 807 : diff = build_x_binary_op (elocus, MINUS_EXPR,
11570 807 : TREE_OPERAND (cond, 1), ERROR_MARK,
11571 : iter, ERROR_MARK,
11572 : NULL_TREE, NULL, tf_warning_or_error);
11573 807 : diff = cp_fully_fold (diff);
11574 807 : if (error_operand_p (diff))
11575 : return true;
11576 807 : if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
11577 : {
11578 0 : error_at (elocus, "difference between %qE and %qD does not have integer type",
11579 0 : TREE_OPERAND (cond, 1), iter);
11580 0 : return true;
11581 : }
11582 807 : if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
11583 807 : TREE_VEC_ELT (declv, i), NULL_TREE,
11584 : cond, cp_walk_subtrees))
11585 : return true;
11586 :
11587 762 : switch (TREE_CODE (incr))
11588 : {
11589 370 : case PREINCREMENT_EXPR:
11590 370 : case PREDECREMENT_EXPR:
11591 370 : case POSTINCREMENT_EXPR:
11592 370 : case POSTDECREMENT_EXPR:
11593 370 : if (TREE_OPERAND (incr, 0) != iter)
11594 : {
11595 0 : incr = error_mark_node;
11596 0 : break;
11597 : }
11598 370 : iter_incr = build_x_unary_op (EXPR_LOCATION (incr),
11599 370 : TREE_CODE (incr), iter,
11600 : NULL_TREE, tf_warning_or_error);
11601 370 : if (error_operand_p (iter_incr))
11602 : return true;
11603 370 : else if (TREE_CODE (incr) == PREINCREMENT_EXPR
11604 219 : || TREE_CODE (incr) == POSTINCREMENT_EXPR)
11605 299 : incr = integer_one_node;
11606 : else
11607 71 : incr = integer_minus_one_node;
11608 : break;
11609 392 : case MODIFY_EXPR:
11610 392 : if (TREE_OPERAND (incr, 0) != iter)
11611 0 : incr = error_mark_node;
11612 392 : else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
11613 392 : || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
11614 : {
11615 392 : tree rhs = TREE_OPERAND (incr, 1);
11616 392 : if (TREE_OPERAND (rhs, 0) == iter)
11617 : {
11618 299 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
11619 : != INTEGER_TYPE)
11620 0 : incr = error_mark_node;
11621 : else
11622 : {
11623 299 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11624 299 : iter, TREE_CODE (rhs),
11625 299 : TREE_OPERAND (rhs, 1),
11626 : NULL_TREE,
11627 : tf_warning_or_error);
11628 299 : if (error_operand_p (iter_incr))
11629 : return true;
11630 299 : incr = TREE_OPERAND (rhs, 1);
11631 299 : incr = cp_convert (TREE_TYPE (diff), incr,
11632 : tf_warning_or_error);
11633 299 : if (TREE_CODE (rhs) == MINUS_EXPR)
11634 : {
11635 16 : incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
11636 16 : incr = fold_simple (incr);
11637 : }
11638 299 : if (TREE_CODE (incr) != INTEGER_CST
11639 299 : && (TREE_CODE (incr) != NOP_EXPR
11640 66 : || (TREE_CODE (TREE_OPERAND (incr, 0))
11641 : != INTEGER_CST)))
11642 : iter_incr = NULL;
11643 : }
11644 : }
11645 93 : else if (TREE_OPERAND (rhs, 1) == iter)
11646 : {
11647 93 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
11648 93 : || TREE_CODE (rhs) != PLUS_EXPR)
11649 0 : incr = error_mark_node;
11650 : else
11651 : {
11652 93 : iter_incr = build_x_binary_op (EXPR_LOCATION (rhs),
11653 : PLUS_EXPR,
11654 93 : TREE_OPERAND (rhs, 0),
11655 : ERROR_MARK, iter,
11656 : ERROR_MARK, NULL_TREE, NULL,
11657 : tf_warning_or_error);
11658 93 : if (error_operand_p (iter_incr))
11659 : return true;
11660 93 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11661 : iter, NOP_EXPR,
11662 : iter_incr, NULL_TREE,
11663 : tf_warning_or_error);
11664 93 : if (error_operand_p (iter_incr))
11665 : return true;
11666 93 : incr = TREE_OPERAND (rhs, 0);
11667 93 : iter_incr = NULL;
11668 : }
11669 : }
11670 : else
11671 0 : incr = error_mark_node;
11672 : }
11673 : else
11674 0 : incr = error_mark_node;
11675 : break;
11676 0 : default:
11677 0 : incr = error_mark_node;
11678 0 : break;
11679 : }
11680 :
11681 762 : if (incr == error_mark_node)
11682 : {
11683 0 : error_at (elocus, "invalid increment expression");
11684 0 : return true;
11685 : }
11686 :
11687 762 : incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
11688 762 : incr = cp_fully_fold (incr);
11689 762 : tree loop_iv_seen = NULL_TREE;
11690 1735 : for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11691 1093 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11692 1093 : && OMP_CLAUSE_DECL (c) == iter)
11693 : {
11694 120 : if (code == OMP_TASKLOOP || code == OMP_LOOP)
11695 : {
11696 60 : loop_iv_seen = c;
11697 60 : OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
11698 : }
11699 : break;
11700 : }
11701 973 : else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
11702 113 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
11703 1007 : && OMP_CLAUSE_DECL (c) == iter)
11704 : {
11705 30 : loop_iv_seen = c;
11706 30 : if (code == OMP_TASKLOOP)
11707 25 : OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
11708 : }
11709 :
11710 762 : decl = create_temporary_var (TREE_TYPE (diff));
11711 762 : pushdecl (decl);
11712 762 : add_decl_expr (decl);
11713 762 : last = create_temporary_var (TREE_TYPE (diff));
11714 762 : pushdecl (last);
11715 762 : add_decl_expr (last);
11716 762 : if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST
11717 10 : && (!ordered || (i < collapse && collapse > 1)))
11718 : {
11719 10 : incr_var = create_temporary_var (TREE_TYPE (diff));
11720 10 : pushdecl (incr_var);
11721 10 : add_decl_expr (incr_var);
11722 : }
11723 762 : gcc_assert (stmts_are_full_exprs_p ());
11724 762 : tree diffvar = NULL_TREE;
11725 762 : if (code == OMP_TASKLOOP)
11726 : {
11727 101 : if (!loop_iv_seen)
11728 : {
11729 38 : tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11730 38 : OMP_CLAUSE_DECL (ivc) = iter;
11731 38 : cxx_omp_finish_clause (ivc, NULL, false);
11732 38 : OMP_CLAUSE_CHAIN (ivc) = clauses;
11733 38 : clauses = ivc;
11734 : }
11735 101 : tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11736 101 : OMP_CLAUSE_DECL (lvc) = last;
11737 101 : OMP_CLAUSE_CHAIN (lvc) = clauses;
11738 101 : clauses = lvc;
11739 101 : diffvar = create_temporary_var (TREE_TYPE (diff));
11740 101 : pushdecl (diffvar);
11741 101 : add_decl_expr (diffvar);
11742 : }
11743 661 : else if (code == OMP_LOOP)
11744 : {
11745 43 : if (!loop_iv_seen)
11746 : {
11747 : /* While iterators on the loop construct are predetermined
11748 : lastprivate, if the decl is not declared inside of the
11749 : loop, OMP_CLAUSE_LASTPRIVATE should have been added
11750 : already. */
11751 16 : loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11752 16 : OMP_CLAUSE_DECL (loop_iv_seen) = iter;
11753 16 : OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
11754 16 : clauses = loop_iv_seen;
11755 : }
11756 27 : else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
11757 : {
11758 5 : OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
11759 5 : OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
11760 5 : OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
11761 : }
11762 43 : if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
11763 21 : cxx_omp_finish_clause (loop_iv_seen, NULL, false);
11764 : }
11765 :
11766 762 : orig_pre_body = *pre_body;
11767 762 : *pre_body = push_stmt_list ();
11768 762 : if (orig_pre_body)
11769 610 : add_stmt (orig_pre_body);
11770 762 : if (init != NULL)
11771 61 : finish_expr_stmt (build_x_modify_expr (elocus,
11772 : iter, NOP_EXPR, init,
11773 : NULL_TREE, tf_warning_or_error));
11774 762 : init = build_int_cst (TREE_TYPE (diff), 0);
11775 762 : if (c && iter_incr == NULL
11776 28 : && (!ordered || (i < collapse && collapse > 1)))
11777 : {
11778 28 : if (incr_var)
11779 : {
11780 10 : finish_expr_stmt (build_x_modify_expr (elocus,
11781 : incr_var, NOP_EXPR,
11782 : incr, NULL_TREE,
11783 : tf_warning_or_error));
11784 10 : incr = incr_var;
11785 : }
11786 28 : iter_incr = build_x_modify_expr (elocus,
11787 : iter, PLUS_EXPR, incr,
11788 : NULL_TREE, tf_warning_or_error);
11789 : }
11790 762 : if (c && ordered && i < collapse && collapse > 1)
11791 762 : iter_incr = incr;
11792 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11793 : last, NOP_EXPR, init,
11794 : NULL_TREE, tf_warning_or_error));
11795 762 : if (diffvar)
11796 : {
11797 101 : finish_expr_stmt (build_x_modify_expr (elocus,
11798 : diffvar, NOP_EXPR,
11799 : diff, NULL_TREE, tf_warning_or_error));
11800 101 : diff = diffvar;
11801 : }
11802 762 : *pre_body = pop_stmt_list (*pre_body);
11803 :
11804 1524 : cond = cp_build_binary_op (elocus,
11805 762 : TREE_CODE (cond), decl, diff,
11806 : tf_warning_or_error);
11807 762 : incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
11808 : elocus, incr, NULL_TREE);
11809 :
11810 762 : orig_body = *body;
11811 762 : *body = push_stmt_list ();
11812 762 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
11813 762 : iter_init = build_x_modify_expr (elocus,
11814 : iter, PLUS_EXPR, iter_init,
11815 : NULL_TREE, tf_warning_or_error);
11816 762 : if (iter_init != error_mark_node)
11817 759 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11818 762 : finish_expr_stmt (iter_init);
11819 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11820 : last, NOP_EXPR, decl,
11821 : NULL_TREE, tf_warning_or_error));
11822 762 : add_stmt (orig_body);
11823 762 : *body = pop_stmt_list (*body);
11824 :
11825 762 : if (c)
11826 : {
11827 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list ();
11828 120 : if (!ordered)
11829 114 : finish_expr_stmt (iter_incr);
11830 : else
11831 : {
11832 6 : iter_init = decl;
11833 6 : if (i < collapse && collapse > 1 && !error_operand_p (iter_incr))
11834 2 : iter_init = build2 (PLUS_EXPR, TREE_TYPE (diff),
11835 : iter_init, iter_incr);
11836 6 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), iter_init, last);
11837 6 : iter_init = build_x_modify_expr (elocus,
11838 : iter, PLUS_EXPR, iter_init,
11839 : NULL_TREE, tf_warning_or_error);
11840 6 : if (iter_init != error_mark_node)
11841 6 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11842 6 : finish_expr_stmt (iter_init);
11843 : }
11844 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c)
11845 240 : = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c));
11846 : }
11847 :
11848 762 : if (TREE_CODE (TREE_VEC_ELT (orig_declv, i)) == TREE_LIST)
11849 : {
11850 116 : tree t = TREE_VEC_ELT (orig_declv, i);
11851 116 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
11852 : && TREE_VALUE (t) == NULL_TREE
11853 : && TREE_CODE (TREE_CHAIN (t)) == TREE_VEC);
11854 116 : TREE_PURPOSE (t) = TREE_VEC_ELT (declv, i);
11855 116 : TREE_VALUE (t) = last;
11856 : }
11857 : else
11858 646 : TREE_VEC_ELT (orig_declv, i)
11859 1292 : = tree_cons (TREE_VEC_ELT (declv, i), last, NULL_TREE);
11860 762 : TREE_VEC_ELT (declv, i) = decl;
11861 762 : TREE_VEC_ELT (initv, i) = init;
11862 762 : TREE_VEC_ELT (condv, i) = cond;
11863 762 : TREE_VEC_ELT (incrv, i) = incr;
11864 :
11865 762 : return false;
11866 : }
11867 :
11868 : /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
11869 : are directly for their associated operands in the statement. DECL
11870 : and INIT are a combo; if DECL is NULL then INIT ought to be a
11871 : MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
11872 : optional statements that need to go before the loop into its
11873 : sk_omp scope. */
11874 :
11875 : tree
11876 21128 : finish_omp_for (location_t locus, enum tree_code code, tree declv,
11877 : tree orig_declv, tree initv, tree condv, tree incrv,
11878 : tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
11879 : {
11880 21128 : tree omp_for = NULL, orig_incr = NULL;
11881 21128 : tree decl = NULL, init, cond, incr;
11882 21128 : location_t elocus;
11883 21128 : int i;
11884 21128 : int collapse = 1;
11885 21128 : int ordered = 0;
11886 21128 : auto_vec<location_t> init_locv;
11887 :
11888 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
11889 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
11890 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
11891 21128 : if (TREE_VEC_LENGTH (declv) > 1)
11892 : {
11893 4054 : if (tree ti = omp_find_clause (clauses, OMP_CLAUSE_TILE))
11894 83 : collapse = list_length (OMP_CLAUSE_TILE_LIST (ti));
11895 : else
11896 : {
11897 3971 : if (tree co = omp_find_clause (clauses, OMP_CLAUSE_COLLAPSE))
11898 3501 : collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
11899 470 : else if (tree si = omp_find_clause (clauses, OMP_CLAUSE_SIZES))
11900 394 : collapse = list_length (OMP_CLAUSE_SIZES_LIST (si));
11901 3971 : if (collapse != TREE_VEC_LENGTH (declv))
11902 100 : ordered = TREE_VEC_LENGTH (declv);
11903 : }
11904 : }
11905 48601 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
11906 : {
11907 27509 : decl = TREE_VEC_ELT (declv, i);
11908 27509 : init = TREE_VEC_ELT (initv, i);
11909 27509 : cond = TREE_VEC_ELT (condv, i);
11910 27509 : incr = TREE_VEC_ELT (incrv, i);
11911 27509 : elocus = locus;
11912 :
11913 27509 : if (decl == global_namespace)
11914 : {
11915 1101 : gcc_assert (init == NULL_TREE && cond == NULL_TREE && incr == NULL_TREE);
11916 1101 : TREE_VEC_ELT (declv, i) = NULL_TREE;
11917 1101 : init_locv.safe_push (UNKNOWN_LOCATION);
11918 1101 : continue;
11919 : }
11920 : /* We are going to throw out the init's original MODIFY_EXPR or
11921 : MODOP_EXPR below. Save its location so we can use it when
11922 : reconstructing the expression farther down. Alternatively, if the
11923 : initializer is a binding of the iteration variable, save
11924 : that location. Any of these locations in the initialization clause
11925 : for the current nested loop are better than using the argument locus,
11926 : that points to the "for" of the outermost loop in the nest. */
11927 26408 : if (init && EXPR_HAS_LOCATION (init))
11928 17875 : elocus = EXPR_LOCATION (init);
11929 8533 : else if (decl && INDIRECT_REF_P (decl) && EXPR_HAS_LOCATION (decl))
11930 : /* This can happen for class iterators. */
11931 0 : elocus = EXPR_LOCATION (decl);
11932 8533 : else if (decl && DECL_P (decl))
11933 : {
11934 8506 : if (DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
11935 8506 : elocus = DECL_SOURCE_LOCATION (decl);
11936 0 : else if (DECL_INITIAL (decl)
11937 0 : && EXPR_HAS_LOCATION (DECL_INITIAL (decl)))
11938 0 : elocus = EXPR_LOCATION (DECL_INITIAL (decl));
11939 : }
11940 26408 : init_locv.safe_push (elocus);
11941 :
11942 26408 : if (decl == NULL)
11943 : {
11944 16564 : if (init != NULL)
11945 16561 : switch (TREE_CODE (init))
11946 : {
11947 16176 : case MODIFY_EXPR:
11948 16176 : decl = TREE_OPERAND (init, 0);
11949 16176 : init = TREE_OPERAND (init, 1);
11950 16176 : break;
11951 367 : case MODOP_EXPR:
11952 367 : if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
11953 : {
11954 367 : decl = TREE_OPERAND (init, 0);
11955 367 : init = TREE_OPERAND (init, 2);
11956 : }
11957 : break;
11958 : default:
11959 : break;
11960 : }
11961 :
11962 16564 : if (decl == NULL)
11963 : {
11964 21 : error_at (locus,
11965 : "expected iteration declaration or initialization");
11966 21 : return NULL;
11967 : }
11968 : }
11969 :
11970 26387 : if (cond == global_namespace)
11971 170 : continue;
11972 :
11973 26217 : if (cond == NULL)
11974 : {
11975 9 : error_at (elocus, "missing controlling predicate");
11976 9 : return NULL;
11977 : }
11978 :
11979 26208 : if (incr == NULL)
11980 : {
11981 6 : error_at (elocus, "missing increment expression");
11982 6 : return NULL;
11983 : }
11984 :
11985 26202 : TREE_VEC_ELT (declv, i) = decl;
11986 26202 : TREE_VEC_ELT (initv, i) = init;
11987 : }
11988 :
11989 21092 : if (orig_inits)
11990 : {
11991 : bool fail = false;
11992 : tree orig_init;
11993 21214 : FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
11994 1181 : if (orig_init
11995 3396 : && !c_omp_check_loop_iv_exprs (locus, code,
11996 : orig_declv ? orig_declv : declv, i,
11997 1164 : TREE_VEC_ELT (declv, i), orig_init,
11998 : NULL_TREE, cp_walk_subtrees))
11999 : fail = true;
12000 20033 : if (fail)
12001 887 : return NULL;
12002 : }
12003 :
12004 21035 : if (dependent_omp_for_p (declv, initv, condv, incrv, body))
12005 : {
12006 453 : tree stmt;
12007 :
12008 453 : stmt = make_node (code);
12009 :
12010 1499 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12011 : {
12012 593 : if (TREE_VEC_ELT (declv, i) == NULL_TREE)
12013 9 : continue;
12014 : /* This is really just a place-holder. We'll be decomposing this
12015 : again and going through the cp_build_modify_expr path below when
12016 : we instantiate the thing. */
12017 584 : TREE_VEC_ELT (initv, i)
12018 1168 : = build2_loc (init_locv[i], MODIFY_EXPR, void_type_node,
12019 584 : TREE_VEC_ELT (declv, i), TREE_VEC_ELT (initv, i));
12020 : }
12021 :
12022 453 : TREE_TYPE (stmt) = void_type_node;
12023 453 : OMP_FOR_INIT (stmt) = initv;
12024 453 : OMP_FOR_COND (stmt) = condv;
12025 453 : OMP_FOR_INCR (stmt) = incrv;
12026 453 : OMP_FOR_BODY (stmt) = body;
12027 453 : OMP_FOR_PRE_BODY (stmt) = pre_body;
12028 453 : OMP_FOR_CLAUSES (stmt) = clauses;
12029 :
12030 453 : SET_EXPR_LOCATION (stmt, locus);
12031 453 : return add_stmt (stmt);
12032 : }
12033 :
12034 20582 : if (!orig_declv)
12035 19795 : orig_declv = copy_node (declv);
12036 :
12037 20582 : if (processing_template_decl)
12038 612 : orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv));
12039 :
12040 48030 : for (i = 0; i < TREE_VEC_LENGTH (declv); )
12041 : {
12042 27540 : decl = TREE_VEC_ELT (declv, i);
12043 27540 : init = TREE_VEC_ELT (initv, i);
12044 27540 : cond = TREE_VEC_ELT (condv, i);
12045 27540 : incr = TREE_VEC_ELT (incrv, i);
12046 27540 : if (orig_incr)
12047 844 : TREE_VEC_ELT (orig_incr, i) = incr;
12048 27540 : elocus = init_locv[i];
12049 :
12050 27540 : if (decl == NULL_TREE)
12051 : {
12052 1092 : i++;
12053 1092 : continue;
12054 : }
12055 :
12056 26448 : if (!DECL_P (decl))
12057 : {
12058 6 : error_at (elocus, "expected iteration declaration or initialization");
12059 6 : return NULL;
12060 : }
12061 :
12062 26442 : if (incr && TREE_CODE (incr) == MODOP_EXPR)
12063 : {
12064 1 : if (orig_incr)
12065 1 : TREE_VEC_ELT (orig_incr, i) = incr;
12066 1 : incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
12067 1 : TREE_CODE (TREE_OPERAND (incr, 1)),
12068 1 : TREE_OPERAND (incr, 2),
12069 : tf_warning_or_error);
12070 : }
12071 :
12072 26442 : if (CLASS_TYPE_P (TREE_TYPE (decl)))
12073 : {
12074 825 : if (code == OMP_SIMD)
12075 : {
12076 12 : error_at (elocus, "%<#pragma omp simd%> used with class "
12077 : "iteration variable %qE", decl);
12078 12 : return NULL;
12079 : }
12080 813 : if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
12081 : initv, condv, incrv, &body,
12082 : &pre_body, clauses,
12083 : collapse, ordered))
12084 : return NULL;
12085 762 : continue;
12086 : }
12087 :
12088 51234 : if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
12089 27203 : && !TYPE_PTR_P (TREE_TYPE (decl)))
12090 : {
12091 14 : error_at (elocus, "invalid type for iteration variable %qE", decl);
12092 14 : return NULL;
12093 : }
12094 :
12095 25603 : if (!processing_template_decl && TREE_CODE (init) != TREE_VEC)
12096 24842 : init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
12097 : tf_warning_or_error);
12098 : else
12099 761 : init = build2_loc (elocus, MODIFY_EXPR, void_type_node, decl, init);
12100 25603 : if (decl == error_mark_node || init == error_mark_node)
12101 : return NULL;
12102 :
12103 25594 : TREE_VEC_ELT (declv, i) = decl;
12104 25594 : TREE_VEC_ELT (initv, i) = init;
12105 25594 : TREE_VEC_ELT (condv, i) = cond;
12106 25594 : TREE_VEC_ELT (incrv, i) = incr;
12107 25594 : i++;
12108 : }
12109 :
12110 20490 : if (pre_body && IS_EMPTY_STMT (pre_body))
12111 0 : pre_body = NULL;
12112 :
12113 40980 : omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
12114 : incrv, body, pre_body,
12115 20490 : !processing_template_decl);
12116 :
12117 : /* Check for iterators appearing in lb, b or incr expressions. */
12118 20490 : if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees))
12119 : omp_for = NULL_TREE;
12120 :
12121 20004 : if (omp_for == NULL)
12122 702 : return NULL;
12123 :
12124 19788 : add_stmt (omp_for);
12125 :
12126 45448 : for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
12127 : {
12128 25660 : init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i);
12129 25660 : if (init == NULL_TREE)
12130 1032 : continue;
12131 24628 : decl = TREE_OPERAND (init, 0);
12132 24628 : cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i);
12133 24628 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
12134 :
12135 24628 : if (!processing_template_decl)
12136 : {
12137 24107 : if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC)
12138 : {
12139 106 : tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1);
12140 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 1)
12141 106 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12142 106 : t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2);
12143 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 2)
12144 212 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12145 : }
12146 : else
12147 : {
12148 24001 : tree t = TREE_OPERAND (init, 1);
12149 24001 : TREE_OPERAND (init, 1)
12150 48002 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12151 : }
12152 24107 : if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC)
12153 : {
12154 121 : tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1);
12155 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1)
12156 121 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12157 121 : t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2);
12158 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2)
12159 242 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12160 : }
12161 : else
12162 : {
12163 23986 : tree t = TREE_OPERAND (cond, 1);
12164 23986 : TREE_OPERAND (cond, 1)
12165 47972 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12166 : }
12167 : }
12168 :
12169 24628 : if (TREE_CODE (incr) != MODIFY_EXPR)
12170 18426 : continue;
12171 :
12172 6202 : if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
12173 70 : && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
12174 6272 : && !processing_template_decl)
12175 : {
12176 64 : tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
12177 64 : if (TREE_SIDE_EFFECTS (t)
12178 8 : && t != decl
12179 70 : && (TREE_CODE (t) != NOP_EXPR
12180 0 : || TREE_OPERAND (t, 0) != decl))
12181 6 : TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
12182 12 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12183 :
12184 64 : t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
12185 64 : if (TREE_SIDE_EFFECTS (t)
12186 56 : && t != decl
12187 120 : && (TREE_CODE (t) != NOP_EXPR
12188 5 : || TREE_OPERAND (t, 0) != decl))
12189 56 : TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
12190 112 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12191 : }
12192 :
12193 6202 : if (orig_incr)
12194 177 : TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
12195 : }
12196 19788 : OMP_FOR_CLAUSES (omp_for) = clauses;
12197 :
12198 : /* For simd loops with non-static data member iterators, we could have added
12199 : OMP_CLAUSE_LINEAR clauses without OMP_CLAUSE_LINEAR_STEP. As we know the
12200 : step at this point, fill it in. */
12201 4735 : if (code == OMP_SIMD && !processing_template_decl
12202 24479 : && TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)) == 1)
12203 4619 : for (tree c = omp_find_clause (clauses, OMP_CLAUSE_LINEAR); c;
12204 561 : c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_LINEAR))
12205 561 : if (OMP_CLAUSE_LINEAR_STEP (c) == NULL_TREE)
12206 : {
12207 4 : decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0), 0);
12208 4 : gcc_assert (decl == OMP_CLAUSE_DECL (c));
12209 4 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
12210 4 : tree step, stept;
12211 4 : switch (TREE_CODE (incr))
12212 : {
12213 0 : case PREINCREMENT_EXPR:
12214 0 : case POSTINCREMENT_EXPR:
12215 : /* c_omp_for_incr_canonicalize_ptr() should have been
12216 : called to massage things appropriately. */
12217 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12218 0 : OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1);
12219 0 : break;
12220 0 : case PREDECREMENT_EXPR:
12221 0 : case POSTDECREMENT_EXPR:
12222 : /* c_omp_for_incr_canonicalize_ptr() should have been
12223 : called to massage things appropriately. */
12224 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12225 0 : OMP_CLAUSE_LINEAR_STEP (c)
12226 0 : = build_int_cst (TREE_TYPE (decl), -1);
12227 0 : break;
12228 4 : case MODIFY_EXPR:
12229 4 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12230 4 : incr = TREE_OPERAND (incr, 1);
12231 4 : switch (TREE_CODE (incr))
12232 : {
12233 4 : case PLUS_EXPR:
12234 4 : if (TREE_OPERAND (incr, 1) == decl)
12235 0 : step = TREE_OPERAND (incr, 0);
12236 : else
12237 4 : step = TREE_OPERAND (incr, 1);
12238 : break;
12239 0 : case MINUS_EXPR:
12240 0 : case POINTER_PLUS_EXPR:
12241 0 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12242 0 : step = TREE_OPERAND (incr, 1);
12243 0 : break;
12244 0 : default:
12245 0 : gcc_unreachable ();
12246 : }
12247 4 : stept = TREE_TYPE (decl);
12248 4 : if (INDIRECT_TYPE_P (stept))
12249 0 : stept = sizetype;
12250 4 : step = fold_convert (stept, step);
12251 4 : if (TREE_CODE (incr) == MINUS_EXPR)
12252 0 : step = fold_build1 (NEGATE_EXPR, stept, step);
12253 4 : OMP_CLAUSE_LINEAR_STEP (c) = step;
12254 4 : break;
12255 0 : default:
12256 0 : gcc_unreachable ();
12257 : }
12258 : }
12259 : /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
12260 : clauses, we need copy ctor for those rather than default ctor,
12261 : plus as for other lastprivates assignment op and dtor. */
12262 19788 : if (code == OMP_LOOP && !processing_template_decl)
12263 1993 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
12264 1285 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12265 204 : && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
12266 1307 : && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
12267 : false, true, true, true))
12268 0 : CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
12269 :
12270 : return omp_for;
12271 21128 : }
12272 :
12273 : /* Code walker for finish_omp_for_block: extract binding of DP->var
12274 : from its current block and move it to a new BIND_EXPR DP->b
12275 : surrounding the body of DP->omp_for. */
12276 :
12277 : struct fofb_data {
12278 : tree var;
12279 : tree b;
12280 : tree omp_for;
12281 : };
12282 :
12283 : static tree
12284 389 : finish_omp_for_block_walker (tree *tp, int *walk_subtrees, void *dp)
12285 : {
12286 389 : struct fofb_data *fofb = (struct fofb_data *)dp;
12287 389 : if (TREE_CODE (*tp) == BIND_EXPR)
12288 578 : for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
12289 : {
12290 576 : if (*p == fofb->var)
12291 : {
12292 363 : *p = DECL_CHAIN (*p);
12293 363 : if (fofb->b == NULL_TREE)
12294 : {
12295 214 : fofb->b = make_node (BLOCK);
12296 214 : fofb->b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12297 214 : OMP_FOR_BODY (fofb->omp_for), fofb->b);
12298 214 : TREE_SIDE_EFFECTS (fofb->b) = 1;
12299 214 : OMP_FOR_BODY (fofb->omp_for) = fofb->b;
12300 : }
12301 363 : DECL_CHAIN (fofb->var) = BIND_EXPR_VARS (fofb->b);
12302 363 : BIND_EXPR_VARS (fofb->b) = fofb->var;
12303 363 : BLOCK_VARS (BIND_EXPR_BLOCK (fofb->b)) = fofb->var;
12304 363 : BLOCK_VARS (BIND_EXPR_BLOCK (*tp)) = BIND_EXPR_VARS (*tp);
12305 363 : return *tp;
12306 : }
12307 : }
12308 26 : if (TREE_CODE (*tp) != BIND_EXPR && TREE_CODE (*tp) != STATEMENT_LIST)
12309 22 : *walk_subtrees = false;
12310 : return NULL_TREE;
12311 : }
12312 :
12313 : /* Fix up range for decls. Those decls were pushed into BIND's
12314 : BIND_EXPR_VARS, or that of a nested BIND_EXPR inside its body,
12315 : and need to be moved into a new BIND_EXPR surrounding OMP_FOR's body
12316 : so that processing of combined loop directives can find them. */
12317 : tree
12318 14525 : finish_omp_for_block (tree bind, tree omp_for)
12319 : {
12320 14525 : if (omp_for == NULL_TREE
12321 14478 : || !OMP_FOR_ORIG_DECLS (omp_for)
12322 28435 : || bind == NULL_TREE)
12323 615 : return bind;
12324 13910 : struct fofb_data fofb;
12325 13910 : fofb.b = NULL_TREE;
12326 13910 : fofb.omp_for = omp_for;
12327 33347 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (omp_for)); i++)
12328 19437 : if (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i)
12329 19215 : && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i))
12330 : == TREE_LIST)
12331 20268 : && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)))
12332 : {
12333 237 : tree v = TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i));
12334 602 : for (int j = 2; j < TREE_VEC_LENGTH (v); j++)
12335 : {
12336 365 : fofb.var = TREE_VEC_ELT (v, j);
12337 365 : cp_walk_tree (&bind, finish_omp_for_block_walker,
12338 : (void *)&fofb, NULL);
12339 : }
12340 : }
12341 13910 : return bind;
12342 : }
12343 :
12344 : void
12345 3342 : finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
12346 : tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
12347 : tree clauses, enum omp_memory_order mo, bool weak)
12348 : {
12349 3342 : tree orig_lhs;
12350 3342 : tree orig_rhs;
12351 3342 : tree orig_v;
12352 3342 : tree orig_lhs1;
12353 3342 : tree orig_rhs1;
12354 3342 : tree orig_r;
12355 3342 : bool dependent_p;
12356 3342 : tree stmt;
12357 :
12358 3342 : orig_lhs = lhs;
12359 3342 : orig_rhs = rhs;
12360 3342 : orig_v = v;
12361 3342 : orig_lhs1 = lhs1;
12362 3342 : orig_rhs1 = rhs1;
12363 3342 : orig_r = r;
12364 3342 : dependent_p = false;
12365 3342 : stmt = NULL_TREE;
12366 :
12367 : /* Even in a template, we can detect invalid uses of the atomic
12368 : pragma if neither LHS nor RHS is type-dependent. */
12369 3342 : if (processing_template_decl)
12370 : {
12371 600 : dependent_p = (type_dependent_expression_p (lhs)
12372 237 : || (rhs && type_dependent_expression_p (rhs))
12373 234 : || (v && type_dependent_expression_p (v))
12374 234 : || (lhs1 && type_dependent_expression_p (lhs1))
12375 234 : || (rhs1 && type_dependent_expression_p (rhs1))
12376 834 : || (r
12377 25 : && r != void_list_node
12378 16 : && type_dependent_expression_p (r)));
12379 600 : if (clauses)
12380 : {
12381 30 : gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE
12382 : && OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT
12383 : && OMP_CLAUSE_CHAIN (clauses) == NULL_TREE);
12384 30 : if (type_dependent_expression_p (OMP_CLAUSE_HINT_EXPR (clauses))
12385 30 : || TREE_CODE (OMP_CLAUSE_HINT_EXPR (clauses)) != INTEGER_CST)
12386 : dependent_p = true;
12387 : }
12388 : }
12389 576 : if (!dependent_p)
12390 : {
12391 2958 : bool swapped = false;
12392 2958 : if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs))
12393 : {
12394 143 : std::swap (rhs, rhs1);
12395 143 : swapped = !commutative_tree_code (opcode);
12396 : }
12397 2958 : if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1))
12398 : {
12399 0 : if (code == OMP_ATOMIC)
12400 0 : error ("%<#pragma omp atomic update%> uses two different "
12401 : "expressions for memory");
12402 : else
12403 0 : error ("%<#pragma omp atomic capture%> uses two different "
12404 : "expressions for memory");
12405 0 : return;
12406 : }
12407 2958 : if (lhs1 && !cp_tree_equal (lhs, lhs1))
12408 : {
12409 0 : if (code == OMP_ATOMIC)
12410 0 : error ("%<#pragma omp atomic update%> uses two different "
12411 : "expressions for memory");
12412 : else
12413 0 : error ("%<#pragma omp atomic capture%> uses two different "
12414 : "expressions for memory");
12415 0 : return;
12416 : }
12417 5916 : stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs,
12418 : v, lhs1, rhs1, r, swapped, mo, weak,
12419 2958 : processing_template_decl != 0);
12420 2958 : if (stmt == error_mark_node)
12421 : return;
12422 : }
12423 3312 : if (processing_template_decl)
12424 : {
12425 591 : if (code == OMP_ATOMIC_READ)
12426 : {
12427 167 : stmt = build_min_nt_loc (loc, OMP_ATOMIC_READ, orig_lhs);
12428 167 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12429 167 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12430 : }
12431 : else
12432 : {
12433 424 : if (opcode == NOP_EXPR)
12434 35 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
12435 389 : else if (opcode == COND_EXPR)
12436 : {
12437 124 : stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs);
12438 124 : if (orig_r)
12439 50 : stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r,
12440 : stmt);
12441 124 : stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1,
12442 : orig_lhs);
12443 124 : orig_rhs1 = NULL_TREE;
12444 : }
12445 : else
12446 265 : stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
12447 424 : if (orig_rhs1)
12448 182 : stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
12449 : COMPOUND_EXPR, orig_rhs1, stmt);
12450 424 : if (code != OMP_ATOMIC)
12451 : {
12452 233 : stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt);
12453 233 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12454 233 : OMP_ATOMIC_WEAK (stmt) = weak;
12455 233 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12456 : }
12457 : }
12458 591 : stmt = build2 (OMP_ATOMIC, void_type_node,
12459 : clauses ? clauses : integer_zero_node, stmt);
12460 591 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12461 591 : OMP_ATOMIC_WEAK (stmt) = weak;
12462 591 : SET_EXPR_LOCATION (stmt, loc);
12463 : }
12464 :
12465 : /* Avoid -Wunused-value warnings here, the whole construct has side-effects
12466 : and even if it might be wrapped from fold-const.cc or c-omp.cc wrapped
12467 : in some tree that appears to be unused, the value is not unused. */
12468 3312 : warning_sentinel w (warn_unused_value);
12469 3312 : finish_expr_stmt (stmt);
12470 3312 : }
12471 :
12472 : void
12473 359 : finish_omp_barrier (void)
12474 : {
12475 359 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
12476 359 : releasing_vec vec;
12477 359 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12478 359 : finish_expr_stmt (stmt);
12479 359 : }
12480 :
12481 : void
12482 397 : finish_omp_depobj (location_t loc, tree depobj,
12483 : enum omp_clause_depend_kind kind, tree clause)
12484 : {
12485 397 : if (!error_operand_p (depobj) && !type_dependent_expression_p (depobj))
12486 : {
12487 343 : if (!lvalue_p (depobj))
12488 : {
12489 6 : error_at (EXPR_LOC_OR_LOC (depobj, loc),
12490 : "%<depobj%> expression is not lvalue expression");
12491 6 : depobj = error_mark_node;
12492 : }
12493 : }
12494 :
12495 397 : if (processing_template_decl)
12496 : {
12497 114 : if (clause == NULL_TREE)
12498 47 : clause = build_int_cst (integer_type_node, kind);
12499 114 : add_stmt (build_min_nt_loc (loc, OMP_DEPOBJ, depobj, clause));
12500 114 : return;
12501 : }
12502 :
12503 283 : if (!error_operand_p (depobj))
12504 : {
12505 274 : tree addr = cp_build_addr_expr (depobj, tf_warning_or_error);
12506 274 : if (addr == error_mark_node)
12507 : depobj = error_mark_node;
12508 : else
12509 274 : depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR,
12510 : tf_warning_or_error);
12511 : }
12512 :
12513 283 : c_finish_omp_depobj (loc, depobj, kind, clause);
12514 : }
12515 :
12516 : void
12517 162 : finish_omp_flush (int mo)
12518 : {
12519 162 : tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
12520 162 : releasing_vec vec;
12521 162 : if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST)
12522 : {
12523 54 : fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
12524 54 : vec->quick_push (build_int_cst (integer_type_node, mo));
12525 : }
12526 162 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12527 162 : finish_expr_stmt (stmt);
12528 162 : }
12529 :
12530 : void
12531 111 : finish_omp_taskwait (void)
12532 : {
12533 111 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
12534 111 : releasing_vec vec;
12535 111 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12536 111 : finish_expr_stmt (stmt);
12537 111 : }
12538 :
12539 : void
12540 16 : finish_omp_taskyield (void)
12541 : {
12542 16 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
12543 16 : releasing_vec vec;
12544 16 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12545 16 : finish_expr_stmt (stmt);
12546 16 : }
12547 :
12548 : void
12549 596 : finish_omp_cancel (tree clauses)
12550 : {
12551 596 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
12552 596 : int mask = 0;
12553 596 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12554 : mask = 1;
12555 414 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12556 : mask = 2;
12557 285 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12558 : mask = 4;
12559 164 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12560 : mask = 8;
12561 : else
12562 : {
12563 0 : error ("%<#pragma omp cancel%> must specify one of "
12564 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12565 0 : return;
12566 : }
12567 596 : releasing_vec vec;
12568 596 : tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
12569 596 : if (ifc != NULL_TREE)
12570 : {
12571 70 : if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
12572 70 : && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
12573 6 : error_at (OMP_CLAUSE_LOCATION (ifc),
12574 : "expected %<cancel%> %<if%> clause modifier");
12575 : else
12576 : {
12577 64 : tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
12578 64 : if (ifc2 != NULL_TREE)
12579 : {
12580 3 : gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
12581 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
12582 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
12583 3 : error_at (OMP_CLAUSE_LOCATION (ifc2),
12584 : "expected %<cancel%> %<if%> clause modifier");
12585 : }
12586 : }
12587 :
12588 70 : if (!processing_template_decl)
12589 61 : ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc));
12590 : else
12591 9 : ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
12592 9 : OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK,
12593 : integer_zero_node, ERROR_MARK,
12594 : NULL_TREE, NULL, tf_warning_or_error);
12595 : }
12596 : else
12597 526 : ifc = boolean_true_node;
12598 596 : vec->quick_push (build_int_cst (integer_type_node, mask));
12599 596 : vec->quick_push (ifc);
12600 596 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12601 596 : finish_expr_stmt (stmt);
12602 596 : }
12603 :
12604 : void
12605 494 : finish_omp_cancellation_point (tree clauses)
12606 : {
12607 494 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
12608 494 : int mask = 0;
12609 494 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12610 : mask = 1;
12611 366 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12612 : mask = 2;
12613 261 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12614 : mask = 4;
12615 156 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12616 : mask = 8;
12617 : else
12618 : {
12619 3 : error ("%<#pragma omp cancellation point%> must specify one of "
12620 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12621 3 : return;
12622 : }
12623 491 : releasing_vec vec
12624 491 : = make_tree_vector_single (build_int_cst (integer_type_node, mask));
12625 491 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12626 491 : finish_expr_stmt (stmt);
12627 491 : }
12628 :
12629 : /* Begin a __transaction_atomic or __transaction_relaxed statement.
12630 : If PCOMPOUND is non-null, this is for a function-transaction-block, and we
12631 : should create an extra compound stmt. */
12632 :
12633 : tree
12634 303 : begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
12635 : {
12636 303 : tree r;
12637 :
12638 303 : if (pcompound)
12639 21 : *pcompound = begin_compound_stmt (0);
12640 :
12641 303 : r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
12642 :
12643 : /* Only add the statement to the function if support enabled. */
12644 303 : if (flag_tm)
12645 297 : add_stmt (r);
12646 : else
12647 12 : error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
12648 : ? G_("%<__transaction_relaxed%> without "
12649 : "transactional memory support enabled")
12650 : : G_("%<__transaction_atomic%> without "
12651 : "transactional memory support enabled")));
12652 :
12653 303 : TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
12654 303 : TREE_SIDE_EFFECTS (r) = 1;
12655 303 : return r;
12656 : }
12657 :
12658 : /* End a __transaction_atomic or __transaction_relaxed statement.
12659 : If COMPOUND_STMT is non-null, this is for a function-transaction-block,
12660 : and we should end the compound. If NOEX is non-NULL, we wrap the body in
12661 : a MUST_NOT_THROW_EXPR with NOEX as condition. */
12662 :
12663 : void
12664 303 : finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
12665 : {
12666 303 : TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
12667 303 : TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
12668 303 : TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
12669 303 : TRANSACTION_EXPR_IS_STMT (stmt) = 1;
12670 :
12671 : /* noexcept specifications are not allowed for function transactions. */
12672 303 : gcc_assert (!(noex && compound_stmt));
12673 303 : if (noex)
12674 : {
12675 51 : tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
12676 : noex);
12677 51 : protected_set_expr_location
12678 51 : (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
12679 51 : TREE_SIDE_EFFECTS (body) = 1;
12680 51 : TRANSACTION_EXPR_BODY (stmt) = body;
12681 : }
12682 :
12683 303 : if (compound_stmt)
12684 21 : finish_compound_stmt (compound_stmt);
12685 303 : }
12686 :
12687 : /* Build a __transaction_atomic or __transaction_relaxed expression. If
12688 : NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
12689 : condition. */
12690 :
12691 : tree
12692 116 : build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
12693 : {
12694 116 : tree ret;
12695 116 : if (noex)
12696 : {
12697 57 : expr = build_must_not_throw_expr (expr, noex);
12698 57 : protected_set_expr_location (expr, loc);
12699 57 : TREE_SIDE_EFFECTS (expr) = 1;
12700 : }
12701 116 : ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
12702 116 : if (flags & TM_STMT_ATTR_RELAXED)
12703 4 : TRANSACTION_EXPR_RELAXED (ret) = 1;
12704 116 : TREE_SIDE_EFFECTS (ret) = 1;
12705 116 : SET_EXPR_LOCATION (ret, loc);
12706 116 : return ret;
12707 : }
12708 :
12709 : void
12710 97402 : init_cp_semantics (void)
12711 : {
12712 97402 : }
12713 :
12714 :
12715 : /* Get constant string at LOCATION. Returns true if successful,
12716 : otherwise false. */
12717 :
12718 : bool
12719 10774987 : cexpr_str::type_check (location_t location, bool allow_char8_t /*=false*/)
12720 : {
12721 10774987 : tsubst_flags_t complain = tf_warning_or_error;
12722 :
12723 10774987 : if (message == NULL_TREE
12724 10774987 : || message == error_mark_node
12725 21549971 : || check_for_bare_parameter_packs (message))
12726 3 : return false;
12727 :
12728 10774984 : if (TREE_CODE (message) != STRING_CST
12729 10774984 : && !type_dependent_expression_p (message))
12730 : {
12731 973 : message_sz
12732 973 : = finish_class_member_access_expr (message,
12733 : get_identifier ("size"),
12734 : false, complain);
12735 973 : if (message_sz != error_mark_node)
12736 886 : message_data
12737 886 : = finish_class_member_access_expr (message,
12738 : get_identifier ("data"),
12739 : false, complain);
12740 973 : if (message_sz == error_mark_node || message_data == error_mark_node)
12741 : {
12742 121 : error_at (location, "constexpr string must be a string "
12743 : "literal or object with %<size%> and "
12744 : "%<data%> members");
12745 292 : return false;
12746 : }
12747 852 : releasing_vec size_args, data_args;
12748 852 : message_sz = finish_call_expr (message_sz, &size_args, false, false,
12749 : complain);
12750 852 : message_data = finish_call_expr (message_data, &data_args, false, false,
12751 : complain);
12752 852 : if (message_sz == error_mark_node || message_data == error_mark_node)
12753 : return false;
12754 738 : message_sz = build_converted_constant_expr (size_type_node, message_sz,
12755 : complain);
12756 738 : if (message_sz == error_mark_node)
12757 : {
12758 15 : error_at (location, "constexpr string %<size()%> "
12759 : "must be implicitly convertible to "
12760 : "%<std::size_t%>");
12761 15 : return false;
12762 : }
12763 :
12764 723 : if (allow_char8_t
12765 34 : && POINTER_TYPE_P (TREE_TYPE (message_data))
12766 34 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
12767 34 : == char8_type_node)
12768 733 : && (TYPE_QUALS (TREE_TYPE (TREE_TYPE (message_data)))
12769 : == TYPE_QUAL_CONST))
12770 : return true;
12771 :
12772 713 : message_data = build_converted_constant_expr (const_string_type_node,
12773 : message_data, complain);
12774 713 : if (message_data == error_mark_node)
12775 : {
12776 32 : error_at (location, "constexpr string %<data()%> "
12777 : "must be implicitly convertible to "
12778 : "%<const char*%>");
12779 32 : return false;
12780 : }
12781 852 : }
12782 : return true;
12783 : }
12784 :
12785 : /* Extract constant string at LOCATON into output string STR.
12786 : Returns true if successful, otherwise false. */
12787 :
12788 : bool
12789 405 : cexpr_str::extract (location_t location, tree &str)
12790 : {
12791 405 : const char *msg;
12792 405 : int len;
12793 405 : if (!extract (location, msg, len))
12794 : return false;
12795 343 : str = build_string (len, msg);
12796 343 : return true;
12797 : }
12798 :
12799 : /* Extract constant string at LOCATION into output string MSG with LEN.
12800 : Returns true if successful, otherwise false. */
12801 :
12802 : bool
12803 2138 : cexpr_str::extract (location_t location, const char * &msg, int &len,
12804 : const constexpr_ctx *ctx /* = NULL */,
12805 : bool *non_constant_p /* = NULL */,
12806 : bool *overflow_p /* = NULL */,
12807 : tree *jump_target /* = NULL */)
12808 : {
12809 2138 : tsubst_flags_t complain = tf_warning_or_error;
12810 :
12811 2138 : msg = NULL;
12812 2138 : if (message_sz && message_data)
12813 : {
12814 617 : tree msz;
12815 617 : if (ctx)
12816 : {
12817 52 : msz = cxx_eval_constant_expression (ctx, message_sz, vc_prvalue,
12818 : non_constant_p, overflow_p,
12819 : jump_target);
12820 52 : if (*jump_target || *non_constant_p)
12821 : return false;
12822 : }
12823 : else
12824 565 : msz = cxx_constant_value (message_sz, NULL_TREE, complain);
12825 613 : if (!tree_fits_uhwi_p (msz))
12826 : {
12827 35 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12828 35 : error_at (location,
12829 : "constexpr string %<size()%> "
12830 : "must be a constant expression");
12831 35 : return false;
12832 : }
12833 578 : else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
12834 : != tree_to_uhwi (msz))
12835 : {
12836 0 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12837 0 : error_at (location,
12838 : "constexpr string message %<size()%> "
12839 : "%qE too large", msz);
12840 0 : return false;
12841 : }
12842 578 : len = tree_to_uhwi (msz);
12843 578 : tree data;
12844 578 : if (ctx)
12845 : {
12846 48 : data = cxx_eval_constant_expression (ctx, message_data, vc_prvalue,
12847 : non_constant_p, overflow_p,
12848 : jump_target);
12849 48 : if (*jump_target || *non_constant_p)
12850 : return false;
12851 44 : STRIP_NOPS (data);
12852 44 : if (TREE_CODE (data) != ADDR_EXPR)
12853 : {
12854 0 : unhandled:
12855 0 : if (!cxx_constexpr_quiet_p (ctx))
12856 0 : error_at (location, "unhandled return from %<data()%>");
12857 0 : return false;
12858 : }
12859 44 : tree str = TREE_OPERAND (data, 0);
12860 44 : unsigned HOST_WIDE_INT off = 0;
12861 44 : if (TREE_CODE (str) == ARRAY_REF
12862 44 : && tree_fits_uhwi_p (TREE_OPERAND (str, 1)))
12863 : {
12864 6 : off = tree_to_uhwi (TREE_OPERAND (str, 1));
12865 6 : str = TREE_OPERAND (str, 0);
12866 : }
12867 44 : str = cxx_eval_constant_expression (ctx, str, vc_prvalue,
12868 : non_constant_p, overflow_p,
12869 : jump_target);
12870 44 : if (*jump_target || *non_constant_p)
12871 : return false;
12872 44 : if (TREE_CODE (str) == STRING_CST)
12873 : {
12874 42 : if (TREE_STRING_LENGTH (str) < len
12875 42 : || (unsigned) TREE_STRING_LENGTH (str) < off
12876 84 : || (unsigned) TREE_STRING_LENGTH (str) < off + len)
12877 0 : goto unhandled;
12878 42 : msg = TREE_STRING_POINTER (str) + off;
12879 42 : goto translate;
12880 : }
12881 2 : if (TREE_CODE (str) != CONSTRUCTOR
12882 2 : || TREE_CODE (TREE_TYPE (str)) != ARRAY_TYPE)
12883 0 : goto unhandled;
12884 2 : char *b;
12885 2 : if (len < 64)
12886 2 : b = XALLOCAVEC (char, len + 1);
12887 : else
12888 : {
12889 0 : buf = XNEWVEC (char, len + 1);
12890 0 : b = buf;
12891 : }
12892 2 : msg = b;
12893 2 : memset (b, 0, len + 1);
12894 2 : tree field, value;
12895 2 : unsigned k;
12896 2 : unsigned HOST_WIDE_INT l = 0;
12897 22 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (str), k, field, value)
12898 22 : if (!tree_fits_shwi_p (value))
12899 0 : goto unhandled;
12900 22 : else if (field == NULL_TREE)
12901 : {
12902 0 : if (integer_zerop (value))
12903 : break;
12904 0 : if (l >= off && l < off + len)
12905 0 : b[l - off] = tree_to_shwi (value);
12906 0 : ++l;
12907 : }
12908 22 : else if (TREE_CODE (field) == RANGE_EXPR)
12909 : {
12910 0 : tree lo = TREE_OPERAND (field, 0);
12911 0 : tree hi = TREE_OPERAND (field, 1);
12912 0 : if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
12913 0 : goto unhandled;
12914 0 : if (integer_zerop (value))
12915 : break;
12916 0 : unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
12917 0 : for (l = tree_to_uhwi (lo); l <= m; ++l)
12918 0 : if (l >= off && l < off + len)
12919 0 : b[l - off] = tree_to_shwi (value);
12920 : }
12921 22 : else if (tree_fits_uhwi_p (field))
12922 : {
12923 22 : l = tree_to_uhwi (field);
12924 22 : if (integer_zerop (value))
12925 : break;
12926 20 : if (l >= off && l < off + len)
12927 20 : b[l - off] = tree_to_shwi (value);
12928 20 : l++;
12929 : }
12930 2 : b[len] = '\0';
12931 : }
12932 : else
12933 : {
12934 530 : data = maybe_constant_value (message_data, NULL_TREE, mce_true);
12935 530 : if (!reduced_constant_expression_p (data))
12936 96 : data = NULL_TREE;
12937 530 : if (len)
12938 : {
12939 453 : if (data)
12940 379 : msg = c_getstr (data);
12941 453 : if (msg == NULL)
12942 119 : buf = XNEWVEC (char, len);
12943 1452 : for (int i = 0; i < len; ++i)
12944 : {
12945 1029 : tree t = message_data;
12946 1029 : if (i)
12947 1152 : t = build2 (POINTER_PLUS_EXPR,
12948 576 : TREE_TYPE (message_data), message_data,
12949 576 : size_int (i));
12950 1029 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
12951 1029 : tree t2 = cxx_constant_value (t, NULL_TREE, complain);
12952 1029 : if (!tree_fits_shwi_p (t2))
12953 : {
12954 30 : error_at (location,
12955 : "constexpr string %<data()[%d]%> "
12956 : "must be a constant expression", i);
12957 30 : return false;
12958 : }
12959 999 : if (msg == NULL)
12960 362 : buf[i] = tree_to_shwi (t2);
12961 : /* If c_getstr worked, just verify the first and
12962 : last characters using constant evaluation. */
12963 637 : else if (len > 2 && i == 0)
12964 266 : i = len - 2;
12965 : }
12966 423 : if (msg == NULL)
12967 104 : msg = buf;
12968 : }
12969 77 : else if (!data)
12970 : {
12971 : /* We don't have any function to test whether some
12972 : expression is a core constant expression. So, instead
12973 : test whether (message.data (), 0) is a constant
12974 : expression. */
12975 22 : data = build2 (COMPOUND_EXPR, integer_type_node,
12976 : message_data, integer_zero_node);
12977 22 : tree t = cxx_constant_value (data, NULL_TREE, complain);
12978 22 : if (!integer_zerop (t))
12979 : {
12980 22 : error_at (location,
12981 : "constexpr string %<data()%> "
12982 : "must be a core constant expression");
12983 22 : return false;
12984 : }
12985 : }
12986 : }
12987 : }
12988 : else
12989 : {
12990 1521 : tree eltype = TREE_TYPE (TREE_TYPE (message));
12991 1521 : int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
12992 1521 : msg = TREE_STRING_POINTER (message);
12993 1521 : len = TREE_STRING_LENGTH (message) / sz - 1;
12994 : }
12995 2043 : translate:
12996 2043 : if ((message_sz && message_data) || ctx)
12997 : {
12998 : /* Convert the string from execution charset to SOURCE_CHARSET. */
12999 608 : cpp_string istr, ostr;
13000 608 : istr.len = len;
13001 608 : istr.text = (const unsigned char *) msg;
13002 608 : enum cpp_ttype type = CPP_STRING;
13003 608 : if (message_sz && message_data)
13004 : {
13005 522 : if (POINTER_TYPE_P (TREE_TYPE (message_data))
13006 522 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
13007 522 : == char8_type_node))
13008 : type = CPP_UTF8STRING;
13009 : }
13010 86 : else if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message)))
13011 86 : == char8_type_node)
13012 608 : type = CPP_UTF8STRING;
13013 608 : if (len == 0)
13014 : ;
13015 525 : else if (!cpp_translate_string (parse_in, &istr, &ostr, type,
13016 : true))
13017 : {
13018 0 : if (type == CPP_UTF8STRING)
13019 0 : error_at (location, "could not convert constexpr string from "
13020 : "UTF-8 encoding to source character "
13021 : "set");
13022 : else
13023 0 : error_at (location, "could not convert constexpr string from "
13024 : "ordinary literal encoding to source character "
13025 : "set");
13026 0 : return false;
13027 : }
13028 : else
13029 : {
13030 525 : if (buf)
13031 104 : XDELETEVEC (buf);
13032 525 : msg = buf = const_cast <char *> ((const char *) ostr.text);
13033 525 : len = ostr.len;
13034 : }
13035 : }
13036 :
13037 : return true;
13038 : }
13039 :
13040 : /* Build a STATIC_ASSERT for a static assertion with the condition
13041 : CONDITION and the message text MESSAGE. LOCATION is the location
13042 : of the static assertion in the source code. When MEMBER_P, this
13043 : static assertion is a member of a class. If SHOW_EXPR_P is true,
13044 : print the condition (because it was instantiation-dependent).
13045 : If CONSTEVAL_BLOCK_P is true, this static assertion represents
13046 : a consteval block. */
13047 :
13048 : void
13049 10774420 : finish_static_assert (tree condition, tree message, location_t location,
13050 : bool member_p, bool show_expr_p,
13051 : bool consteval_block_p/*=false*/)
13052 : {
13053 10774420 : tsubst_flags_t complain = tf_warning_or_error;
13054 :
13055 10774420 : if (condition == NULL_TREE
13056 10774420 : || condition == error_mark_node)
13057 4386946 : return;
13058 :
13059 10774256 : if (check_for_bare_parameter_packs (condition))
13060 : return;
13061 :
13062 10774253 : cexpr_str cstr(message);
13063 10774253 : if (!cstr.type_check (location))
13064 : return;
13065 :
13066 : /* Save the condition in case it was a concept check. */
13067 10774159 : tree orig_condition = condition;
13068 :
13069 10774159 : if (instantiation_dependent_expression_p (condition)
13070 10774159 : || instantiation_dependent_expression_p (message))
13071 : {
13072 : /* We're in a template; build a STATIC_ASSERT and put it in
13073 : the right place. */
13074 4386450 : defer:
13075 4386450 : tree assertion = make_node (STATIC_ASSERT);
13076 4386450 : STATIC_ASSERT_CONDITION (assertion) = orig_condition;
13077 4386450 : STATIC_ASSERT_MESSAGE (assertion) = cstr.message;
13078 4386450 : STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
13079 4386450 : CONSTEVAL_BLOCK_P (assertion) = consteval_block_p;
13080 :
13081 4386450 : if (member_p)
13082 2285843 : maybe_add_class_template_decl_list (current_class_type,
13083 : assertion,
13084 : /*friend_p=*/0);
13085 : else
13086 2100607 : add_stmt (assertion);
13087 :
13088 4386450 : return;
13089 : }
13090 :
13091 : /* Evaluate the consteval { }. This must be done only once. */
13092 6390172 : if (consteval_block_p)
13093 : {
13094 210 : cxx_constant_value (condition);
13095 210 : return;
13096 : }
13097 :
13098 : /* Fold the expression and convert it to a boolean value. */
13099 6389962 : condition = contextual_conv_bool (condition, complain);
13100 6389962 : condition = fold_non_dependent_expr (condition, complain,
13101 : /*manifestly_const_eval=*/true);
13102 :
13103 6389961 : if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
13104 : /* Do nothing; the condition is satisfied. */
13105 : ;
13106 : else
13107 : {
13108 4551 : iloc_sentinel ils (location);
13109 :
13110 4551 : if (integer_zerop (condition))
13111 : {
13112 : /* CWG2518: static_assert failure in a template is not IFNDR. */
13113 4058 : if (processing_template_decl)
13114 2463 : goto defer;
13115 :
13116 1595 : int len;
13117 1595 : const char *msg = NULL;
13118 1595 : if (!cstr.extract (location, msg, len))
13119 25 : return;
13120 :
13121 : /* See if we can find which clause was failing (for logical AND). */
13122 1570 : tree bad = find_failing_clause (NULL, orig_condition);
13123 : /* If not, or its location is unusable, fall back to the previous
13124 : location. */
13125 1570 : location_t cloc = cp_expr_loc_or_loc (bad, location);
13126 :
13127 1570 : auto_diagnostic_group d;
13128 :
13129 : /* Report the error. */
13130 1570 : if (len == 0)
13131 976 : error_at (cloc, "static assertion failed");
13132 : else
13133 594 : error_at (cloc, "static assertion failed: %.*s", len, msg);
13134 :
13135 1570 : diagnose_failing_condition (bad, cloc, show_expr_p);
13136 :
13137 : /* Suppress -Wreturn-type for functions with failed static_asserts.
13138 : Otherwise templates like:
13139 : if constexpr (whatever)
13140 : return something (args);
13141 : else
13142 : static_assert (false, "explanation");
13143 : get a useless extra -Wreturn-type warning. */
13144 1570 : if (current_function_decl)
13145 574 : suppress_warning (current_function_decl, OPT_Wreturn_type);
13146 1570 : }
13147 493 : else if (condition && condition != error_mark_node)
13148 : {
13149 490 : error ("non-constant condition for static assertion");
13150 490 : if (require_rvalue_constant_expression (condition))
13151 434 : cxx_constant_value (condition);
13152 : }
13153 4551 : }
13154 10774252 : }
13155 :
13156 : /* Implements the C++0x decltype keyword. Returns the type of EXPR,
13157 : suitable for use as a type-specifier.
13158 :
13159 : ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
13160 : id-expression or a class member access, FALSE when it was parsed as
13161 : a full expression. */
13162 :
13163 : tree
13164 62605778 : finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
13165 : tsubst_flags_t complain)
13166 : {
13167 62605778 : tree type = NULL_TREE;
13168 :
13169 62605778 : if (!expr || error_operand_p (expr))
13170 224801 : return error_mark_node;
13171 :
13172 62380977 : if (TYPE_P (expr)
13173 62380977 : || TREE_CODE (expr) == TYPE_DECL
13174 124761936 : || (TREE_CODE (expr) == BIT_NOT_EXPR
13175 13134 : && TYPE_P (TREE_OPERAND (expr, 0))))
13176 : {
13177 27 : if (complain & tf_error)
13178 27 : error ("argument to %<decltype%> must be an expression");
13179 27 : return error_mark_node;
13180 : }
13181 :
13182 : /* decltype is an unevaluated context. */
13183 62380950 : cp_unevaluated u;
13184 :
13185 62380950 : processing_template_decl_sentinel ptds (/*reset=*/false);
13186 :
13187 : /* Depending on the resolution of DR 1172, we may later need to distinguish
13188 : instantiation-dependent but not type-dependent expressions so that, say,
13189 : A<decltype(sizeof(T))>::U doesn't require 'typename'. */
13190 62380950 : if (instantiation_dependent_uneval_expression_p (expr))
13191 : {
13192 6822288 : dependent:
13193 6822672 : type = cxx_make_type (DECLTYPE_TYPE);
13194 6822672 : DECLTYPE_TYPE_EXPR (type) = expr;
13195 13645344 : DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
13196 6822672 : = id_expression_or_member_access_p;
13197 6822672 : SET_TYPE_STRUCTURAL_EQUALITY (type);
13198 :
13199 6822672 : return type;
13200 : }
13201 55558662 : else if (processing_template_decl)
13202 : {
13203 4290 : expr = instantiate_non_dependent_expr (expr, complain|tf_decltype);
13204 4290 : if (expr == error_mark_node)
13205 : return error_mark_node;
13206 : /* Keep processing_template_decl cleared for the rest of the function
13207 : (for sake of the call to lvalue_kind below, which handles templated
13208 : and non-templated COND_EXPR differently). */
13209 4253 : processing_template_decl = 0;
13210 : }
13211 :
13212 : /* The type denoted by decltype(e) is defined as follows: */
13213 :
13214 55558625 : expr = resolve_nondeduced_context (expr, complain);
13215 55558625 : if (!mark_single_function (expr, complain))
13216 0 : return error_mark_node;
13217 :
13218 55558625 : if (invalid_nonstatic_memfn_p (input_location, expr, complain))
13219 18 : return error_mark_node;
13220 :
13221 55558607 : if (type_unknown_p (expr))
13222 : {
13223 18 : if (complain & tf_error)
13224 6 : error ("%<decltype%> cannot resolve address of overloaded function");
13225 18 : return error_mark_node;
13226 : }
13227 :
13228 55558589 : if (id_expression_or_member_access_p)
13229 : {
13230 : /* If e is an id-expression or a class member access (5.2.5
13231 : [expr.ref]), decltype(e) is defined as the type of the entity
13232 : named by e. If there is no such entity, or e names a set of
13233 : overloaded functions, the program is ill-formed. */
13234 2834266 : if (identifier_p (expr))
13235 0 : expr = lookup_name (expr);
13236 :
13237 : /* If e is a constified expression inside a contract assertion,
13238 : strip the const wrapper. Per P2900R14, "For a function f with the
13239 : return type T , the result name is an lvalue of type const T , decltype(r)
13240 : is T , and decltype((r)) is const T&." */
13241 2834266 : expr = strip_contract_const_wrapper (expr);
13242 :
13243 2834266 : if (INDIRECT_REF_P (expr)
13244 2834266 : || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
13245 : /* This can happen when the expression is, e.g., "a.b". Just
13246 : look at the underlying operand. */
13247 2596968 : expr = TREE_OPERAND (expr, 0);
13248 :
13249 2834266 : if (TREE_CODE (expr) == OFFSET_REF
13250 2834266 : || TREE_CODE (expr) == MEMBER_REF
13251 2834266 : || TREE_CODE (expr) == SCOPE_REF)
13252 : /* We're only interested in the field itself. If it is a
13253 : BASELINK, we will need to see through it in the next
13254 : step. */
13255 0 : expr = TREE_OPERAND (expr, 1);
13256 :
13257 2834266 : if (BASELINK_P (expr))
13258 : /* See through BASELINK nodes to the underlying function. */
13259 5 : expr = BASELINK_FUNCTIONS (expr);
13260 :
13261 : /* decltype of a decomposition name drops references in the tuple case
13262 : (unlike decltype of a normal variable) and keeps cv-qualifiers from
13263 : the containing object in the other cases (unlike decltype of a member
13264 : access expression). */
13265 2834266 : if (DECL_DECOMPOSITION_P (expr))
13266 : {
13267 1412 : if (ptds.saved)
13268 : {
13269 275 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr)
13270 : || (DECL_CONTEXT (expr)
13271 : != current_function_decl));
13272 : /* DECL_HAS_VALUE_EXPR_P is always set if
13273 : processing_template_decl at least for structured bindings
13274 : within the template. If lookup_decomp_type
13275 : returns non-NULL, it is the tuple case. */
13276 275 : if (tree ret = lookup_decomp_type (expr))
13277 : return ret;
13278 191 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
13279 : }
13280 1328 : if (DECL_HAS_VALUE_EXPR_P (expr))
13281 : /* Expr is an array or struct subobject proxy, handle
13282 : bit-fields properly. */
13283 1016 : return unlowered_expr_type (expr);
13284 : else
13285 : /* Expr is a reference variable for the tuple case. */
13286 312 : return lookup_decomp_type (expr);
13287 : }
13288 :
13289 2832854 : switch (TREE_CODE (expr))
13290 : {
13291 222 : case FIELD_DECL:
13292 222 : if (DECL_BIT_FIELD_TYPE (expr))
13293 : {
13294 : type = DECL_BIT_FIELD_TYPE (expr);
13295 : break;
13296 : }
13297 : /* Fall through for fields that aren't bitfields. */
13298 194960 : gcc_fallthrough ();
13299 :
13300 194960 : case VAR_DECL:
13301 194960 : if (is_capture_proxy (expr))
13302 : {
13303 85 : if (is_normal_capture_proxy (expr))
13304 : {
13305 21 : expr = DECL_CAPTURED_VARIABLE (expr);
13306 21 : type = TREE_TYPE (expr);
13307 : }
13308 : else
13309 : {
13310 64 : expr = DECL_VALUE_EXPR (expr);
13311 64 : gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
13312 64 : expr = TREE_OPERAND (expr, 1);
13313 64 : type = TREE_TYPE (expr);
13314 : }
13315 : break;
13316 : }
13317 : /* Fall through for variables that aren't capture proxies. */
13318 2829090 : gcc_fallthrough ();
13319 :
13320 2829090 : case FUNCTION_DECL:
13321 2829090 : case CONST_DECL:
13322 2829090 : case PARM_DECL:
13323 2829090 : case RESULT_DECL:
13324 2829090 : case TEMPLATE_PARM_INDEX:
13325 2829090 : expr = mark_type_use (expr);
13326 2829090 : type = TREE_TYPE (expr);
13327 2829090 : if (VAR_P (expr) && DECL_NTTP_OBJECT_P (expr))
13328 : {
13329 : /* decltype of an NTTP object is the type of the template
13330 : parameter, which is the object type modulo cv-quals. */
13331 1150 : int quals = cp_type_quals (type);
13332 1150 : gcc_checking_assert (quals & TYPE_QUAL_CONST);
13333 1150 : type = cv_unqualified (type);
13334 : }
13335 : break;
13336 :
13337 0 : case ERROR_MARK:
13338 0 : type = error_mark_node;
13339 0 : break;
13340 :
13341 3035 : case COMPONENT_REF:
13342 3035 : case COMPOUND_EXPR:
13343 3035 : mark_type_use (expr);
13344 3035 : type = is_bitfield_expr_with_lowered_type (expr);
13345 3035 : if (!type)
13346 3000 : type = TREE_TYPE (TREE_OPERAND (expr, 1));
13347 : break;
13348 :
13349 0 : case BIT_FIELD_REF:
13350 0 : gcc_unreachable ();
13351 :
13352 408 : case INTEGER_CST:
13353 408 : case PTRMEM_CST:
13354 : /* We can get here when the id-expression refers to an
13355 : enumerator or non-type template parameter. */
13356 408 : type = TREE_TYPE (expr);
13357 408 : break;
13358 :
13359 236 : default:
13360 : /* Handle instantiated template non-type arguments. */
13361 236 : type = TREE_TYPE (expr);
13362 236 : break;
13363 : }
13364 : }
13365 : else
13366 : {
13367 52724323 : tree decl = STRIP_REFERENCE_REF (expr);
13368 52724323 : tree lam = current_lambda_expr ();
13369 52724323 : if (lam && outer_automatic_var_p (decl))
13370 : {
13371 : /* [expr.prim.id.unqual]/3: If naming the entity from outside of an
13372 : unevaluated operand within S would refer to an entity captured by
13373 : copy in some intervening lambda-expression, then let E be the
13374 : innermost such lambda-expression.
13375 :
13376 : If there is such a lambda-expression and if P is in E's function
13377 : parameter scope but not its parameter-declaration-clause, then the
13378 : type of the expression is the type of a class member access
13379 : expression naming the non-static data member that would be declared
13380 : for such a capture in the object parameter of the function call
13381 : operator of E." */
13382 : /* FIXME: This transformation needs to happen for all uses of an outer
13383 : local variable inside decltype, not just decltype((x)) (PR83167).
13384 : And we don't handle nested lambdas properly, where we need to
13385 : consider the outer lambdas as well (PR112926). */
13386 940 : tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK,
13387 : LOOK_want::HIDDEN_LAMBDA);
13388 :
13389 940 : if (cap && is_capture_proxy (cap))
13390 319 : type = TREE_TYPE (cap);
13391 621 : else if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_COPY)
13392 : {
13393 500 : type = TREE_TYPE (decl);
13394 500 : if (TYPE_REF_P (type)
13395 500 : && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
13396 25 : type = TREE_TYPE (type);
13397 : }
13398 :
13399 819 : if (type && !TYPE_REF_P (type))
13400 : {
13401 761 : int quals;
13402 761 : if (current_function_decl
13403 1428 : && LAMBDA_FUNCTION_P (current_function_decl)
13404 1428 : && DECL_XOBJ_MEMBER_FUNCTION_P (current_function_decl))
13405 : {
13406 600 : tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl));
13407 600 : if (WILDCARD_TYPE_P (non_reference (obtype)))
13408 : /* We don't know what the eventual obtype quals will be. */
13409 384 : goto dependent;
13410 432 : auto direct_type = [](tree t){
13411 216 : if (INDIRECT_TYPE_P (t))
13412 108 : return TREE_TYPE (t);
13413 : return t;
13414 : };
13415 432 : quals = (cp_type_quals (type)
13416 216 : | cp_type_quals (direct_type (obtype)));
13417 : }
13418 : else
13419 : /* We are in the parameter clause, trailing return type, or
13420 : the requires clause and have no relevant c_f_decl yet. */
13421 251 : quals = (LAMBDA_EXPR_CONST_QUAL_P (lam)
13422 161 : ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
13423 377 : type = cp_build_qualified_type (type, quals);
13424 377 : type = build_reference_type (type);
13425 : }
13426 : }
13427 52723383 : else if (error_operand_p (expr))
13428 0 : type = error_mark_node;
13429 52723383 : else if (expr == current_class_ptr)
13430 : /* If the expression is just "this", we want the
13431 : cv-unqualified pointer for the "this" type. */
13432 0 : type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
13433 :
13434 377 : if (!type)
13435 : {
13436 : /* Otherwise, where T is the type of e, if e is an lvalue,
13437 : decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
13438 52723504 : cp_lvalue_kind clk = lvalue_kind (expr);
13439 52723504 : type = unlowered_expr_type (expr);
13440 52723504 : gcc_assert (!TYPE_REF_P (type));
13441 :
13442 : /* For vector types, pick a non-opaque variant. */
13443 52723504 : if (VECTOR_TYPE_P (type))
13444 127 : type = strip_typedefs (type);
13445 :
13446 52723504 : if (clk != clk_none && !(clk & clk_class))
13447 10492744 : type = cp_build_reference_type (type, (clk & clk_rvalueref));
13448 : }
13449 : }
13450 :
13451 : return type;
13452 62380950 : }
13453 :
13454 : /* Called from trait_expr_value to evaluate either __has_nothrow_assign or
13455 : __has_nothrow_copy, depending on assign_p. Returns true iff all
13456 : the copy {ctor,assign} fns are nothrow. */
13457 :
13458 : static bool
13459 279 : classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
13460 : {
13461 279 : tree fns = NULL_TREE;
13462 :
13463 279 : if (assign_p || TYPE_HAS_COPY_CTOR (type))
13464 276 : fns = get_class_binding (type, assign_p ? assign_op_identifier
13465 : : ctor_identifier);
13466 :
13467 279 : bool saw_copy = false;
13468 696 : for (ovl_iterator iter (fns); iter; ++iter)
13469 : {
13470 441 : tree fn = *iter;
13471 :
13472 441 : if (copy_fn_p (fn) > 0)
13473 : {
13474 423 : saw_copy = true;
13475 423 : if (!maybe_instantiate_noexcept (fn)
13476 423 : || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
13477 192 : return false;
13478 : }
13479 : }
13480 :
13481 87 : return saw_copy;
13482 : }
13483 :
13484 : /* Return true if BASE is a pointer-interconvertible base of DERIVED. */
13485 :
13486 : bool
13487 157 : pointer_interconvertible_base_of_p (tree base, tree derived,
13488 : bool explain/*=false*/)
13489 : {
13490 157 : if (base == error_mark_node || derived == error_mark_node)
13491 : return false;
13492 :
13493 157 : base = TYPE_MAIN_VARIANT (base);
13494 157 : derived = TYPE_MAIN_VARIANT (derived);
13495 157 : if (!NON_UNION_CLASS_TYPE_P (base))
13496 : {
13497 15 : if (explain)
13498 3 : inform (location_of (base),
13499 : "%qT is not a non-union class type", base);
13500 15 : return false;
13501 : }
13502 142 : if (!NON_UNION_CLASS_TYPE_P (derived))
13503 : {
13504 6 : if (explain)
13505 3 : inform (location_of (derived),
13506 : "%qT is not a non-union class type", derived);
13507 6 : return false;
13508 : }
13509 :
13510 136 : if (same_type_p (base, derived))
13511 : return true;
13512 :
13513 106 : if (!std_layout_type_p (derived))
13514 : {
13515 17 : if (explain)
13516 6 : inform (location_of (derived),
13517 : "%qT is not a standard-layout type", derived);
13518 17 : return false;
13519 : }
13520 :
13521 89 : if (!uniquely_derived_from_p (base, derived))
13522 : {
13523 16 : if (explain)
13524 : {
13525 : /* An ambiguous base should already be impossible due to
13526 : the std_layout_type_p check. */
13527 3 : gcc_checking_assert (!DERIVED_FROM_P (base, derived));
13528 3 : inform (location_of (derived),
13529 : "%qT is not a base of %qT", base, derived);
13530 : }
13531 16 : return false;
13532 : }
13533 :
13534 : return true;
13535 : }
13536 :
13537 : /* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
13538 : return true if MEMBERTYPE is the type of the first non-static data member
13539 : of TYPE or for unions of any members. */
13540 : static bool
13541 637 : first_nonstatic_data_member_p (tree type, tree membertype)
13542 : {
13543 1297 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13544 : {
13545 1222 : if (TREE_CODE (field) != FIELD_DECL)
13546 135 : continue;
13547 1087 : if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
13548 60 : continue;
13549 1027 : if (DECL_FIELD_IS_BASE (field))
13550 45 : return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
13551 982 : if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13552 : {
13553 216 : if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
13554 138 : || std_layout_type_p (TREE_TYPE (field)))
13555 294 : && first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
13556 : return true;
13557 : }
13558 766 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13559 : membertype))
13560 : return true;
13561 537 : if (TREE_CODE (type) != UNION_TYPE)
13562 : return false;
13563 : }
13564 : return false;
13565 : }
13566 :
13567 : /* Fold __builtin_is_pointer_interconvertible_with_class call. */
13568 :
13569 : tree
13570 536 : fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
13571 : tree *args)
13572 : {
13573 : /* Unless users call the builtin directly, the following 3 checks should be
13574 : ensured from std::is_pointer_interconvertible_with_class function
13575 : template. */
13576 536 : if (nargs != 1)
13577 : {
13578 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13579 : "needs a single argument");
13580 6 : return boolean_false_node;
13581 : }
13582 530 : tree arg = args[0];
13583 530 : if (error_operand_p (arg))
13584 0 : return boolean_false_node;
13585 530 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
13586 : {
13587 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13588 : "argument is not pointer to member");
13589 6 : return boolean_false_node;
13590 : }
13591 :
13592 524 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
13593 18 : return boolean_false_node;
13594 :
13595 506 : tree membertype = TREE_TYPE (TREE_TYPE (arg));
13596 506 : tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
13597 506 : if (!complete_type_or_else (basetype, NULL_TREE))
13598 3 : return boolean_false_node;
13599 :
13600 503 : if (TREE_CODE (basetype) != UNION_TYPE
13601 503 : && !std_layout_type_p (basetype))
13602 22 : return boolean_false_node;
13603 :
13604 481 : if (!first_nonstatic_data_member_p (basetype, membertype))
13605 132 : return boolean_false_node;
13606 :
13607 349 : if (TREE_CODE (arg) == PTRMEM_CST)
13608 68 : arg = cplus_expand_constant (arg);
13609 :
13610 349 : if (integer_nonzerop (arg))
13611 10 : return boolean_false_node;
13612 339 : if (integer_zerop (arg))
13613 71 : return boolean_true_node;
13614 :
13615 268 : return fold_build2 (EQ_EXPR, boolean_type_node, arg,
13616 : build_zero_cst (TREE_TYPE (arg)));
13617 : }
13618 :
13619 : /* Helper function for is_corresponding_member_aggr. Return true if
13620 : MEMBERTYPE pointer-to-data-member ARG can be found in anonymous
13621 : union or structure BASETYPE. */
13622 :
13623 : static bool
13624 90 : is_corresponding_member_union (tree basetype, tree membertype, tree arg)
13625 : {
13626 222 : for (tree field = TYPE_FIELDS (basetype); field; field = DECL_CHAIN (field))
13627 192 : if (TREE_CODE (field) != FIELD_DECL || DECL_BIT_FIELD_TYPE (field))
13628 36 : continue;
13629 156 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13630 : membertype))
13631 : {
13632 48 : if (TREE_CODE (arg) != INTEGER_CST
13633 48 : || tree_int_cst_equal (arg, byte_position (field)))
13634 48 : return true;
13635 : }
13636 108 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13637 : {
13638 18 : tree narg = arg;
13639 18 : if (TREE_CODE (basetype) != UNION_TYPE
13640 0 : && TREE_CODE (narg) == INTEGER_CST)
13641 0 : narg = size_binop (MINUS_EXPR, arg, byte_position (field));
13642 18 : if (is_corresponding_member_union (TREE_TYPE (field),
13643 : membertype, narg))
13644 : return true;
13645 : }
13646 : return false;
13647 : }
13648 :
13649 : /* Helper function for fold_builtin_is_corresponding_member call.
13650 : Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and
13651 : MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members,
13652 : boolean_true_node if they are corresponding members, or for
13653 : non-constant ARG2 the highest member offset for corresponding
13654 : members. */
13655 :
13656 : static tree
13657 550 : is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
13658 : tree arg1, tree basetype2, tree membertype2,
13659 : tree arg2)
13660 : {
13661 550 : tree field1 = TYPE_FIELDS (basetype1);
13662 550 : tree field2 = TYPE_FIELDS (basetype2);
13663 550 : tree ret = boolean_false_node;
13664 2376 : while (1)
13665 : {
13666 1463 : bool r = next_common_initial_sequence (field1, field2);
13667 1463 : if (field1 == NULL_TREE || field2 == NULL_TREE)
13668 : break;
13669 1331 : if (r
13670 1038 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field1),
13671 : membertype1)
13672 1841 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field2),
13673 : membertype2))
13674 : {
13675 504 : tree pos = byte_position (field1);
13676 504 : if (TREE_CODE (arg1) == INTEGER_CST
13677 504 : && tree_int_cst_equal (arg1, pos))
13678 : {
13679 92 : if (TREE_CODE (arg2) == INTEGER_CST)
13680 92 : return boolean_true_node;
13681 : return pos;
13682 : }
13683 412 : else if (TREE_CODE (arg1) != INTEGER_CST)
13684 1188 : ret = pos;
13685 : }
13686 1654 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field1))
13687 944 : && ANON_AGGR_TYPE_P (TREE_TYPE (field2)))
13688 : {
13689 117 : if ((!lookup_attribute ("no_unique_address",
13690 117 : DECL_ATTRIBUTES (field1)))
13691 117 : != !lookup_attribute ("no_unique_address",
13692 117 : DECL_ATTRIBUTES (field2)))
13693 : break;
13694 117 : if (!tree_int_cst_equal (bit_position (field1),
13695 117 : bit_position (field2)))
13696 : break;
13697 99 : bool overlap = true;
13698 99 : tree pos = byte_position (field1);
13699 99 : if (TREE_CODE (arg1) == INTEGER_CST)
13700 : {
13701 27 : tree off1 = fold_convert (sizetype, arg1);
13702 27 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (field1));
13703 27 : if (tree_int_cst_lt (off1, pos)
13704 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz1), off1))
13705 : overlap = false;
13706 : }
13707 99 : if (TREE_CODE (arg2) == INTEGER_CST)
13708 : {
13709 27 : tree off2 = fold_convert (sizetype, arg2);
13710 27 : tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (field2));
13711 27 : if (tree_int_cst_lt (off2, pos)
13712 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz2), off2))
13713 : overlap = false;
13714 : }
13715 87 : if (overlap
13716 87 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field1))
13717 126 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field2)))
13718 : {
13719 39 : tree narg1 = arg1;
13720 39 : if (TREE_CODE (arg1) == INTEGER_CST)
13721 9 : narg1 = size_binop (MINUS_EXPR,
13722 : fold_convert (sizetype, arg1), pos);
13723 39 : tree narg2 = arg2;
13724 39 : if (TREE_CODE (arg2) == INTEGER_CST)
13725 9 : narg2 = size_binop (MINUS_EXPR,
13726 : fold_convert (sizetype, arg2), pos);
13727 39 : tree t1 = TREE_TYPE (field1);
13728 39 : tree t2 = TREE_TYPE (field2);
13729 39 : tree nret = is_corresponding_member_aggr (loc, t1, membertype1,
13730 : narg1, t2, membertype2,
13731 : narg2);
13732 39 : if (nret != boolean_false_node)
13733 : {
13734 39 : if (nret == boolean_true_node)
13735 : return nret;
13736 30 : if (TREE_CODE (arg1) == INTEGER_CST)
13737 0 : return size_binop (PLUS_EXPR, nret, pos);
13738 30 : ret = size_binop (PLUS_EXPR, nret, pos);
13739 : }
13740 : }
13741 60 : else if (overlap
13742 48 : && TREE_CODE (TREE_TYPE (field1)) == UNION_TYPE
13743 108 : && TREE_CODE (TREE_TYPE (field2)) == UNION_TYPE)
13744 : {
13745 48 : tree narg1 = arg1;
13746 48 : if (TREE_CODE (arg1) == INTEGER_CST)
13747 6 : narg1 = size_binop (MINUS_EXPR,
13748 : fold_convert (sizetype, arg1), pos);
13749 48 : tree narg2 = arg2;
13750 48 : if (TREE_CODE (arg2) == INTEGER_CST)
13751 6 : narg2 = size_binop (MINUS_EXPR,
13752 : fold_convert (sizetype, arg2), pos);
13753 48 : if (is_corresponding_member_union (TREE_TYPE (field1),
13754 : membertype1, narg1)
13755 48 : && is_corresponding_member_union (TREE_TYPE (field2),
13756 : membertype2, narg2))
13757 : {
13758 24 : sorry_at (loc, "%<__builtin_is_corresponding_member%> "
13759 : "not well defined for anonymous unions");
13760 24 : return boolean_false_node;
13761 : }
13762 : }
13763 : }
13764 1188 : if (!r)
13765 : break;
13766 913 : field1 = DECL_CHAIN (field1);
13767 913 : field2 = DECL_CHAIN (field2);
13768 913 : }
13769 : return ret;
13770 : }
13771 :
13772 : /* Fold __builtin_is_corresponding_member call. */
13773 :
13774 : tree
13775 699 : fold_builtin_is_corresponding_member (location_t loc, int nargs,
13776 : tree *args)
13777 : {
13778 : /* Unless users call the builtin directly, the following 3 checks should be
13779 : ensured from std::is_corresponding_member function template. */
13780 699 : if (nargs != 2)
13781 : {
13782 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13783 : "needs two arguments");
13784 9 : return boolean_false_node;
13785 : }
13786 690 : tree arg1 = args[0];
13787 690 : tree arg2 = args[1];
13788 690 : if (error_operand_p (arg1) || error_operand_p (arg2))
13789 0 : return boolean_false_node;
13790 711 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg1))
13791 705 : || !TYPE_PTRMEM_P (TREE_TYPE (arg2)))
13792 : {
13793 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13794 : "argument is not pointer to member");
13795 9 : return boolean_false_node;
13796 : }
13797 :
13798 681 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg1))
13799 681 : || !TYPE_PTRDATAMEM_P (TREE_TYPE (arg2)))
13800 15 : return boolean_false_node;
13801 :
13802 666 : tree membertype1 = TREE_TYPE (TREE_TYPE (arg1));
13803 666 : tree basetype1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg1));
13804 666 : if (!complete_type_or_else (basetype1, NULL_TREE))
13805 12 : return boolean_false_node;
13806 :
13807 654 : tree membertype2 = TREE_TYPE (TREE_TYPE (arg2));
13808 654 : tree basetype2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg2));
13809 654 : if (!complete_type_or_else (basetype2, NULL_TREE))
13810 12 : return boolean_false_node;
13811 :
13812 627 : if (!NON_UNION_CLASS_TYPE_P (basetype1)
13813 627 : || !NON_UNION_CLASS_TYPE_P (basetype2)
13814 627 : || !std_layout_type_p (basetype1)
13815 1233 : || !std_layout_type_p (basetype2))
13816 51 : return boolean_false_node;
13817 :
13818 : /* If the member types aren't layout compatible, then they
13819 : can't be corresponding members. */
13820 591 : if (!layout_compatible_type_p (membertype1, membertype2))
13821 18 : return boolean_false_node;
13822 :
13823 573 : if (TREE_CODE (arg1) == PTRMEM_CST)
13824 176 : arg1 = cplus_expand_constant (arg1);
13825 573 : if (TREE_CODE (arg2) == PTRMEM_CST)
13826 182 : arg2 = cplus_expand_constant (arg2);
13827 :
13828 573 : if (null_member_pointer_value_p (arg1)
13829 573 : || null_member_pointer_value_p (arg2))
13830 9 : return boolean_false_node;
13831 :
13832 564 : if (TREE_CODE (arg1) == INTEGER_CST
13833 182 : && TREE_CODE (arg2) == INTEGER_CST
13834 746 : && !tree_int_cst_equal (arg1, arg2))
13835 53 : return boolean_false_node;
13836 :
13837 511 : if (TREE_CODE (arg2) == INTEGER_CST
13838 129 : && TREE_CODE (arg1) != INTEGER_CST)
13839 : {
13840 : std::swap (arg1, arg2);
13841 : std::swap (membertype1, membertype2);
13842 : std::swap (basetype1, basetype2);
13843 : }
13844 :
13845 511 : tree ret = is_corresponding_member_aggr (loc, basetype1, membertype1, arg1,
13846 : basetype2, membertype2, arg2);
13847 511 : if (TREE_TYPE (ret) == boolean_type_node)
13848 : return ret;
13849 : /* If both arg1 and arg2 are INTEGER_CSTs, is_corresponding_member_aggr
13850 : already returns boolean_{true,false}_node whether those particular
13851 : members are corresponding members or not. Otherwise, if only
13852 : one of them is INTEGER_CST (canonicalized to first being INTEGER_CST
13853 : above), it returns boolean_false_node if it is certainly not a
13854 : corresponding member and otherwise we need to do a runtime check that
13855 : those two OFFSET_TYPE offsets are equal.
13856 : If neither of the operands is INTEGER_CST, is_corresponding_member_aggr
13857 : returns the largest offset at which the members would be corresponding
13858 : members, so perform arg1 <= ret && arg1 == arg2 runtime check. */
13859 304 : gcc_assert (TREE_CODE (arg2) != INTEGER_CST);
13860 304 : if (TREE_CODE (arg1) == INTEGER_CST)
13861 0 : return fold_build2 (EQ_EXPR, boolean_type_node, arg1,
13862 : fold_convert (TREE_TYPE (arg1), arg2));
13863 304 : ret = fold_build2 (LE_EXPR, boolean_type_node,
13864 : fold_convert (pointer_sized_int_node, arg1),
13865 : fold_convert (pointer_sized_int_node, ret));
13866 304 : return fold_build2 (TRUTH_AND_EXPR, boolean_type_node, ret,
13867 : fold_build2 (EQ_EXPR, boolean_type_node, arg1,
13868 : fold_convert (TREE_TYPE (arg1), arg2)));
13869 : }
13870 :
13871 : /* Fold __builtin_is_string_literal call. */
13872 :
13873 : tree
13874 1658 : fold_builtin_is_string_literal (location_t loc, int nargs, tree *args)
13875 : {
13876 : /* Unless users call the builtin directly, the following 3 checks should be
13877 : ensured from std::is_string_literal overloads. */
13878 1658 : if (nargs != 1)
13879 : {
13880 0 : error_at (loc, "%<__builtin_is_string_literal%> needs a single "
13881 : "argument");
13882 0 : return boolean_false_node;
13883 : }
13884 1658 : tree arg = args[0];
13885 1658 : if (error_operand_p (arg))
13886 0 : return boolean_false_node;
13887 1658 : if (!TYPE_PTR_P (TREE_TYPE (arg))
13888 1658 : || !TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg)))
13889 3316 : || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (arg))))
13890 : {
13891 0 : arg_invalid:
13892 0 : error_at (loc, "%<__builtin_is_string_literal%> "
13893 : "argument is not %<const char*%>, %<const wchar_t*%>, "
13894 : "%<const char8_t*%>, %<const char16_t*%> or "
13895 : "%<const char32_t*%>");
13896 0 : return boolean_false_node;
13897 : }
13898 1658 : tree chart = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg)));
13899 1658 : if (chart != char_type_node
13900 1324 : && chart != wchar_type_node
13901 993 : && chart != char8_type_node
13902 662 : && chart != char16_type_node
13903 331 : && chart != char32_type_node)
13904 0 : goto arg_invalid;
13905 :
13906 1658 : STRIP_NOPS (arg);
13907 3322 : while (TREE_CODE (arg) == POINTER_PLUS_EXPR)
13908 : {
13909 6 : arg = TREE_OPERAND (arg, 0);
13910 6 : STRIP_NOPS (arg);
13911 : }
13912 1658 : if (TREE_CODE (arg) != ADDR_EXPR)
13913 1630 : return boolean_false_node;
13914 28 : arg = TREE_OPERAND (arg, 0);
13915 28 : if (TREE_CODE (arg) == ARRAY_REF)
13916 12 : arg = TREE_OPERAND (arg, 0);
13917 28 : if (TREE_CODE (arg) != STRING_CST)
13918 8 : return boolean_false_node;
13919 20 : return boolean_true_node;
13920 : }
13921 :
13922 : /* [basic.types] 8. True iff TYPE is an object type. */
13923 :
13924 : static bool
13925 3320022 : object_type_p (const_tree type)
13926 : {
13927 3320022 : return (TREE_CODE (type) != FUNCTION_TYPE
13928 0 : && !TYPE_REF_P (type)
13929 3320022 : && !VOID_TYPE_P (type));
13930 : }
13931 :
13932 : /* [defns.referenceable] True iff TYPE is a referenceable type. */
13933 :
13934 : static bool
13935 4050627 : referenceable_type_p (const_tree type)
13936 : {
13937 4050627 : return (TYPE_REF_P (type)
13938 4051021 : || object_type_p (type)
13939 4051021 : || (FUNC_OR_METHOD_TYPE_P (type)
13940 332 : && type_memfn_quals (type) == TYPE_UNQUALIFIED
13941 272 : && type_memfn_rqual (type) == REF_QUAL_NONE));
13942 : }
13943 :
13944 : /* Actually evaluates the trait. */
13945 :
13946 : static bool
13947 21871170 : trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
13948 : {
13949 21871170 : enum tree_code type_code1;
13950 21871170 : tree t;
13951 :
13952 21871170 : type_code1 = TREE_CODE (type1);
13953 :
13954 21871170 : switch (kind)
13955 : {
13956 317 : case CPTK_HAS_NOTHROW_ASSIGN:
13957 317 : type1 = strip_array_types (type1);
13958 601 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
13959 601 : && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
13960 173 : || (CLASS_TYPE_P (type1)
13961 129 : && classtype_has_nothrow_assign_or_copy_p (type1,
13962 : true))));
13963 :
13964 215 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
13965 215 : type1 = strip_array_types (type1);
13966 215 : return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
13967 215 : || (CLASS_TYPE_P (type1)
13968 93 : && (t = locate_ctor (type1))
13969 60 : && maybe_instantiate_noexcept (t)
13970 58 : && TYPE_NOTHROW_P (TREE_TYPE (t))));
13971 :
13972 305 : case CPTK_HAS_NOTHROW_COPY:
13973 305 : type1 = strip_array_types (type1);
13974 305 : return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
13975 305 : || (CLASS_TYPE_P (type1)
13976 150 : && classtype_has_nothrow_assign_or_copy_p (type1, false)));
13977 :
13978 517 : case CPTK_HAS_TRIVIAL_ASSIGN:
13979 : /* ??? The standard seems to be missing the "or array of such a class
13980 : type" wording for this trait. */
13981 517 : type1 = strip_array_types (type1);
13982 1016 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
13983 1001 : && (trivial_type_p (type1)
13984 307 : || (CLASS_TYPE_P (type1)
13985 222 : && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
13986 :
13987 505 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
13988 505 : type1 = strip_array_types (type1);
13989 505 : return (trivial_type_p (type1)
13990 505 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
13991 :
13992 526 : case CPTK_HAS_TRIVIAL_COPY:
13993 : /* ??? The standard seems to be missing the "or array of such a class
13994 : type" wording for this trait. */
13995 526 : type1 = strip_array_types (type1);
13996 878 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
13997 863 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
13998 :
13999 761 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14000 761 : type1 = strip_array_types (type1);
14001 761 : if (CLASS_TYPE_P (type1) && type_build_dtor_call (type1))
14002 : {
14003 123 : deferring_access_check_sentinel dacs (dk_no_check);
14004 123 : cp_unevaluated un;
14005 123 : tree fn = get_dtor (type1, tf_none);
14006 123 : if (!fn && !seen_error ())
14007 3 : warning (0, "checking %qs for type %qT with a destructor that "
14008 : "cannot be called", "__has_trivial_destructor", type1);
14009 123 : }
14010 1092 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14011 1089 : || (CLASS_TYPE_P (type1)
14012 284 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
14013 :
14014 57408 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14015 57408 : return type_has_unique_obj_representations (type1);
14016 :
14017 279 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14018 279 : return type_has_virtual_destructor (type1);
14019 :
14020 54218 : case CPTK_IS_ABSTRACT:
14021 54218 : return ABSTRACT_CLASS_TYPE_P (type1);
14022 :
14023 813 : case CPTK_IS_AGGREGATE:
14024 813 : return CP_AGGREGATE_TYPE_P (type1);
14025 :
14026 482680 : case CPTK_IS_ARRAY:
14027 482680 : return (type_code1 == ARRAY_TYPE
14028 : /* We don't want to report T[0] as being an array type.
14029 : This is for compatibility with an implementation of
14030 : std::is_array by template argument deduction, because
14031 : compute_array_index_type_loc rejects a zero-size array
14032 : in SFINAE context. */
14033 482680 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14034 :
14035 1108935 : case CPTK_IS_ASSIGNABLE:
14036 1108935 : return is_xible (MODIFY_EXPR, type1, type2);
14037 :
14038 583010 : case CPTK_IS_BASE_OF:
14039 582919 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14040 1147491 : && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
14041 530380 : || DERIVED_FROM_P (type1, type2)));
14042 :
14043 90364 : case CPTK_IS_BOUNDED_ARRAY:
14044 90364 : return (type_code1 == ARRAY_TYPE
14045 1094 : && TYPE_DOMAIN (type1)
14046 : /* We don't want to report T[0] as being a bounded array type.
14047 : This is for compatibility with an implementation of
14048 : std::is_bounded_array by template argument deduction, because
14049 : compute_array_index_type_loc rejects a zero-size array
14050 : in SFINAE context. */
14051 91342 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14052 :
14053 678800 : case CPTK_IS_CLASS:
14054 678800 : return NON_UNION_CLASS_TYPE_P (type1);
14055 :
14056 706066 : case CPTK_IS_CONST:
14057 706066 : return CP_TYPE_CONST_P (type1);
14058 :
14059 3017287 : case CPTK_IS_CONSTRUCTIBLE:
14060 3017287 : return is_xible (INIT_EXPR, type1, type2);
14061 :
14062 3707260 : case CPTK_IS_CONVERTIBLE:
14063 3707260 : return is_convertible (type1, type2);
14064 :
14065 1722 : case CPTK_IS_DESTRUCTIBLE:
14066 1722 : return is_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14067 :
14068 245206 : case CPTK_IS_EMPTY:
14069 245206 : return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
14070 :
14071 709034 : case CPTK_IS_ENUM:
14072 709034 : return type_code1 == ENUMERAL_TYPE;
14073 :
14074 447546 : case CPTK_IS_FINAL:
14075 447546 : return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
14076 :
14077 61039 : case CPTK_IS_FUNCTION:
14078 61039 : return type_code1 == FUNCTION_TYPE;
14079 :
14080 667 : case CPTK_IS_IMPLICIT_LIFETIME:
14081 667 : return implicit_lifetime_type_p (type1);
14082 :
14083 45866 : case CPTK_IS_INVOCABLE:
14084 45866 : return !error_operand_p (build_invoke (type1, type2, tf_none));
14085 :
14086 195 : case CPTK_IS_LAYOUT_COMPATIBLE:
14087 195 : return layout_compatible_type_p (type1, type2);
14088 :
14089 197 : case CPTK_IS_LITERAL_TYPE:
14090 197 : return literal_type_p (type1);
14091 :
14092 46020 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14093 46020 : return TYPE_PTRMEMFUNC_P (type1);
14094 :
14095 45989 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14096 45989 : return TYPE_PTRDATAMEM_P (type1);
14097 :
14098 10211 : case CPTK_IS_MEMBER_POINTER:
14099 10211 : return TYPE_PTRMEM_P (type1);
14100 :
14101 543617 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14102 543617 : return is_nothrow_xible (MODIFY_EXPR, type1, type2);
14103 :
14104 1000540 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14105 1000540 : return is_nothrow_xible (INIT_EXPR, type1, type2);
14106 :
14107 667 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14108 667 : return is_nothrow_convertible (type1, type2);
14109 :
14110 23129 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14111 23129 : return is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14112 :
14113 40255 : case CPTK_IS_NOTHROW_INVOCABLE:
14114 40255 : return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
14115 :
14116 1262501 : case CPTK_IS_OBJECT:
14117 1262501 : return object_type_p (type1);
14118 :
14119 142 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14120 142 : return pointer_interconvertible_base_of_p (type1, type2);
14121 :
14122 11004 : case CPTK_IS_POD:
14123 11004 : return pod_type_p (type1);
14124 :
14125 151437 : case CPTK_IS_POINTER:
14126 151437 : return TYPE_PTR_P (type1);
14127 :
14128 277 : case CPTK_IS_POLYMORPHIC:
14129 277 : return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
14130 :
14131 825245 : case CPTK_IS_REFERENCE:
14132 825245 : return type_code1 == REFERENCE_TYPE;
14133 :
14134 4220581 : case CPTK_IS_SAME:
14135 4220581 : return same_type_p (type1, type2);
14136 :
14137 373 : case CPTK_IS_SCOPED_ENUM:
14138 373 : return SCOPED_ENUM_P (type1);
14139 :
14140 58014 : case CPTK_IS_STD_LAYOUT:
14141 58014 : return std_layout_type_p (type1);
14142 :
14143 54798 : case CPTK_IS_TRIVIAL:
14144 54798 : return trivial_type_p (type1);
14145 :
14146 9882 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14147 9882 : return is_trivially_xible (MODIFY_EXPR, type1, type2);
14148 :
14149 67085 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14150 67085 : return is_trivially_xible (INIT_EXPR, type1, type2);
14151 :
14152 108838 : case CPTK_IS_TRIVIALLY_COPYABLE:
14153 108838 : return trivially_copyable_p (type1);
14154 :
14155 24305 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14156 24305 : return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14157 :
14158 91193 : case CPTK_IS_UNBOUNDED_ARRAY:
14159 91193 : return array_of_unknown_bound_p (type1);
14160 :
14161 267015 : case CPTK_IS_UNION:
14162 267015 : return type_code1 == UNION_TYPE;
14163 :
14164 712 : case CPTK_IS_VIRTUAL_BASE_OF:
14165 646 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14166 1342 : && lookup_base (type2, type1, ba_require_virtual,
14167 : NULL, tf_none) != NULL_TREE);
14168 :
14169 728403 : case CPTK_IS_VOLATILE:
14170 728403 : return CP_TYPE_VOLATILE_P (type1);
14171 :
14172 225517 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14173 225517 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
14174 :
14175 51575 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14176 51575 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/false);
14177 :
14178 79 : case CPTK_IS_DEDUCIBLE:
14179 79 : return type_targs_deducible_from (type1, type2);
14180 :
14181 28 : case CPTK_IS_CONSTEVAL_ONLY:
14182 28 : return consteval_only_p (type1);
14183 :
14184 : /* __array_rank, __builtin_type_order and __builtin_structured_binding_size
14185 : are handled in finish_trait_expr. */
14186 0 : case CPTK_RANK:
14187 0 : case CPTK_TYPE_ORDER:
14188 0 : case CPTK_STRUCTURED_BINDING_SIZE:
14189 0 : gcc_unreachable ();
14190 :
14191 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14192 : case CPTK_##CODE:
14193 : #include "cp-trait.def"
14194 : #undef DEFTRAIT_TYPE
14195 : /* Type-yielding traits are handled in finish_trait_type. */
14196 : break;
14197 : }
14198 :
14199 0 : gcc_unreachable ();
14200 : }
14201 :
14202 : /* Returns true if TYPE meets the requirements for the specified KIND,
14203 : false otherwise.
14204 :
14205 : When KIND == 1, TYPE must be an array of unknown bound,
14206 : or (possibly cv-qualified) void, or a complete type.
14207 :
14208 : When KIND == 2, TYPE must be a complete type, or array of complete type,
14209 : or (possibly cv-qualified) void.
14210 :
14211 : When KIND == 3:
14212 : If TYPE is a non-union class type, it must be complete.
14213 :
14214 : When KIND == 4:
14215 : If TYPE is a class type, it must be complete. */
14216 :
14217 : static bool
14218 21955506 : check_trait_type (tree type, int kind = 1)
14219 : {
14220 21955506 : if (type == NULL_TREE)
14221 : return true;
14222 :
14223 21955506 : if (TREE_CODE (type) == TREE_VEC)
14224 : {
14225 7255877 : for (tree arg : tree_vec_range (type))
14226 3088032 : if (!check_trait_type (arg, kind))
14227 21 : return false;
14228 4167845 : return true;
14229 : }
14230 :
14231 17787640 : if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
14232 : return true; // Array of unknown bound. Don't care about completeness.
14233 :
14234 17787096 : if (kind == 3 && !NON_UNION_CLASS_TYPE_P (type))
14235 : return true; // Not a non-union class type. Don't care about completeness.
14236 :
14237 17676591 : if (kind == 4 && TREE_CODE (type) == ARRAY_TYPE)
14238 : return true; // Not a class type. Don't care about completeness.
14239 :
14240 17676104 : if (VOID_TYPE_P (type))
14241 : return true;
14242 :
14243 17675004 : type = complete_type (strip_array_types (type));
14244 17675004 : if (!COMPLETE_TYPE_P (type)
14245 152 : && cxx_incomplete_type_diagnostic (NULL_TREE, type,
14246 : diagnostics::kind::permerror)
14247 17675156 : && !flag_permissive)
14248 : return false;
14249 : return true;
14250 : }
14251 :
14252 : /* True iff the conversion (if any) would be a direct reference
14253 : binding, not requiring complete types. This is LWG2939. */
14254 :
14255 : static bool
14256 8156112 : same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2)
14257 : {
14258 8156112 : tree from, to;
14259 8156112 : switch (kind)
14260 : {
14261 : /* These put the target type first. */
14262 : case CPTK_IS_CONSTRUCTIBLE:
14263 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14264 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14265 : case CPTK_IS_INVOCABLE:
14266 : case CPTK_IS_NOTHROW_INVOCABLE:
14267 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14268 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14269 : to = type1;
14270 : from = type2;
14271 : break;
14272 :
14273 : /* These put it second. */
14274 3707927 : case CPTK_IS_CONVERTIBLE:
14275 3707927 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14276 3707927 : to = type2;
14277 3707927 : from = type1;
14278 3707927 : break;
14279 :
14280 0 : default:
14281 0 : gcc_unreachable ();
14282 : }
14283 :
14284 8156112 : if (TREE_CODE (to) != REFERENCE_TYPE || !from)
14285 : return false;
14286 994144 : if (TREE_CODE (from) == TREE_VEC && TREE_VEC_LENGTH (from) == 1)
14287 57870 : from = TREE_VEC_ELT (from, 0);
14288 994144 : return (TYPE_P (from)
14289 1980533 : && (same_type_ignoring_top_level_qualifiers_p
14290 986389 : (non_reference (to), non_reference (from))));
14291 : }
14292 :
14293 : /* Helper for finish_trait_expr and tsubst_expr. Handle
14294 : CPTK_STRUCTURED_BINDING_SIZE in possibly SFINAE-friendly
14295 : way. */
14296 :
14297 : tree
14298 261 : finish_structured_binding_size (location_t loc, tree type,
14299 : tsubst_flags_t complain)
14300 : {
14301 261 : if (TYPE_REF_P (type))
14302 : {
14303 105 : if (complain & tf_error)
14304 99 : error_at (loc, "%qs argument %qT is a reference",
14305 : "__builtin_structured_binding_size", type);
14306 105 : return error_mark_node;
14307 : }
14308 156 : HOST_WIDE_INT ret = cp_decomp_size (loc, type, complain);
14309 156 : if (ret == -1)
14310 57 : return error_mark_node;
14311 99 : return maybe_wrap_with_location (build_int_cst (size_type_node, ret), loc);
14312 : }
14313 :
14314 : /* Process a trait expression. */
14315 :
14316 : tree
14317 25044418 : finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
14318 : {
14319 25044418 : if (type1 == error_mark_node
14320 25044415 : || type2 == error_mark_node)
14321 : return error_mark_node;
14322 :
14323 25044415 : if (processing_template_decl)
14324 : {
14325 3173583 : tree trait_expr = make_node (TRAIT_EXPR);
14326 3173583 : if (kind == CPTK_RANK || kind == CPTK_STRUCTURED_BINDING_SIZE)
14327 29397 : TREE_TYPE (trait_expr) = size_type_node;
14328 3144186 : else if (kind == CPTK_TYPE_ORDER)
14329 : {
14330 2794 : tree val = type_order_value (type1, type1);
14331 2794 : if (val != error_mark_node)
14332 2794 : TREE_TYPE (trait_expr) = TREE_TYPE (val);
14333 : }
14334 : else
14335 3141392 : TREE_TYPE (trait_expr) = boolean_type_node;
14336 3173583 : TRAIT_EXPR_TYPE1 (trait_expr) = type1;
14337 3173583 : TRAIT_EXPR_TYPE2 (trait_expr) = type2;
14338 3173583 : TRAIT_EXPR_KIND (trait_expr) = kind;
14339 3173583 : TRAIT_EXPR_LOCATION (trait_expr) = loc;
14340 3173583 : return trait_expr;
14341 : }
14342 :
14343 21870832 : switch (kind)
14344 : {
14345 51519 : case CPTK_HAS_NOTHROW_ASSIGN:
14346 51519 : case CPTK_HAS_TRIVIAL_ASSIGN:
14347 51519 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14348 51519 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14349 51519 : case CPTK_HAS_NOTHROW_COPY:
14350 51519 : case CPTK_HAS_TRIVIAL_COPY:
14351 51519 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14352 51519 : case CPTK_IS_DESTRUCTIBLE:
14353 51519 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14354 51519 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14355 51519 : if (!check_trait_type (type1))
14356 21 : return error_mark_node;
14357 : break;
14358 :
14359 290320 : case CPTK_IS_LITERAL_TYPE:
14360 290320 : case CPTK_IS_POD:
14361 290320 : case CPTK_IS_STD_LAYOUT:
14362 290320 : case CPTK_IS_TRIVIAL:
14363 290320 : case CPTK_IS_TRIVIALLY_COPYABLE:
14364 290320 : case CPTK_IS_CONSTEVAL_ONLY:
14365 290320 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14366 290320 : if (!check_trait_type (type1, /* kind = */ 2))
14367 33 : return error_mark_node;
14368 : break;
14369 :
14370 299995 : case CPTK_IS_ABSTRACT:
14371 299995 : case CPTK_IS_EMPTY:
14372 299995 : case CPTK_IS_POLYMORPHIC:
14373 299995 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14374 299995 : if (!check_trait_type (type1, /* kind = */ 3))
14375 15 : return error_mark_node;
14376 : break;
14377 :
14378 : /* N.B. std::is_aggregate is kind=2 but we don't need a complete element
14379 : type to know whether an array is an aggregate, so use kind=4 here. */
14380 449043 : case CPTK_IS_AGGREGATE:
14381 449043 : case CPTK_IS_FINAL:
14382 449043 : case CPTK_IS_IMPLICIT_LIFETIME:
14383 449043 : if (!check_trait_type (type1, /* kind = */ 4))
14384 17 : return error_mark_node;
14385 : break;
14386 :
14387 8156112 : case CPTK_IS_CONSTRUCTIBLE:
14388 8156112 : case CPTK_IS_CONVERTIBLE:
14389 8156112 : case CPTK_IS_INVOCABLE:
14390 8156112 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14391 8156112 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14392 8156112 : case CPTK_IS_NOTHROW_INVOCABLE:
14393 8156112 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14394 8156112 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14395 8156112 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14396 8156112 : /* Don't check completeness for direct reference binding. */;
14397 8156112 : if (same_type_ref_bind_p (kind, type1, type2))
14398 : break;
14399 8888318 : gcc_fallthrough ();
14400 :
14401 8888318 : case CPTK_IS_ASSIGNABLE:
14402 8888318 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14403 8888318 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14404 8888318 : if (!check_trait_type (type1)
14405 8888318 : || !check_trait_type (type2))
14406 63 : return error_mark_node;
14407 : break;
14408 :
14409 583155 : case CPTK_IS_BASE_OF:
14410 583155 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14411 583052 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14412 564611 : && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
14413 1113635 : && !complete_type_or_else (type2, NULL_TREE))
14414 : /* We already issued an error. */
14415 3 : return error_mark_node;
14416 : break;
14417 :
14418 715 : case CPTK_IS_VIRTUAL_BASE_OF:
14419 649 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14420 1348 : && !complete_type_or_else (type2, NULL_TREE))
14421 : /* We already issued an error. */
14422 3 : return error_mark_node;
14423 : break;
14424 :
14425 : case CPTK_IS_ARRAY:
14426 : case CPTK_IS_BOUNDED_ARRAY:
14427 : case CPTK_IS_CLASS:
14428 : case CPTK_IS_CONST:
14429 : case CPTK_IS_ENUM:
14430 : case CPTK_IS_FUNCTION:
14431 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14432 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14433 : case CPTK_IS_MEMBER_POINTER:
14434 : case CPTK_IS_OBJECT:
14435 : case CPTK_IS_POINTER:
14436 : case CPTK_IS_REFERENCE:
14437 : case CPTK_IS_SAME:
14438 : case CPTK_IS_SCOPED_ENUM:
14439 : case CPTK_IS_UNBOUNDED_ARRAY:
14440 : case CPTK_IS_UNION:
14441 : case CPTK_IS_VOLATILE:
14442 : break;
14443 :
14444 : case CPTK_RANK:
14445 : {
14446 : size_t rank = 0;
14447 122 : for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
14448 80 : ++rank;
14449 42 : return maybe_wrap_with_location (build_int_cst (size_type_node, rank),
14450 : loc);
14451 : }
14452 :
14453 122 : case CPTK_TYPE_ORDER:
14454 122 : return maybe_wrap_with_location (type_order_value (type1, type2), loc);
14455 :
14456 138 : case CPTK_STRUCTURED_BINDING_SIZE:
14457 138 : return finish_structured_binding_size (loc, type1, tf_warning_or_error);
14458 :
14459 204 : case CPTK_IS_LAYOUT_COMPATIBLE:
14460 204 : if (!array_of_unknown_bound_p (type1)
14461 189 : && TREE_CODE (type1) != VOID_TYPE
14462 387 : && !complete_type_or_else (type1, NULL_TREE))
14463 : /* We already issued an error. */
14464 6 : return error_mark_node;
14465 198 : if (!array_of_unknown_bound_p (type2)
14466 177 : && TREE_CODE (type2) != VOID_TYPE
14467 369 : && !complete_type_or_else (type2, NULL_TREE))
14468 : /* We already issued an error. */
14469 3 : return error_mark_node;
14470 : break;
14471 :
14472 79 : case CPTK_IS_DEDUCIBLE:
14473 79 : if (!DECL_TYPE_TEMPLATE_P (type1))
14474 : {
14475 0 : error ("%qD is not a class or alias template", type1);
14476 0 : return error_mark_node;
14477 : }
14478 : break;
14479 :
14480 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14481 : case CPTK_##CODE:
14482 : #include "cp-trait.def"
14483 : #undef DEFTRAIT_TYPE
14484 : /* Type-yielding traits are handled in finish_trait_type. */
14485 0 : gcc_unreachable ();
14486 : }
14487 :
14488 21870366 : tree val = (trait_expr_value (kind, type1, type2)
14489 21870366 : ? boolean_true_node : boolean_false_node);
14490 21870366 : return maybe_wrap_with_location (val, loc);
14491 : }
14492 :
14493 : /* Process a trait type. */
14494 :
14495 : tree
14496 9221446 : finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
14497 : tsubst_flags_t complain)
14498 : {
14499 9221446 : if (type1 == error_mark_node
14500 9221443 : || type2 == error_mark_node)
14501 : return error_mark_node;
14502 :
14503 9221443 : if (processing_template_decl)
14504 : {
14505 215466 : tree type = cxx_make_type (TRAIT_TYPE);
14506 215466 : TRAIT_TYPE_TYPE1 (type) = type1;
14507 215466 : TRAIT_TYPE_TYPE2 (type) = type2;
14508 215466 : TRAIT_TYPE_KIND_RAW (type) = build_int_cstu (integer_type_node, kind);
14509 : /* These traits are intended to be used in the definition of the ::type
14510 : member of the corresponding standard library type trait and aren't
14511 : mangleable (and thus won't appear directly in template signatures),
14512 : so structural equality should suffice. */
14513 215466 : SET_TYPE_STRUCTURAL_EQUALITY (type);
14514 215466 : return type;
14515 : }
14516 :
14517 9005977 : switch (kind)
14518 : {
14519 1409155 : case CPTK_ADD_LVALUE_REFERENCE:
14520 : /* [meta.trans.ref]. */
14521 1409155 : if (referenceable_type_p (type1))
14522 1409080 : return cp_build_reference_type (type1, /*rval=*/false);
14523 : return type1;
14524 :
14525 730969 : case CPTK_ADD_POINTER:
14526 : /* [meta.trans.ptr]. */
14527 730969 : if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
14528 : {
14529 730937 : if (TYPE_REF_P (type1))
14530 729881 : type1 = TREE_TYPE (type1);
14531 730937 : return build_pointer_type (type1);
14532 : }
14533 : return type1;
14534 :
14535 1910523 : case CPTK_ADD_RVALUE_REFERENCE:
14536 : /* [meta.trans.ref]. */
14537 1910523 : if (referenceable_type_p (type1))
14538 1910470 : return cp_build_reference_type (type1, /*rval=*/true);
14539 : return type1;
14540 :
14541 270099 : case CPTK_DECAY:
14542 270099 : if (TYPE_REF_P (type1))
14543 40690 : type1 = TREE_TYPE (type1);
14544 :
14545 270099 : if (TREE_CODE (type1) == ARRAY_TYPE)
14546 667 : return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
14547 667 : complain);
14548 269432 : else if (TREE_CODE (type1) == FUNCTION_TYPE)
14549 176 : return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
14550 : else
14551 269256 : return cv_unqualified (type1);
14552 :
14553 219 : case CPTK_REMOVE_ALL_EXTENTS:
14554 219 : return strip_array_types (type1);
14555 :
14556 1113798 : case CPTK_REMOVE_CV:
14557 1113798 : return cv_unqualified (type1);
14558 :
14559 659493 : case CPTK_REMOVE_CVREF:
14560 659493 : if (TYPE_REF_P (type1))
14561 331371 : type1 = TREE_TYPE (type1);
14562 659493 : return cv_unqualified (type1);
14563 :
14564 63956 : case CPTK_REMOVE_EXTENT:
14565 63956 : if (TREE_CODE (type1) == ARRAY_TYPE)
14566 9095 : type1 = TREE_TYPE (type1);
14567 : return type1;
14568 :
14569 49818 : case CPTK_REMOVE_POINTER:
14570 49818 : if (TYPE_PTR_P (type1))
14571 47116 : type1 = TREE_TYPE (type1);
14572 : return type1;
14573 :
14574 2645893 : case CPTK_REMOVE_REFERENCE:
14575 2645893 : if (TYPE_REF_P (type1))
14576 1632432 : type1 = TREE_TYPE (type1);
14577 : return type1;
14578 :
14579 105760 : case CPTK_TYPE_PACK_ELEMENT:
14580 105760 : return finish_type_pack_element (type1, type2, complain);
14581 :
14582 46294 : case CPTK_UNDERLYING_TYPE:
14583 46294 : return finish_underlying_type (type1);
14584 :
14585 : #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
14586 : case CPTK_##CODE:
14587 : #include "cp-trait.def"
14588 : #undef DEFTRAIT_EXPR
14589 : /* Expression-yielding traits are handled in finish_trait_expr. */
14590 : case CPTK_BASES:
14591 : case CPTK_DIRECT_BASES:
14592 : /* BASES and DIRECT_BASES are handled in finish_bases. */
14593 : break;
14594 : }
14595 :
14596 0 : gcc_unreachable ();
14597 : }
14598 :
14599 : /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
14600 : which is ignored for C++. */
14601 :
14602 : void
14603 0 : set_float_const_decimal64 (void)
14604 : {
14605 0 : }
14606 :
14607 : void
14608 0 : clear_float_const_decimal64 (void)
14609 : {
14610 0 : }
14611 :
14612 : bool
14613 1874138 : float_const_decimal64_p (void)
14614 : {
14615 1874138 : return 0;
14616 : }
14617 :
14618 :
14619 : /* Return true if T designates the implied `this' parameter. */
14620 :
14621 : bool
14622 6324719 : is_this_parameter (tree t)
14623 : {
14624 6324719 : if (!DECL_P (t) || DECL_NAME (t) != this_identifier)
14625 : return false;
14626 3579197 : gcc_assert (TREE_CODE (t) == PARM_DECL
14627 : || (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
14628 : || (cp_binding_oracle && VAR_P (t)));
14629 : return true;
14630 : }
14631 :
14632 : /* As above, or a C++23 explicit object parameter. */
14633 :
14634 : bool
14635 456 : is_object_parameter (tree t)
14636 : {
14637 456 : if (is_this_parameter (t))
14638 : return true;
14639 91 : if (TREE_CODE (t) != PARM_DECL)
14640 : return false;
14641 34 : tree ctx = DECL_CONTEXT (t);
14642 34 : return (ctx && DECL_XOBJ_MEMBER_FUNCTION_P (ctx)
14643 62 : && t == DECL_ARGUMENTS (ctx));
14644 : }
14645 :
14646 : /* Insert the deduced return type for an auto function. */
14647 :
14648 : void
14649 2234865 : apply_deduced_return_type (tree fco, tree return_type)
14650 : {
14651 2234865 : tree result;
14652 :
14653 2234865 : if (return_type == error_mark_node)
14654 : return;
14655 :
14656 2234862 : if (DECL_CONV_FN_P (fco))
14657 42 : DECL_NAME (fco) = make_conv_op_name (return_type);
14658 :
14659 2234862 : TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
14660 :
14661 2234862 : maybe_update_postconditions (fco);
14662 :
14663 : /* Apply the type to the result object. */
14664 :
14665 2234862 : result = DECL_RESULT (fco);
14666 2234862 : if (result == NULL_TREE)
14667 : return;
14668 2225401 : if (TREE_TYPE (result) == return_type)
14669 : return;
14670 :
14671 2225395 : if (!processing_template_decl && !VOID_TYPE_P (return_type)
14672 3726272 : && !complete_type_or_else (return_type, NULL_TREE))
14673 : return;
14674 :
14675 : /* We already have a DECL_RESULT from start_preparsed_function.
14676 : Now we need to redo the work it and allocate_struct_function
14677 : did to reflect the new type. */
14678 2225398 : result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
14679 2225398 : TYPE_MAIN_VARIANT (return_type));
14680 2225398 : DECL_ARTIFICIAL (result) = 1;
14681 2225398 : DECL_IGNORED_P (result) = 1;
14682 2225398 : cp_apply_type_quals_to_decl (cp_type_quals (return_type),
14683 : result);
14684 2225398 : DECL_RESULT (fco) = result;
14685 :
14686 2225398 : if (!uses_template_parms (fco))
14687 2225398 : if (function *fun = DECL_STRUCT_FUNCTION (fco))
14688 : {
14689 2224934 : bool aggr = aggregate_value_p (result, fco);
14690 : #ifdef PCC_STATIC_STRUCT_RETURN
14691 : fun->returns_pcc_struct = aggr;
14692 : #endif
14693 2224934 : fun->returns_struct = aggr;
14694 : }
14695 : }
14696 :
14697 : /* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true,
14698 : this is a right unary fold. Otherwise it is a left unary fold. */
14699 :
14700 : static tree
14701 739829 : finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir)
14702 : {
14703 : /* Build a pack expansion (assuming expr has pack type). */
14704 739829 : if (!uses_parameter_packs (expr))
14705 : {
14706 3 : error_at (location_of (expr), "operand of fold expression has no "
14707 : "unexpanded parameter packs");
14708 3 : return error_mark_node;
14709 : }
14710 739826 : tree pack = make_pack_expansion (expr);
14711 :
14712 : /* Build the fold expression. */
14713 739826 : tree code = build_int_cstu (integer_type_node, abs (op));
14714 739826 : tree fold = build_min_nt_loc (loc, dir, code, pack);
14715 739826 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14716 739826 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14717 739826 : FOLD_EXPR_OP (fold),
14718 739826 : FOLD_EXPR_MODIFY_P (fold));
14719 739826 : return fold;
14720 : }
14721 :
14722 : tree
14723 19011 : finish_left_unary_fold_expr (location_t loc, tree expr, int op)
14724 : {
14725 19011 : return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR);
14726 : }
14727 :
14728 : tree
14729 720818 : finish_right_unary_fold_expr (location_t loc, tree expr, int op)
14730 : {
14731 720818 : return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR);
14732 : }
14733 :
14734 : /* Build a binary fold expression over EXPR1 and EXPR2. The
14735 : associativity of the fold is determined by EXPR1 and EXPR2 (whichever
14736 : has an unexpanded parameter pack). */
14737 :
14738 : static tree
14739 9745 : finish_binary_fold_expr (location_t loc, tree pack, tree init,
14740 : int op, tree_code dir)
14741 : {
14742 9745 : pack = make_pack_expansion (pack);
14743 9745 : tree code = build_int_cstu (integer_type_node, abs (op));
14744 9745 : tree fold = build_min_nt_loc (loc, dir, code, pack, init);
14745 9745 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14746 9745 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14747 9745 : FOLD_EXPR_OP (fold),
14748 9745 : FOLD_EXPR_MODIFY_P (fold));
14749 9745 : return fold;
14750 : }
14751 :
14752 : tree
14753 9745 : finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op)
14754 : {
14755 : // Determine which expr has an unexpanded parameter pack and
14756 : // set the pack and initial term.
14757 9745 : bool pack1 = uses_parameter_packs (expr1);
14758 9745 : bool pack2 = uses_parameter_packs (expr2);
14759 9745 : if (pack1 && !pack2)
14760 755 : return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
14761 8990 : else if (pack2 && !pack1)
14762 8990 : return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
14763 : else
14764 : {
14765 0 : if (pack1)
14766 0 : error ("both arguments in binary fold have unexpanded parameter packs");
14767 : else
14768 0 : error ("no unexpanded parameter packs in binary fold");
14769 : }
14770 0 : return error_mark_node;
14771 : }
14772 :
14773 : /* Finish __builtin_launder (arg). */
14774 :
14775 : tree
14776 12940 : finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain)
14777 : {
14778 12940 : tree orig_arg = arg;
14779 12940 : if (!type_dependent_expression_p (arg))
14780 84 : arg = decay_conversion (arg, complain);
14781 12940 : if (error_operand_p (arg))
14782 0 : return error_mark_node;
14783 12940 : if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
14784 : {
14785 24 : error_at (loc, "type %qT of argument to %<__builtin_launder%> "
14786 24 : "is not a pointer to object type", TREE_TYPE (arg));
14787 24 : return error_mark_node;
14788 : }
14789 12916 : if (processing_template_decl)
14790 12856 : arg = orig_arg;
14791 12916 : return build_call_expr_internal_loc (loc, IFN_LAUNDER,
14792 25832 : TREE_TYPE (arg), 1, arg);
14793 : }
14794 :
14795 : /* Finish __builtin_convertvector (arg, type). */
14796 :
14797 : tree
14798 188 : cp_build_vec_convert (tree arg, location_t loc, tree type,
14799 : tsubst_flags_t complain)
14800 : {
14801 188 : if (error_operand_p (type))
14802 9 : return error_mark_node;
14803 179 : if (error_operand_p (arg))
14804 0 : return error_mark_node;
14805 :
14806 179 : tree ret = NULL_TREE;
14807 179 : if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
14808 197 : ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg),
14809 : decay_conversion (arg, complain),
14810 : loc, type, (complain & tf_error) != 0);
14811 :
14812 179 : if (!processing_template_decl)
14813 : return ret;
14814 :
14815 24 : return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg);
14816 : }
14817 :
14818 : /* Finish __builtin_bit_cast (type, arg). */
14819 :
14820 : tree
14821 272970 : cp_build_bit_cast (location_t loc, tree type, tree arg,
14822 : tsubst_flags_t complain)
14823 : {
14824 272970 : if (error_operand_p (type))
14825 0 : return error_mark_node;
14826 272970 : if (!dependent_type_p (type))
14827 : {
14828 198669 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
14829 9 : return error_mark_node;
14830 198660 : if (TREE_CODE (type) == ARRAY_TYPE)
14831 : {
14832 : /* std::bit_cast for destination ARRAY_TYPE is not possible,
14833 : as functions may not return an array, so don't bother trying
14834 : to support this (and then deal with VLAs etc.). */
14835 9 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14836 : "is an array type", type);
14837 9 : return error_mark_node;
14838 : }
14839 198651 : if (!trivially_copyable_p (type))
14840 : {
14841 18 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14842 : "is not trivially copyable", type);
14843 18 : return error_mark_node;
14844 : }
14845 198633 : if (consteval_only_p (type) || consteval_only_p (arg))
14846 : {
14847 4 : error_at (loc, "%<__builtin_bit_cast%> cannot be used with "
14848 : "consteval-only types");
14849 4 : return error_mark_node;
14850 : }
14851 : }
14852 :
14853 272930 : if (error_operand_p (arg))
14854 0 : return error_mark_node;
14855 :
14856 272930 : if (!type_dependent_expression_p (arg))
14857 : {
14858 109123 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
14859 : {
14860 : /* Don't perform array-to-pointer conversion. */
14861 25 : arg = mark_rvalue_use (arg, loc, true);
14862 25 : if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
14863 0 : return error_mark_node;
14864 : }
14865 : else
14866 109098 : arg = decay_conversion (arg, complain);
14867 :
14868 109123 : if (error_operand_p (arg))
14869 12 : return error_mark_node;
14870 :
14871 109111 : if (!trivially_copyable_p (TREE_TYPE (arg)))
14872 : {
14873 9 : error_at (cp_expr_loc_or_loc (arg, loc),
14874 : "%<__builtin_bit_cast%> source type %qT "
14875 9 : "is not trivially copyable", TREE_TYPE (arg));
14876 9 : return error_mark_node;
14877 : }
14878 109102 : if (!dependent_type_p (type)
14879 181620 : && !cp_tree_equal (TYPE_SIZE_UNIT (type),
14880 72518 : TYPE_SIZE_UNIT (TREE_TYPE (arg))))
14881 : {
14882 18 : error_at (loc, "%<__builtin_bit_cast%> source size %qE "
14883 : "not equal to destination type size %qE",
14884 18 : TYPE_SIZE_UNIT (TREE_TYPE (arg)),
14885 18 : TYPE_SIZE_UNIT (type));
14886 18 : return error_mark_node;
14887 : }
14888 : }
14889 :
14890 272891 : tree ret = build_min (BIT_CAST_EXPR, type, arg);
14891 272891 : SET_EXPR_LOCATION (ret, loc);
14892 :
14893 272891 : if (!processing_template_decl && CLASS_TYPE_P (type))
14894 226 : ret = get_target_expr (ret, complain);
14895 :
14896 : return ret;
14897 : }
14898 :
14899 : /* Diagnose invalid #pragma GCC unroll argument and adjust
14900 : it if needed. */
14901 :
14902 : tree
14903 22856 : cp_check_pragma_unroll (location_t loc, tree unroll)
14904 : {
14905 22856 : HOST_WIDE_INT lunroll = 0;
14906 22856 : if (type_dependent_expression_p (unroll))
14907 : ;
14908 45640 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll))
14909 45594 : || (!value_dependent_expression_p (unroll)
14910 22744 : && (!tree_fits_shwi_p (unroll)
14911 22718 : || (lunroll = tree_to_shwi (unroll)) < 0
14912 22703 : || lunroll >= USHRT_MAX)))
14913 : {
14914 90 : error_at (loc, "%<#pragma GCC unroll%> requires an"
14915 : " assignment-expression that evaluates to a non-negative"
14916 : " integral constant less than %u", USHRT_MAX);
14917 90 : unroll = integer_one_node;
14918 : }
14919 22730 : else if (TREE_CODE (unroll) == INTEGER_CST)
14920 : {
14921 22700 : unroll = fold_convert (integer_type_node, unroll);
14922 22700 : if (integer_zerop (unroll))
14923 12 : unroll = integer_one_node;
14924 : }
14925 22856 : return unroll;
14926 : }
14927 :
14928 : #include "gt-cp-semantics.h"
|