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 22867643066 : push_deferring_access_checks (deferring_kind deferring)
146 : {
147 : /* For context like template instantiation, access checking
148 : disabling applies to all nested context. */
149 22867643066 : if (deferred_access_no_check || deferring == dk_no_check)
150 290125103 : deferred_access_no_check++;
151 : else
152 : {
153 22577517963 : deferred_access e = {NULL, deferring};
154 22577517963 : vec_safe_push (deferred_access_stack, e);
155 : }
156 22867643066 : }
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 417910403 : reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
163 : {
164 417910403 : push_deferring_access_checks (dk_deferred);
165 417910403 : if (!deferred_access_no_check)
166 411322619 : deferred_access_stack->last().deferred_access_checks = checks;
167 417910403 : }
168 :
169 : /* Resume deferring access checks again after we stopped doing
170 : this previously. */
171 :
172 : void
173 173633978 : resume_deferring_access_checks (void)
174 : {
175 173633978 : if (!deferred_access_no_check)
176 173613703 : deferred_access_stack->last().deferring_access_checks_kind = dk_deferred;
177 173633978 : }
178 :
179 : /* Stop deferring access checks. */
180 :
181 : void
182 487257399 : stop_deferring_access_checks (void)
183 : {
184 487257399 : if (!deferred_access_no_check)
185 487197241 : deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred;
186 487257399 : }
187 :
188 : /* Discard the current deferred access checks and restore the
189 : previous states. */
190 :
191 : void
192 14239597946 : pop_deferring_access_checks (void)
193 : {
194 14239597946 : if (deferred_access_no_check)
195 222383359 : deferred_access_no_check--;
196 : else
197 14017214587 : deferred_access_stack->pop ();
198 14239597946 : }
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 1284309129 : get_deferred_access_checks (void)
207 : {
208 1284309129 : if (deferred_access_no_check)
209 : return NULL;
210 : else
211 1271249729 : 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 8627910391 : pop_to_parent_deferring_access_checks (void)
220 : {
221 8627910391 : if (deferred_access_no_check)
222 67741738 : deferred_access_no_check--;
223 : else
224 : {
225 8560168653 : vec<deferred_access_check, va_gc> *checks;
226 8560168653 : deferred_access *ptr;
227 :
228 8560168653 : checks = (deferred_access_stack->last ().deferred_access_checks);
229 :
230 8560168653 : deferred_access_stack->pop ();
231 8560168653 : ptr = &deferred_access_stack->last ();
232 8560168653 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
233 : {
234 : /* Check access. */
235 545797754 : 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 8207826095 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
244 : {
245 105310585 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe)
246 : {
247 9507339 : if (probe->binfo == chk->binfo &&
248 7552372 : probe->decl == chk->decl &&
249 925116 : probe->diag_decl == chk->diag_decl)
250 924352 : goto found;
251 : }
252 : /* Insert into parent's checks. */
253 95803246 : vec_safe_push (ptr->deferred_access_checks, *chk);
254 96727598 : found:;
255 : }
256 : }
257 : }
258 8627910391 : }
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 510977156 : enforce_access (tree basetype_path, tree decl, tree diag_decl,
334 : tsubst_flags_t complain, access_failure_info *afi = NULL)
335 : {
336 510977156 : gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
337 :
338 510977156 : if (flag_new_inheriting_ctors
339 654229408 : && 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 75507 : decl = strip_inheriting_ctors (decl);
345 75507 : basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl),
346 : ba_any, NULL, complain);
347 : }
348 :
349 510977156 : tree cs = current_scope ();
350 510977156 : if (in_template_context
351 510977156 : && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
352 40114568 : 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 39882105 : 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 471095051 : if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true))
382 : {
383 21359 : if (flag_new_inheriting_ctors)
384 21329 : diag_decl = strip_inheriting_ctors (diag_decl);
385 21359 : 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 21359 : if (afi)
416 412 : afi->record_access_failure (basetype_path, decl, diag_decl);
417 21359 : 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 1100211618 : perform_access_checks (vec<deferred_access_check, va_gc> *checks,
431 : tsubst_flags_t complain)
432 : {
433 1100211618 : int i;
434 1100211618 : deferred_access_check *chk;
435 1100211618 : location_t loc = input_location;
436 1100211618 : bool ok = true;
437 :
438 1100211618 : if (!checks)
439 : return true;
440 :
441 130453116 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
442 : {
443 72669075 : input_location = chk->loc;
444 72669075 : ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain);
445 : }
446 :
447 57784041 : input_location = loc;
448 57784041 : 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 288456407 : perform_deferred_access_checks (tsubst_flags_t complain)
469 : {
470 288456407 : 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 726401848 : perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
480 : tsubst_flags_t complain,
481 : access_failure_info *afi)
482 : {
483 726401848 : int i;
484 726401848 : deferred_access *ptr;
485 726401848 : deferred_access_check *chk;
486 :
487 : /* Exit if we are in a context that no access checking is performed. */
488 726401848 : if (deferred_access_no_check)
489 : return true;
490 :
491 702876434 : gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
492 :
493 702876434 : ptr = &deferred_access_stack->last ();
494 :
495 : /* If we are not supposed to defer access checks, just check now. */
496 702876434 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
497 : {
498 438308081 : bool ok = enforce_access (binfo, decl, diag_decl, complain, afi);
499 650648611 : return (complain & tf_error) ? true : ok;
500 : }
501 :
502 : /* See if we are already going to perform this check. */
503 320312387 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk)
504 : {
505 73984633 : if (chk->decl == decl && chk->binfo == binfo &&
506 18241330 : chk->diag_decl == diag_decl)
507 : {
508 : return true;
509 : }
510 : }
511 : /* If not, record the check. */
512 246327754 : deferred_access_check new_access = {binfo, decl, diag_decl, input_location};
513 246327754 : vec_safe_push (ptr->deferred_access_checks, new_access);
514 :
515 246327754 : 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 1597189505 : stmts_are_full_exprs_p (void)
524 : {
525 1597189505 : 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 1323697313 : add_stmt (tree t)
534 : {
535 1323697313 : enum tree_code code = TREE_CODE (t);
536 :
537 1323697313 : if (EXPR_P (t) && code != LABEL_EXPR)
538 : {
539 1272644762 : if (!EXPR_HAS_LOCATION (t))
540 192194187 : 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 1272644762 : if (STATEMENT_CODE_P (TREE_CODE (t)))
545 340218085 : STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
546 : }
547 :
548 1323697313 : if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
549 8562304 : 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 1323697313 : gcc_checking_assert (!stmt_list_stack->is_empty ());
554 1323697313 : append_to_statement_list_force (t, &cur_stmt_list);
555 :
556 1323697313 : return t;
557 : }
558 :
559 : /* Returns the stmt_tree to which statements are currently being added. */
560 :
561 : stmt_tree
562 7985095534 : current_stmt_tree (void)
563 : {
564 7985095534 : return (cfun
565 7944347162 : ? &cfun->language->base.x_stmt_tree
566 7985095534 : : &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 658292 : maybe_cleanup_point_expr (tree expr)
573 : {
574 658292 : if (!processing_template_decl && stmts_are_full_exprs_p ())
575 644341 : expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
576 658292 : 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 336046159 : maybe_cleanup_point_expr_void (tree expr)
586 : {
587 336046159 : if (!processing_template_decl && stmts_are_full_exprs_p ())
588 130455324 : expr = fold_build_cleanup_point_expr (void_type_node, expr);
589 336046159 : return expr;
590 : }
591 :
592 :
593 :
594 : /* Create a declaration statement for the declaration given by the DECL. */
595 :
596 : void
597 110790946 : add_decl_expr (tree decl)
598 : {
599 110790946 : tree r = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
600 110790946 : if (DECL_INITIAL (decl)
601 110790946 : || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
602 20270945 : r = maybe_cleanup_point_expr_void (r);
603 110790946 : add_stmt (r);
604 110790946 : }
605 :
606 : /* Set EXPR_LOCATION on one cleanup T to LOC. */
607 :
608 : static void
609 6075683 : set_one_cleanup_loc (tree t, location_t loc)
610 : {
611 6075683 : if (!t)
612 : return;
613 :
614 6075683 : if (TREE_CODE (t) != POSTCONDITION_STMT)
615 6075683 : 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 6075683 : if (TREE_CODE (t) == NOP_EXPR
622 0 : && TREE_TYPE (t) == void_type_node
623 6075683 : && 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 1237883300 : set_cleanup_locs (tree stmts, location_t loc)
631 : {
632 1243958983 : if (TREE_CODE (stmts) == CLEANUP_STMT)
633 : {
634 6075683 : set_one_cleanup_loc (CLEANUP_EXPR (stmts), loc);
635 6075683 : set_cleanup_locs (CLEANUP_BODY (stmts), loc);
636 : }
637 1237883300 : else if (TREE_CODE (stmts) == STATEMENT_LIST)
638 1086246677 : for (tree stmt : tsi_range (stmts))
639 843812735 : set_cleanup_locs (stmt, loc);
640 1237883300 : }
641 :
642 : /* True iff the innermost block scope is a try block. */
643 :
644 : static bool
645 394070565 : at_try_scope ()
646 : {
647 394070565 : cp_binding_level *b = current_binding_level;
648 394070877 : while (b && b->kind == sk_cleanup)
649 312 : b = b->level_chain;
650 394070565 : return b && b->kind == sk_try;
651 : }
652 :
653 : /* Finish a scope. */
654 :
655 : tree
656 394070565 : do_poplevel (tree stmt_list)
657 : {
658 394070565 : tree block = NULL;
659 :
660 394070565 : bool was_try = at_try_scope ();
661 :
662 394070565 : if (stmts_are_full_exprs_p ())
663 394010152 : block = poplevel (kept_level_p (), 1, 0);
664 :
665 : /* This needs to come after poplevel merges sk_cleanup statement_lists. */
666 394070565 : maybe_splice_retval_cleanup (stmt_list, was_try);
667 :
668 394070565 : stmt_list = pop_stmt_list (stmt_list);
669 :
670 : /* input_location is the last token of the scope, usually a }. */
671 394070565 : set_cleanup_locs (stmt_list, input_location);
672 :
673 394070565 : if (!processing_template_decl)
674 : {
675 144293305 : stmt_list = c_build_bind_expr (input_location, block, stmt_list);
676 : /* ??? See c_end_compound_stmt re statement expressions. */
677 : }
678 :
679 394070565 : return stmt_list;
680 : }
681 :
682 : /* Begin a new scope. */
683 :
684 : tree
685 394034591 : do_pushlevel (scope_kind sk)
686 : {
687 394034591 : tree ret = push_stmt_list ();
688 394034591 : if (stmts_are_full_exprs_p ())
689 394010212 : begin_scope (sk, NULL);
690 394034591 : 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 6075558 : push_cleanup (tree decl, tree cleanup, bool eh_only)
700 : {
701 6075558 : tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
702 6075558 : CLEANUP_EH_ONLY (stmt) = eh_only;
703 6075558 : add_stmt (stmt);
704 6075558 : CLEANUP_BODY (stmt) = push_stmt_list ();
705 6075558 : }
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 18049528 : begin_maybe_infinite_loop (tree cond)
716 : {
717 : /* Only track this while parsing a function, not during instantiation. */
718 18049528 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
719 3261851 : && !processing_template_decl))
720 : return;
721 14787131 : bool maybe_infinite = true;
722 14787131 : if (cond)
723 : {
724 14486606 : cond = fold_non_dependent_expr (cond);
725 14486606 : maybe_infinite = integer_nonzerop (cond);
726 : }
727 29273737 : vec_safe_push (cp_function_chain->infinite_loops,
728 14787131 : 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 1462021 : break_maybe_infinite_loop (void)
736 : {
737 1462021 : if (!cfun)
738 : return;
739 1462021 : 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 18049528 : end_maybe_infinite_loop (tree cond)
747 : {
748 18049528 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
749 3261851 : && !processing_template_decl))
750 : return;
751 14787131 : tree current = cp_function_chain->infinite_loops->pop();
752 14787131 : if (current != NULL_TREE)
753 : {
754 4737701 : cond = fold_non_dependent_expr (cond);
755 4737701 : if (integer_nonzerop (cond))
756 297195 : 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 95225829 : begin_cond (tree *cond_p)
767 : {
768 95225829 : if (processing_template_decl)
769 59005555 : *cond_p = push_stmt_list ();
770 95225829 : }
771 :
772 : /* Finish such a conditional. */
773 :
774 : static void
775 95225829 : finish_cond (tree *cond_p, tree expr)
776 : {
777 95225829 : if (processing_template_decl)
778 : {
779 59005555 : tree cond = pop_stmt_list (*cond_p);
780 :
781 59005555 : if (expr == NULL_TREE)
782 : /* Empty condition in 'for'. */
783 280600 : gcc_assert (empty_expr_stmt_p (cond));
784 58724955 : else if (check_for_bare_parameter_packs (expr))
785 0 : expr = error_mark_node;
786 58724955 : else if (!empty_expr_stmt_p (cond))
787 888524 : expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
788 : }
789 95225829 : *cond_p = expr;
790 95225829 : }
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 12285789 : adjust_loop_decl_cond (tree *body_p, tree *prep_p, tree *cleanup_p)
809 : {
810 12285789 : if (!TREE_SIDE_EFFECTS (*body_p))
811 12276449 : return;
812 :
813 9340 : gcc_assert (!processing_template_decl);
814 9340 : *prep_p = *body_p;
815 9340 : 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 9340 : current_binding_level->keep = true;
840 9340 : 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 9340 : if (tsi_end_p (iter))
847 91 : *body_p = NULL_TREE;
848 : else
849 9249 : *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 9340 : finish_loop_cond_prep (tree *body_p, tree *prep_p, tree cleanup)
862 : {
863 9340 : *prep_p = do_poplevel (*prep_p);
864 9340 : gcc_assert (TREE_CODE (*prep_p) == BIND_EXPR);
865 9340 : 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 9322 : tree stmt_list = BIND_EXPR_BODY (*prep_p);
872 9322 : gcc_assert (TREE_CODE (stmt_list) == STATEMENT_LIST);
873 9322 : 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 9231 : tree_stmt_iterator iter = tsi_start (stmt_list);
893 9427 : while (tsi_stmt (iter) != *body_p)
894 196 : tsi_next (&iter);
895 9231 : *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 841572 : is_assignment_op_expr_p (tree t)
937 : {
938 841572 : if (t == NULL_TREE)
939 : return false;
940 :
941 841572 : if (TREE_CODE (t) == MODIFY_EXPR
942 841572 : || (TREE_CODE (t) == MODOP_EXPR
943 330 : && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR))
944 : return true;
945 :
946 840885 : tree call = extract_call_expr (t);
947 840885 : if (call == NULL_TREE
948 126239 : || call == error_mark_node
949 967124 : || !CALL_EXPR_OPERATOR_SYNTAX (call))
950 : return false;
951 :
952 4377 : tree fndecl = cp_get_callee_fndecl_nofold (call);
953 4377 : return fndecl != NULL_TREE
954 4349 : && DECL_ASSIGNMENT_OPERATOR_P (fndecl)
955 4428 : && 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 77 : if (bool *r = hash_map_safe_get (boolish_class_type_p_cache, type))
971 26 : return *r;
972 :
973 19 : tree ops;
974 19 : bool has_bool_assignment = false;
975 19 : bool has_bool_conversion = false;
976 :
977 19 : ops = lookup_fnfields (type, assign_op_identifier, /*protect=*/0, tf_none);
978 58 : for (tree op : ovl_range (BASELINK_FUNCTIONS (ops)))
979 : {
980 31 : op = STRIP_TEMPLATE (op);
981 31 : if (TREE_CODE (op) != FUNCTION_DECL)
982 0 : continue;
983 31 : tree parm = DECL_CHAIN (DECL_ARGUMENTS (op));
984 31 : tree parm_type = non_reference (TREE_TYPE (parm));
985 31 : if (TREE_CODE (parm_type) == BOOLEAN_TYPE)
986 : {
987 : has_bool_assignment = true;
988 : break;
989 : }
990 : }
991 :
992 19 : if (has_bool_assignment)
993 : {
994 4 : ops = lookup_conversions (type);
995 4 : for (; ops; ops = TREE_CHAIN (ops))
996 : {
997 4 : tree op = TREE_VALUE (ops);
998 4 : if (!DECL_NONCONVERTING_P (op)
999 4 : && TREE_CODE (DECL_CONV_FN_TYPE (op)) == BOOLEAN_TYPE)
1000 : {
1001 : has_bool_conversion = true;
1002 : break;
1003 : }
1004 : }
1005 : }
1006 :
1007 19 : bool boolish = has_bool_assignment && has_bool_conversion;
1008 19 : hash_map_safe_put<true> (boolish_class_type_p_cache, type, boolish);
1009 19 : 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 104120144 : maybe_warn_unparenthesized_assignment (tree t, bool nested_p,
1019 : tsubst_flags_t complain)
1020 : {
1021 104120144 : tree type = TREE_TYPE (t);
1022 104120144 : t = STRIP_REFERENCE_REF (t);
1023 :
1024 104120144 : if ((complain & tf_warning)
1025 104061916 : && warn_parentheses
1026 841572 : && 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 104120497 : && (!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 104120144 : }
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 62394305 : annotate_saver::annotate_saver (tree *cond) : m_annotations (nullptr)
1072 : {
1073 62394305 : tree *t = cond;
1074 62404103 : while (TREE_CODE (*t) == ANNOTATE_EXPR)
1075 9798 : t = &TREE_OPERAND (*t, 0);
1076 :
1077 62394305 : if (t != cond)
1078 : {
1079 9795 : m_annotations = *cond;
1080 9795 : *cond = *t;
1081 9795 : m_inner = t;
1082 : }
1083 62394305 : }
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 62394305 : annotate_saver::restore (tree new_inner)
1092 : {
1093 62394305 : 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 9795 : 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 9795 : *m_inner = new_inner;
1118 9795 : 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 99753465 : maybe_convert_cond (tree cond)
1127 : {
1128 : /* Empty conditions remain empty. */
1129 99753465 : if (!cond)
1130 : return NULL_TREE;
1131 :
1132 : /* Wait until we instantiate templates before doing conversion. */
1133 99398295 : if (type_dependent_expression_p (cond))
1134 37003990 : return cond;
1135 :
1136 : /* Strip any ANNOTATE_EXPRs from COND. */
1137 62394305 : 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 543305 : if (DECL_DECOMPOSITION_P (cond)
1144 224 : && DECL_DECOMP_IS_BASE (cond)
1145 224 : && DECL_DECOMP_BASE (cond)
1146 62394526 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1147 56 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1148 :
1149 62394305 : if (warn_sequence_point && !processing_template_decl)
1150 317126 : verify_sequence_points (cond);
1151 :
1152 62394305 : maybe_warn_unparenthesized_assignment (cond, /*nested_p=*/false,
1153 : tf_warning_or_error);
1154 :
1155 : /* Do the conversion. */
1156 62394305 : cond = convert_from_reference (cond);
1157 62394305 : cond = condition_conversion (cond);
1158 :
1159 : /* Restore any ANNOTATE_EXPRs around COND. */
1160 62394305 : return annotations.restore (cond);
1161 : }
1162 :
1163 : /* Finish an expression-statement, whose EXPRESSION is as indicated. */
1164 :
1165 : tree
1166 178764412 : finish_expr_stmt (tree expr)
1167 : {
1168 178764412 : tree r = NULL_TREE;
1169 178764412 : location_t loc = EXPR_LOCATION (expr);
1170 :
1171 178277895 : if (expr != NULL_TREE)
1172 : {
1173 : /* If we ran into a problem, make sure we complained. */
1174 178764251 : gcc_assert (expr != error_mark_node || seen_error ());
1175 :
1176 178764251 : if (!processing_template_decl)
1177 : {
1178 78469353 : if (warn_sequence_point)
1179 791915 : verify_sequence_points (expr);
1180 78469353 : expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1181 : }
1182 100294898 : else if (!type_dependent_expression_p (expr))
1183 21791728 : convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1184 :
1185 178764248 : 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 178764248 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
1192 : {
1193 178764069 : if (TREE_CODE (expr) != EXPR_STMT
1194 175721799 : && !STATEMENT_CLASS_P (expr)
1195 175717648 : && TREE_CODE (expr) != STATEMENT_LIST)
1196 175285554 : expr = build_stmt (loc, EXPR_STMT, expr);
1197 178764069 : expr = maybe_cleanup_point_expr_void (expr);
1198 : }
1199 :
1200 178764248 : r = add_stmt (expr);
1201 : }
1202 :
1203 178764409 : return r;
1204 : }
1205 :
1206 :
1207 : /* Begin an if-statement. Returns a newly created IF_STMT if
1208 : appropriate. */
1209 :
1210 : tree
1211 81906811 : begin_if_stmt (void)
1212 : {
1213 81906811 : tree r, scope;
1214 81906811 : scope = do_pushlevel (sk_cond);
1215 81906811 : r = build_stmt (input_location, IF_STMT, NULL_TREE,
1216 : NULL_TREE, NULL_TREE, scope);
1217 81906811 : current_binding_level->this_entity = r;
1218 81906811 : begin_cond (&IF_COND (r));
1219 81906811 : 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 242201 : is_std_constant_evaluated_p (tree fn)
1227 : {
1228 : /* std::is_constant_evaluated takes no arguments. */
1229 242201 : if (call_expr_nargs (fn) != 0)
1230 : return false;
1231 :
1232 85370 : tree fndecl = cp_get_callee_fndecl_nofold (fn);
1233 85370 : if (fndecl == NULL_TREE)
1234 : return false;
1235 :
1236 26304 : if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
1237 : BUILT_IN_FRONTEND))
1238 : return true;
1239 :
1240 26281 : if (!decl_in_std_namespace_p (fndecl))
1241 : return false;
1242 :
1243 11328 : tree name = DECL_NAME (fndecl);
1244 11328 : 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 4482989 : find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
1252 : {
1253 4482989 : tree t = *tp;
1254 :
1255 4482989 : if (TYPE_P (t) || TREE_CONSTANT (t))
1256 : {
1257 791400 : *walk_subtrees = false;
1258 791400 : return NULL_TREE;
1259 : }
1260 :
1261 3691589 : switch (TREE_CODE (t))
1262 : {
1263 242201 : case CALL_EXPR:
1264 242201 : 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 81988546 : maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if,
1284 : bool trivial_infinite)
1285 : {
1286 81988546 : if (!warn_tautological_compare)
1287 : return;
1288 :
1289 : /* Suppress warning for std::is_constant_evaluated if the conditional
1290 : comes from a macro. */
1291 1368898 : if (from_macro_expansion_at (EXPR_LOCATION (cond)))
1292 : return;
1293 :
1294 574860 : cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r,
1295 : NULL);
1296 574860 : 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 81906811 : finish_if_stmt_cond (tree orig_cond, tree if_stmt)
1330 : {
1331 81906811 : tree cond = maybe_convert_cond (orig_cond);
1332 81906811 : maybe_warn_for_constant_evaluated (cond, IF_STMT_CONSTEXPR_P (if_stmt),
1333 : /*trivial_infinite=*/false);
1334 81906811 : if (IF_STMT_CONSTEXPR_P (if_stmt)
1335 19190110 : && !type_dependent_expression_p (cond)
1336 14424954 : && require_constant_expression (cond)
1337 14424925 : && !instantiation_dependent_expression_p (cond)
1338 : /* Wait until instantiation time, since only then COND has been
1339 : converted to bool. */
1340 91889476 : && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
1341 : {
1342 9982665 : cond = instantiate_non_dependent_expr (cond);
1343 9982665 : cond = cxx_constant_value (cond);
1344 : }
1345 71924146 : else if (processing_template_decl)
1346 48889992 : cond = orig_cond;
1347 81906811 : finish_cond (&IF_COND (if_stmt), cond);
1348 81906811 : add_stmt (if_stmt);
1349 81906811 : THEN_CLAUSE (if_stmt) = push_stmt_list ();
1350 81906811 : 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 81877137 : finish_then_clause (tree if_stmt)
1358 : {
1359 81877137 : THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
1360 81877137 : return if_stmt;
1361 : }
1362 :
1363 : /* Begin the else-clause of an if-statement. */
1364 :
1365 : void
1366 30345046 : begin_else_clause (tree if_stmt)
1367 : {
1368 30345046 : ELSE_CLAUSE (if_stmt) = push_stmt_list ();
1369 30345046 : }
1370 :
1371 : /* Finish the else-clause of an if-statement, which may be given by
1372 : IF_STMT. */
1373 :
1374 : void
1375 30345008 : finish_else_clause (tree if_stmt)
1376 : {
1377 30345008 : ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
1378 30345008 : }
1379 :
1380 : /* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as
1381 : read. */
1382 :
1383 : static tree
1384 921866208 : maybe_mark_exp_read_r (tree *tp, int *, void *)
1385 : {
1386 921866208 : tree t = *tp;
1387 921866208 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
1388 55811968 : mark_exp_read (t);
1389 921866208 : return NULL_TREE;
1390 : }
1391 :
1392 : /* Finish an if-statement. */
1393 :
1394 : void
1395 81877137 : finish_if_stmt (tree if_stmt)
1396 : {
1397 81877137 : tree scope = IF_SCOPE (if_stmt);
1398 81877137 : IF_SCOPE (if_stmt) = NULL;
1399 81877137 : 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 19160436 : cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt),
1405 : maybe_mark_exp_read_r, NULL);
1406 19160436 : cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt),
1407 : maybe_mark_exp_read_r, NULL);
1408 : }
1409 81877137 : add_stmt (do_poplevel (scope));
1410 81877137 : }
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 17488196 : finish_loop_cond (tree *condp, tree body)
1421 : {
1422 17488196 : if (TREE_CODE (*condp) == INTEGER_CST)
1423 : return;
1424 12677220 : bool trivially_empty = expr_first (body) == NULL_TREE;
1425 12677220 : bool trivial_infinite = false;
1426 12677220 : if (trivially_empty)
1427 : {
1428 94433 : tree c = fold_non_dependent_expr (*condp, tf_none,
1429 : /*manifestly_const_eval=*/true);
1430 94433 : trivial_infinite = c && integer_nonzerop (c);
1431 : }
1432 12677220 : if (warn_tautological_compare)
1433 : {
1434 81915 : tree cond = *condp;
1435 82270 : while (TREE_CODE (cond) == ANNOTATE_EXPR)
1436 355 : cond = TREE_OPERAND (cond, 0);
1437 81915 : if (trivial_infinite
1438 81979 : && !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1439 64 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1440 : /*trivial_infinite=*/true);
1441 81851 : else if (!trivially_empty
1442 347 : || !processing_template_decl
1443 82211 : || DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1444 81671 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1445 : /*trivial_infinite=*/false);
1446 : }
1447 12677220 : 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 4865963 : begin_while_stmt (void)
1459 : {
1460 4865963 : tree r;
1461 4865963 : r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1462 : NULL_TREE, NULL_TREE);
1463 4865963 : add_stmt (r);
1464 4865963 : WHILE_BODY (r) = do_pushlevel (sk_block);
1465 4865963 : begin_cond (&WHILE_COND (r));
1466 4865963 : return r;
1467 : }
1468 :
1469 : /* Process the COND of a while-statement, which may be given by
1470 : WHILE_STMT. */
1471 :
1472 : void
1473 4865963 : finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
1474 : tree unroll, bool novector)
1475 : {
1476 4865963 : cond = maybe_convert_cond (cond);
1477 4865963 : finish_cond (&WHILE_COND (while_stmt), cond);
1478 4865963 : begin_maybe_infinite_loop (cond);
1479 4865963 : 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 4865963 : if (unroll && cond != error_mark_node)
1487 25214 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1488 12607 : TREE_TYPE (WHILE_COND (while_stmt)),
1489 12607 : WHILE_COND (while_stmt),
1490 : build_int_cst (integer_type_node,
1491 : annot_expr_unroll_kind),
1492 : unroll);
1493 4865963 : 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 4865963 : adjust_loop_decl_cond (&WHILE_BODY (while_stmt),
1501 : &WHILE_COND_PREP (while_stmt),
1502 : &WHILE_COND_CLEANUP (while_stmt));
1503 4865963 : }
1504 :
1505 : /* Finish a while-statement, which may be given by WHILE_STMT. */
1506 :
1507 : void
1508 4865963 : finish_while_stmt (tree while_stmt)
1509 : {
1510 4865963 : end_maybe_infinite_loop (boolean_true_node);
1511 4865963 : if (WHILE_COND_PREP (while_stmt))
1512 9166 : finish_loop_cond_prep (&WHILE_BODY (while_stmt),
1513 : &WHILE_COND_PREP (while_stmt),
1514 9166 : WHILE_COND_CLEANUP (while_stmt));
1515 : else
1516 4856797 : WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
1517 4865963 : finish_loop_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
1518 4865963 : }
1519 :
1520 : /* Begin a do-statement. Returns a newly created DO_STMT if
1521 : appropriate. */
1522 :
1523 : tree
1524 5557577 : begin_do_stmt (void)
1525 : {
1526 5557577 : tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE,
1527 : NULL_TREE);
1528 5557577 : begin_maybe_infinite_loop (boolean_true_node);
1529 5557577 : add_stmt (r);
1530 5557577 : DO_BODY (r) = push_stmt_list ();
1531 5557577 : return r;
1532 : }
1533 :
1534 : /* Finish the body of a do-statement, which may be given by DO_STMT. */
1535 :
1536 : void
1537 5557577 : finish_do_body (tree do_stmt)
1538 : {
1539 5557577 : tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
1540 :
1541 5557577 : if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body))
1542 513384 : body = STATEMENT_LIST_TAIL (body)->stmt;
1543 :
1544 5557577 : if (IS_EMPTY_STMT (body))
1545 30 : warning (OPT_Wempty_body,
1546 : "suggest explicit braces around empty body in %<do%> statement");
1547 5557577 : }
1548 :
1549 : /* Finish a do-statement, which may be given by DO_STMT, and whose
1550 : COND is as indicated. */
1551 :
1552 : void
1553 5557577 : finish_do_stmt (tree cond, tree do_stmt, bool ivdep, tree unroll,
1554 : bool novector)
1555 : {
1556 5557577 : cond = maybe_convert_cond (cond);
1557 5557577 : 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 5557577 : if (check_for_bare_parameter_packs (cond))
1562 3 : cond = error_mark_node;
1563 5557577 : 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 5557577 : 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 5557577 : 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 5557577 : DO_COND (do_stmt) = cond;
1576 5557577 : tree do_body = DO_BODY (do_stmt);
1577 5557547 : if (CONVERT_EXPR_P (do_body)
1578 30 : && integer_zerop (TREE_OPERAND (do_body, 0))
1579 5557607 : && VOID_TYPE_P (TREE_TYPE (do_body)))
1580 : do_body = NULL_TREE;
1581 5557577 : finish_loop_cond (&DO_COND (do_stmt), do_body);
1582 5557577 : }
1583 :
1584 : /* Finish a return-statement. The EXPRESSION returned, if any, is as
1585 : indicated. */
1586 :
1587 : tree
1588 129949564 : finish_return_stmt (tree expr)
1589 : {
1590 129949564 : tree r;
1591 129949564 : bool no_warning;
1592 129949564 : bool dangling;
1593 :
1594 129949564 : expr = check_return_expr (expr, &no_warning, &dangling);
1595 :
1596 129949564 : if (error_operand_p (expr)
1597 129949564 : || (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 129948328 : if (!processing_template_decl)
1606 : {
1607 50401402 : if (warn_sequence_point)
1608 1006205 : verify_sequence_points (expr);
1609 : }
1610 :
1611 129948328 : r = build_stmt (input_location, RETURN_EXPR, expr);
1612 129948328 : RETURN_EXPR_LOCAL_ADDR_P (r) = dangling;
1613 129948328 : if (no_warning)
1614 33 : suppress_warning (r, OPT_Wreturn_type);
1615 129948328 : r = maybe_cleanup_point_expr_void (r);
1616 129948328 : r = add_stmt (r);
1617 :
1618 129948328 : 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 7625988 : begin_for_scope (tree *init)
1627 : {
1628 7625988 : tree scope = do_pushlevel (sk_for);
1629 :
1630 7625988 : if (processing_template_decl)
1631 5846645 : *init = push_stmt_list ();
1632 : else
1633 1779343 : *init = NULL_TREE;
1634 :
1635 7625988 : 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 7419826 : begin_for_stmt (tree scope, tree init)
1644 : {
1645 7419826 : tree r;
1646 :
1647 7419826 : 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 7419826 : if (scope == NULL_TREE)
1652 : {
1653 1540876 : gcc_assert (!init);
1654 1540876 : scope = begin_for_scope (&init);
1655 : }
1656 :
1657 7419826 : FOR_INIT_STMT (r) = init;
1658 7419826 : FOR_SCOPE (r) = scope;
1659 :
1660 7419826 : 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 7419826 : finish_init_stmt (tree for_stmt)
1668 : {
1669 7419826 : if (processing_template_decl)
1670 5640483 : FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
1671 7419826 : add_stmt (for_stmt);
1672 7419826 : FOR_BODY (for_stmt) = do_pushlevel (sk_block);
1673 7419826 : begin_cond (&FOR_COND (for_stmt));
1674 7419826 : }
1675 :
1676 : /* Finish the COND of a for-statement, which may be given by
1677 : FOR_STMT. */
1678 :
1679 : void
1680 7419826 : finish_for_cond (tree cond, tree for_stmt, bool ivdep, tree unroll,
1681 : bool novector)
1682 : {
1683 7419826 : cond = maybe_convert_cond (cond);
1684 7419826 : finish_cond (&FOR_COND (for_stmt), cond);
1685 7419826 : begin_maybe_infinite_loop (cond);
1686 7419826 : 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 7419826 : 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 7419826 : 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 7419826 : adjust_loop_decl_cond (&FOR_BODY (for_stmt), &FOR_COND_PREP (for_stmt),
1708 : &FOR_COND_CLEANUP (for_stmt));
1709 7419826 : }
1710 :
1711 : /* Finish the increment-EXPRESSION in a for-statement, which may be
1712 : given by FOR_STMT. */
1713 :
1714 : void
1715 7407689 : finish_for_expr (tree expr, tree for_stmt)
1716 : {
1717 7407689 : 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 6968821 : if (type_unknown_p (expr))
1722 : {
1723 6 : cxx_incomplete_type_error (expr, TREE_TYPE (expr));
1724 6 : expr = error_mark_node;
1725 : }
1726 6968821 : if (!processing_template_decl)
1727 : {
1728 1710627 : if (warn_sequence_point)
1729 14440 : verify_sequence_points (expr);
1730 1710627 : expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
1731 : tf_warning_or_error);
1732 : }
1733 5258194 : else if (!type_dependent_expression_p (expr))
1734 1889250 : convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error);
1735 6968821 : expr = maybe_cleanup_point_expr_void (expr);
1736 6968821 : if (check_for_bare_parameter_packs (expr))
1737 0 : expr = error_mark_node;
1738 6968821 : 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 7626101 : find_range_for_decls (tree range_for_decl[3])
1749 : {
1750 7626101 : 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 30504404 : for (int i = 0; i < 3; i++)
1756 : {
1757 22878303 : tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i];
1758 22878303 : if (IDENTIFIER_BINDING (id)
1759 22878303 : && IDENTIFIER_BINDING (id)->scope == current_binding_level)
1760 : {
1761 330931 : range_for_decl[i] = IDENTIFIER_BINDING (id)->value;
1762 330931 : gcc_assert (VAR_P (range_for_decl[i])
1763 : && DECL_ARTIFICIAL (range_for_decl[i]));
1764 : }
1765 : }
1766 7626101 : }
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 7625988 : finish_for_stmt (tree for_stmt)
1775 : {
1776 7625988 : end_maybe_infinite_loop (boolean_true_node);
1777 :
1778 7625988 : if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
1779 206162 : RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
1780 : else
1781 : {
1782 7419826 : 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 7419652 : FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
1788 7419826 : if (FOR_COND (for_stmt))
1789 7064656 : finish_loop_cond (&FOR_COND (for_stmt),
1790 7064656 : FOR_EXPR (for_stmt) ? integer_one_node
1791 134785 : : FOR_BODY (for_stmt));
1792 : }
1793 :
1794 : /* Pop the scope for the body of the loop. */
1795 7625988 : tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
1796 7625988 : ? &RANGE_FOR_SCOPE (for_stmt)
1797 7419826 : : &FOR_SCOPE (for_stmt));
1798 7625988 : tree scope = *scope_ptr;
1799 7625988 : *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 7625988 : tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
1806 7625988 : find_range_for_decls (range_for_decl);
1807 :
1808 7625988 : 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 7625988 : if (!stmts_are_full_exprs_p ())
1813 12137 : return;
1814 :
1815 30455404 : for (int i = 0; i < 3; i++)
1816 22841553 : if (range_for_decl[i])
1817 330815 : DECL_NAME (range_for_decl[i])
1818 330815 : = 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 206162 : begin_range_for_stmt (tree scope, tree init)
1828 : {
1829 206162 : begin_maybe_infinite_loop (boolean_false_node);
1830 :
1831 206162 : tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE,
1832 : NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
1833 :
1834 206162 : if (scope == NULL_TREE)
1835 : {
1836 254 : gcc_assert (!init);
1837 254 : scope = begin_for_scope (&init);
1838 : }
1839 :
1840 : /* Since C++20, RANGE_FOR_STMTs can use the init tree, so save it. */
1841 206162 : RANGE_FOR_INIT_STMT (r) = init;
1842 206162 : RANGE_FOR_SCOPE (r) = scope;
1843 :
1844 206162 : 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 206162 : finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
1853 : {
1854 206162 : if (processing_template_decl)
1855 412324 : RANGE_FOR_INIT_STMT (range_for_stmt)
1856 412324 : = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt));
1857 206162 : RANGE_FOR_DECL (range_for_stmt) = decl;
1858 206162 : RANGE_FOR_EXPR (range_for_stmt) = expr;
1859 206162 : add_stmt (range_for_stmt);
1860 206162 : RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
1861 206162 : }
1862 :
1863 : /* Begin the scope of an expansion-statement. */
1864 :
1865 : tree
1866 1403 : begin_template_for_scope (tree *init)
1867 : {
1868 1403 : tree scope = do_pushlevel (sk_template_for);
1869 :
1870 1403 : if (processing_template_decl)
1871 416 : *init = push_stmt_list ();
1872 : else
1873 987 : *init = NULL_TREE;
1874 :
1875 1403 : return scope;
1876 : }
1877 :
1878 : /* Finish a break-statement. */
1879 :
1880 : tree
1881 5727200 : 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 5727200 : if (!block_may_fallthru (cur_stmt_list))
1891 711 : return void_node;
1892 5726489 : note_break_stmt ();
1893 5726489 : return add_stmt (build_stmt (input_location, BREAK_STMT, NULL_TREE));
1894 : }
1895 :
1896 : /* Finish a continue-statement. */
1897 :
1898 : tree
1899 221985 : finish_continue_stmt (void)
1900 : {
1901 221985 : 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 1033229 : begin_switch_stmt (void)
1909 : {
1910 1033229 : tree r, scope;
1911 :
1912 1033229 : scope = do_pushlevel (sk_cond);
1913 1033229 : r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1914 : scope, NULL_TREE);
1915 :
1916 1033229 : begin_cond (&SWITCH_STMT_COND (r));
1917 :
1918 1033229 : return r;
1919 : }
1920 :
1921 : /* Finish the cond of a switch-statement. */
1922 :
1923 : void
1924 1033229 : finish_switch_cond (tree cond, tree switch_stmt)
1925 : {
1926 1033229 : tree orig_type = NULL;
1927 :
1928 1033229 : if (!processing_template_decl)
1929 : {
1930 : /* Convert the condition to an integer or enumeration type. */
1931 628977 : 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 629031 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1940 18 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1941 628977 : cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
1942 628977 : 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 628977 : orig_type = unlowered_expr_type (cond);
1950 628977 : if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
1951 263341 : orig_type = TREE_TYPE (cond);
1952 628977 : if (cond != error_mark_node)
1953 : {
1954 : /* [stmt.switch]
1955 :
1956 : Integral promotions are performed. */
1957 628944 : cond = perform_integral_promotions (cond);
1958 628944 : cond = maybe_cleanup_point_expr (cond);
1959 : }
1960 : }
1961 1033229 : if (check_for_bare_parameter_packs (cond))
1962 0 : cond = error_mark_node;
1963 1033229 : else if (!processing_template_decl && warn_sequence_point)
1964 2749 : verify_sequence_points (cond);
1965 :
1966 1033229 : finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
1967 1033229 : SWITCH_STMT_TYPE (switch_stmt) = orig_type;
1968 1033229 : add_stmt (switch_stmt);
1969 1033229 : push_switch (switch_stmt);
1970 1033229 : SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
1971 1033229 : }
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 1033229 : finish_switch_stmt (tree switch_stmt)
1978 : {
1979 1033229 : tree scope;
1980 :
1981 2066458 : SWITCH_STMT_BODY (switch_stmt) =
1982 1033229 : pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
1983 1033229 : pop_switch ();
1984 :
1985 1033229 : scope = SWITCH_STMT_SCOPE (switch_stmt);
1986 1033229 : SWITCH_STMT_SCOPE (switch_stmt) = NULL;
1987 1033229 : add_stmt (do_poplevel (scope));
1988 1033229 : }
1989 :
1990 : /* Begin a try-block. Returns a newly-created TRY_BLOCK if
1991 : appropriate. */
1992 :
1993 : tree
1994 1117168 : begin_try_block (void)
1995 : {
1996 1117168 : tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
1997 1117168 : add_stmt (r);
1998 1117168 : TRY_STMTS (r) = push_stmt_list ();
1999 1117168 : 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 1117168 : finish_try_block (tree try_block)
2023 : {
2024 1117168 : TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
2025 1117168 : TRY_HANDLERS (try_block) = push_stmt_list ();
2026 1117168 : }
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 1117168 : finish_handler_sequence (tree try_block)
2063 : {
2064 1117168 : TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
2065 1117168 : check_handlers (TRY_HANDLERS (try_block));
2066 1117168 : }
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 1556077 : begin_handler (void)
2084 : {
2085 1556077 : tree r;
2086 :
2087 1556077 : r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
2088 1556077 : add_stmt (r);
2089 :
2090 : /* Create a binding level for the eh_info and the exception object
2091 : cleanup. */
2092 1556077 : HANDLER_BODY (r) = do_pushlevel (sk_catch);
2093 :
2094 1556077 : 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 1556077 : finish_handler_parms (tree decl, tree handler)
2103 : {
2104 1556077 : tree type = NULL_TREE;
2105 1556077 : if (processing_template_decl)
2106 : {
2107 1419177 : if (decl)
2108 : {
2109 461797 : decl = pushdecl (decl);
2110 461797 : decl = push_template_decl (decl);
2111 461797 : HANDLER_PARMS (handler) = decl;
2112 461797 : type = TREE_TYPE (decl);
2113 : }
2114 : }
2115 : else
2116 : {
2117 136900 : type = expand_start_catch_block (decl);
2118 136900 : if (warn_catch_value
2119 2070 : && type != NULL_TREE
2120 709 : && type != error_mark_node
2121 137609 : && !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 1556077 : HANDLER_TYPE (handler) = type;
2143 1556077 : }
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 1556077 : finish_handler (tree handler)
2150 : {
2151 1556077 : if (!processing_template_decl)
2152 136900 : expand_end_catch_block ();
2153 1556077 : HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
2154 1556077 : }
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 297132013 : begin_compound_stmt (unsigned int flags)
2165 : {
2166 297132013 : tree r;
2167 :
2168 297132013 : if (flags & BCS_NO_SCOPE)
2169 : {
2170 7779663 : r = push_stmt_list ();
2171 7779663 : 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 7779663 : keep_next_level (false);
2178 : }
2179 : else
2180 : {
2181 289352350 : scope_kind sk = sk_block;
2182 289352350 : if (flags & BCS_TRY_BLOCK)
2183 : sk = sk_try;
2184 288235300 : else if (flags & BCS_TRANSACTION)
2185 : sk = sk_transaction;
2186 288235065 : else if (flags & BCS_STMT_EXPR)
2187 29082 : sk = sk_stmt_expr;
2188 289352350 : 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 297132013 : if (processing_template_decl)
2198 : {
2199 183294097 : r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
2200 183294097 : BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
2201 183294097 : BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
2202 183294097 : TREE_SIDE_EFFECTS (r) = 1;
2203 : }
2204 :
2205 297132013 : return r;
2206 : }
2207 :
2208 : /* Finish a compound-statement, which is given by STMT. */
2209 :
2210 : void
2211 297131974 : finish_compound_stmt (tree stmt)
2212 : {
2213 297131974 : if (TREE_CODE (stmt) == BIND_EXPR)
2214 : {
2215 183294097 : 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 183294097 : if (TREE_CODE (body) == STATEMENT_LIST
2220 167796241 : && STATEMENT_LIST_HEAD (body) == NULL
2221 11215225 : && !BIND_EXPR_BODY_BLOCK (stmt)
2222 194017019 : && !BIND_EXPR_TRY_BLOCK (stmt))
2223 : stmt = body;
2224 : else
2225 172571272 : BIND_EXPR_BODY (stmt) = body;
2226 : }
2227 113837877 : else if (STATEMENT_LIST_NO_SCOPE (stmt))
2228 7743629 : stmt = pop_stmt_list (stmt);
2229 : else
2230 : {
2231 : /* Destroy any ObjC "super" receivers that may have been
2232 : created. */
2233 106094248 : objc_clear_super_receiver ();
2234 :
2235 106094248 : stmt = do_poplevel (stmt);
2236 : }
2237 :
2238 : /* ??? See c_end_compound_stmt wrt statement expressions. */
2239 297131974 : add_stmt (stmt);
2240 297131974 : }
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 53760 : finish_asm_string_expression (location_t loc, tree string)
2248 : {
2249 53760 : if (string == error_mark_node
2250 53747 : || 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 25440 : 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 25440 : tree r;
2277 25440 : tree t;
2278 25440 : int ninputs = list_length (input_operands);
2279 25440 : int noutputs = list_length (output_operands);
2280 :
2281 25440 : if (!processing_template_decl)
2282 : {
2283 12363 : const char *constraint;
2284 12363 : const char **oconstraints;
2285 12363 : bool allows_mem, allows_reg, is_inout;
2286 12363 : tree operand;
2287 12363 : int i;
2288 :
2289 12363 : oconstraints = XALLOCAVEC (const char *, noutputs);
2290 :
2291 24624 : string = finish_asm_string_expression (cp_expr_loc_or_loc (string, loc),
2292 : string);
2293 12363 : if (string == error_mark_node)
2294 109 : return error_mark_node;
2295 36807 : for (int i = 0; i < 2; ++i)
2296 84420 : for (t = i ? input_operands : output_operands; t; t = TREE_CHAIN (t))
2297 : {
2298 35344 : tree s = TREE_VALUE (TREE_PURPOSE (t));
2299 70670 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2300 35344 : if (s == error_mark_node)
2301 : return error_mark_node;
2302 35314 : TREE_VALUE (TREE_PURPOSE (t)) = s;
2303 : }
2304 17707 : for (t = clobbers; t; t = TREE_CHAIN (t))
2305 : {
2306 5453 : tree s = TREE_VALUE (t);
2307 10900 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2308 5453 : TREE_VALUE (t) = s;
2309 : }
2310 :
2311 12254 : string = resolve_asm_operand_names (string, output_operands,
2312 : input_operands, labels);
2313 :
2314 30649 : for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
2315 : {
2316 18395 : 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 18395 : STRIP_NOPS (operand);
2325 :
2326 18395 : operand = mark_lvalue_use (operand);
2327 :
2328 18395 : if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
2329 9 : operand = error_mark_node;
2330 :
2331 18395 : if (operand != error_mark_node
2332 18395 : && (TREE_READONLY (operand)
2333 18380 : || CP_TYPE_CONST_P (TREE_TYPE (operand))
2334 : /* Functions are not modifiable, even though they are
2335 : lvalues. */
2336 18380 : || 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 18380 : || (CLASS_TYPE_P (TREE_TYPE (operand))
2340 150 : && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
2341 6 : cxx_readonly_error (loc, operand, lv_asm);
2342 :
2343 : tree *op = &operand;
2344 18402 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2345 7 : op = &TREE_OPERAND (*op, 1);
2346 18395 : 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 18395 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2359 18395 : oconstraints[i] = constraint;
2360 :
2361 18395 : 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 18386 : if (!allows_reg && !cxx_mark_addressable (*op))
2368 0 : operand = error_mark_node;
2369 18386 : 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 439 : 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 18374 : 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 18395 : TREE_VALUE (t) = operand;
2415 : }
2416 :
2417 29168 : for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
2418 : {
2419 16914 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2420 16914 : bool constraint_parsed
2421 16914 : = 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 16914 : if (constraint_parsed && !allows_reg && allows_mem)
2427 318 : operand = mark_lvalue_use (TREE_VALUE (t));
2428 : else
2429 16596 : 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 16914 : 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 16914 : if (constraint_parsed)
2444 : {
2445 : /* If the operand is going to end up in memory,
2446 : mark it addressable. */
2447 16893 : 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 318 : STRIP_NOPS (operand);
2452 :
2453 318 : tree *op = &operand;
2454 325 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2455 7 : op = &TREE_OPERAND (*op, 1);
2456 318 : 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 318 : if (!cxx_mark_addressable (*op))
2469 0 : operand = error_mark_node;
2470 : }
2471 16575 : 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 16893 : 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 16893 : 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 16914 : 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 16797 : 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 16914 : TREE_VALUE (t) = operand;
2551 : }
2552 : }
2553 :
2554 25331 : r = build_stmt (loc, ASM_EXPR, string,
2555 : output_operands, input_operands,
2556 : clobbers, labels);
2557 25331 : ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
2558 25331 : ASM_INLINE_P (r) = inline_p;
2559 25331 : if (toplev_p)
2560 : {
2561 99 : symtab->finalize_toplevel_asm (r);
2562 99 : return r;
2563 : }
2564 25232 : r = maybe_cleanup_point_expr_void (r);
2565 25232 : 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 3887726 : finish_decl_cleanup (tree decl, tree cleanup)
2603 : {
2604 3887726 : push_cleanup (decl, cleanup, false);
2605 3887726 : }
2606 :
2607 : /* If the current scope exits with an exception, run CLEANUP. */
2608 :
2609 : void
2610 2162328 : finish_eh_cleanup (tree cleanup)
2611 : {
2612 2162328 : push_cleanup (NULL, cleanup, true);
2613 2162328 : }
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 20431282 : 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 20431282 : mem_inits = nreverse (mem_inits);
2625 :
2626 20431282 : if (processing_template_decl)
2627 : {
2628 : tree mem;
2629 :
2630 33175959 : 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 19637440 : if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
2638 19637440 : && check_for_bare_parameter_packs (TREE_VALUE (mem)))
2639 3 : TREE_VALUE (mem) = error_mark_node;
2640 : }
2641 :
2642 13538519 : add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
2643 : CTOR_INITIALIZER, mem_inits));
2644 : }
2645 : else
2646 6892763 : emit_mem_initializers (mem_inits);
2647 20431282 : }
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 46015203 : force_paren_expr (tree expr, bool even_uneval /* = false */)
2655 : {
2656 : /* This is only needed for decltype(auto) in C++14. */
2657 46015203 : 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 45397824 : if (cp_unevaluated_operand && !even_uneval)
2663 : return expr;
2664 :
2665 37972339 : if (TREE_CODE (expr) == COMPONENT_REF
2666 37915445 : || TREE_CODE (expr) == SCOPE_REF
2667 75881603 : || REFERENCE_REF_P (expr))
2668 895258 : REF_PARENTHESIZED_P (expr) = true;
2669 37077081 : else if (DECL_P (tree_strip_any_location_wrapper (expr)))
2670 : {
2671 1677307 : location_t loc = cp_expr_location (expr);
2672 1677307 : const tree_code code = processing_template_decl ? PAREN_EXPR
2673 : : VIEW_CONVERT_EXPR;
2674 1677307 : expr = build1_loc (loc, code, TREE_TYPE (expr), expr);
2675 1677307 : 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 1200576099 : maybe_undo_parenthesized_ref (tree t)
2686 : {
2687 1200576099 : if (cxx_dialect < cxx14)
2688 : return t;
2689 :
2690 1190852974 : if ((TREE_CODE (t) == PAREN_EXPR || TREE_CODE (t) == VIEW_CONVERT_EXPR)
2691 1324009981 : && REF_PARENTHESIZED_P (t))
2692 188723 : t = TREE_OPERAND (t, 0);
2693 :
2694 : return t;
2695 : }
2696 :
2697 : /* Finish a parenthesized expression EXPR. */
2698 :
2699 : cp_expr
2700 31917877 : finish_parenthesized_expr (cp_expr expr)
2701 : {
2702 31917877 : if (EXPR_P (expr))
2703 : {
2704 : /* This inhibits warnings in maybe_warn_unparenthesized_assignment
2705 : and c_common_truthvalue_conversion. */
2706 63550985 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wparentheses);
2707 : /* And maybe_warn_sizeof_array_div. */
2708 63550985 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wsizeof_array_div);
2709 : }
2710 :
2711 31917877 : if (TREE_CODE (expr) == OFFSET_REF
2712 31917877 : || 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 28757 : PTRMEM_OK_P (expr) = 0;
2716 :
2717 31917877 : tree stripped_expr = tree_strip_any_location_wrapper (expr);
2718 31917877 : if (TREE_CODE (stripped_expr) == STRING_CST)
2719 834943 : PAREN_STRING_LITERAL_P (stripped_expr) = 1;
2720 31082934 : else if (TREE_CODE (stripped_expr) == PACK_INDEX_EXPR)
2721 900 : PACK_INDEX_PARENTHESIZED_P (stripped_expr) = true;
2722 :
2723 31917877 : expr = cp_expr (force_paren_expr (expr), expr.get_location ());
2724 :
2725 31917877 : 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 83799771 : finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
2733 : tsubst_flags_t complain /* = tf_warning_or_error */)
2734 : {
2735 83799771 : gcc_assert (TREE_CODE (decl) == FIELD_DECL);
2736 83799771 : bool try_omp_private = !object && omp_private_member_map;
2737 64849956 : tree ret;
2738 :
2739 64849956 : if (!object)
2740 : {
2741 64849956 : tree scope = qualifying_scope;
2742 64849956 : if (scope == NULL_TREE)
2743 : {
2744 64838924 : scope = context_for_name_lookup (decl);
2745 64838924 : 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 64849953 : object = maybe_dummy_object (scope, NULL);
2753 : }
2754 :
2755 83799768 : object = maybe_resolve_dummy (object, true);
2756 83799768 : 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 83799765 : if (is_dummy_object (object)
2762 30478 : && !cp_unevaluated_operand
2763 83799861 : && (!processing_template_decl || !current_class_ref))
2764 : {
2765 81 : 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 81 : return error_mark_node;
2785 : }
2786 :
2787 83799684 : if (current_class_ptr)
2788 83421958 : TREE_USED (current_class_ptr) = 1;
2789 83799684 : if (processing_template_decl)
2790 : {
2791 59285805 : tree type = TREE_TYPE (decl);
2792 :
2793 59285805 : if (TYPE_REF_P (type))
2794 : /* Quals on the object don't matter. */;
2795 57000104 : else if (PACK_EXPANSION_P (type))
2796 : /* Don't bother trying to represent this. */
2797 : type = NULL_TREE;
2798 56997732 : 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 56995485 : int quals = cp_type_quals (TREE_TYPE (object));
2812 :
2813 56995485 : if (DECL_MUTABLE_P (decl))
2814 285377 : quals &= ~TYPE_QUAL_CONST;
2815 :
2816 56995485 : quals |= cp_type_quals (TREE_TYPE (decl));
2817 56995485 : type = cp_build_qualified_type (type, quals);
2818 : }
2819 :
2820 59285805 : if (qualifying_scope)
2821 : /* Wrap this in a SCOPE_REF for now. */
2822 9094 : ret = build_qualified_name (type, qualifying_scope, decl,
2823 : /*template_p=*/false);
2824 : else
2825 59276711 : ret = (convert_from_reference
2826 59276711 : (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 24513879 : tree access_type = TREE_TYPE (object);
2833 :
2834 24513879 : 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 24513879 : if (qualifying_scope)
2841 : {
2842 1900 : tree binfo = NULL_TREE;
2843 1900 : object = build_scoped_ref (object, qualifying_scope,
2844 : &binfo);
2845 : }
2846 :
2847 24513879 : ret = build_class_member_access_expr (object, decl,
2848 : /*access_path=*/NULL_TREE,
2849 : /*preserve_reference=*/false,
2850 : complain);
2851 : }
2852 83799684 : 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 4717913668 : 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 4717913668 : if (deferred_access_no_check)
2876 : return true;
2877 :
2878 : /* Determine the SCOPE of DECL. */
2879 4710116401 : tree scope = context_for_name_lookup (decl);
2880 : /* If the SCOPE is not a type, then DECL is not a member. */
2881 4710116401 : 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 4710116401 : || dependent_type_p (scope))
2886 4183914665 : return true;
2887 :
2888 526201736 : tree qualifying_type = NULL_TREE;
2889 : /* Compute the scope through which DECL is being accessed. */
2890 526201736 : 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 92952 : && CLASS_TYPE_P (object_type)
2900 526294671 : && 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 92926 : if (tree open = currently_open_class (object_type))
2905 : qualifying_type = open;
2906 : else
2907 : qualifying_type = object_type;
2908 : }
2909 526108810 : 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 753219921 : if (DECL_NONSTATIC_MEMBER_P (decl)
2915 376659419 : && current_class_ptr)
2916 39630 : if (tree current = current_nonlambda_class_type ())
2917 : {
2918 39607 : 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 3565 : 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 149498848 : qualifying_type = currently_open_derived_class (scope);
2938 :
2939 526109210 : 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 526165694 : && CLASS_TYPE_P (qualifying_type))
2943 500256094 : return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
2944 500256094 : 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 96529141 : 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 96529141 : gcc_assert (TYPE_P (qualifying_class));
2967 :
2968 96529141 : if (error_operand_p (expr))
2969 21 : return error_mark_node;
2970 :
2971 96529120 : if (DECL_P (expr)
2972 : /* Functions are marked after overload resolution; avoid redundant
2973 : warnings. */
2974 89008694 : && TREE_CODE (expr) != FUNCTION_DECL
2975 185537790 : && !mark_used (expr, complain))
2976 0 : return error_mark_node;
2977 :
2978 96529120 : if (template_p)
2979 : {
2980 239481 : 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 239472 : 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 96529120 : if (address_p && done
2994 154258 : && TREE_CODE (qualifying_class) != ENUMERAL_TYPE)
2995 : {
2996 154256 : if (TREE_CODE (expr) == SCOPE_REF)
2997 0 : expr = TREE_OPERAND (expr, 1);
2998 154256 : expr = build_offset_ref (qualifying_class, expr,
2999 : /*address_p=*/true, complain);
3000 154256 : return expr;
3001 : }
3002 :
3003 : /* No need to check access within an enum. */
3004 96374864 : if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE
3005 3382017 : && 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 92992850 : 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 92990242 : else if (TREE_CODE (expr) == FIELD_DECL)
3015 : {
3016 11032 : push_deferring_access_checks (dk_no_check);
3017 11032 : expr = finish_non_static_data_member (expr, NULL_TREE,
3018 : qualifying_class, complain);
3019 11032 : pop_deferring_access_checks ();
3020 : }
3021 92979210 : 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 7082892 : if (!shared_member_p (expr)
3026 454809 : && current_class_ptr
3027 7537068 : && DERIVED_FROM_P (qualifying_class,
3028 : current_nonlambda_class_type ()))
3029 453976 : expr = (build_class_member_access_expr
3030 453976 : (maybe_dummy_object (qualifying_class, NULL),
3031 : expr,
3032 453976 : BASELINK_ACCESS_BINFO (expr),
3033 : /*preserve_reference=*/false,
3034 : complain));
3035 6628916 : else if (done)
3036 : /* The expression is a qualified name whose address is not
3037 : being taken. */
3038 2440 : expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
3039 : complain);
3040 : }
3041 85896318 : else if (!template_p
3042 85703189 : && TREE_CODE (expr) == TEMPLATE_DECL
3043 85896397 : && !DECL_FUNCTION_TEMPLATE_P (expr))
3044 : {
3045 79 : if (complain & tf_error)
3046 4 : error ("%qE missing template arguments", expr);
3047 79 : 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 85896239 : if (processing_template_decl
3057 85896239 : && (!currently_open_class (qualifying_class)
3058 9830 : || TREE_CODE (expr) == IDENTIFIER_NODE
3059 9830 : || TREE_CODE (expr) == TEMPLATE_ID_EXPR
3060 82 : || TREE_CODE (expr) == BIT_NOT_EXPR))
3061 10455040 : expr = build_qualified_name (TREE_TYPE (expr),
3062 : qualifying_class, expr,
3063 : template_p);
3064 75441199 : else if (tree wrap = maybe_get_tls_wrapper_call (expr))
3065 9 : expr = wrap;
3066 :
3067 85896239 : 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 7801493 : begin_stmt_expr (void)
3078 : {
3079 7801493 : 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 29581 : finish_stmt_expr_expr (tree expr, tree stmt_expr)
3089 : {
3090 29581 : 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 29578 : if (expr)
3101 : {
3102 29563 : tree type = TREE_TYPE (expr);
3103 :
3104 29563 : 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 29548 : 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 29379 : 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 29348 : expr = force_rvalue (expr, tf_warning_or_error);
3131 29348 : if (error_operand_p (expr))
3132 0 : return error_mark_node;
3133 :
3134 : /* Update for array-to-pointer decay. */
3135 29348 : type = TREE_TYPE (expr);
3136 :
3137 : /* This TARGET_EXPR will initialize the outer one added by
3138 : finish_stmt_expr. */
3139 29348 : 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 29348 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
3145 29348 : expr = maybe_cleanup_point_expr (expr);
3146 29348 : add_stmt (expr);
3147 : }
3148 :
3149 : /* The type of the statement-expression is the type of the last
3150 : expression. */
3151 29548 : 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 7801493 : finish_stmt_expr (tree stmt_expr, bool has_no_scope)
3163 : {
3164 7801493 : tree type;
3165 7801493 : tree result;
3166 :
3167 7801493 : if (error_operand_p (stmt_expr))
3168 : {
3169 18 : pop_stmt_list (stmt_expr);
3170 18 : return error_mark_node;
3171 : }
3172 :
3173 7801475 : gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
3174 :
3175 7801475 : type = TREE_TYPE (stmt_expr);
3176 7801475 : result = pop_stmt_list (stmt_expr);
3177 7801475 : TREE_TYPE (result) = type;
3178 :
3179 7801475 : if (processing_template_decl)
3180 : {
3181 36227 : result = build_min (STMT_EXPR, type, result);
3182 36227 : TREE_SIDE_EFFECTS (result) = 1;
3183 36227 : STMT_EXPR_NO_SCOPE (result) = has_no_scope;
3184 : }
3185 7765248 : 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 59005727 : empty_expr_stmt_p (tree expr_stmt)
3221 : {
3222 59005731 : tree body = NULL_TREE;
3223 :
3224 59005731 : if (expr_stmt == void_node)
3225 : return true;
3226 :
3227 59005728 : if (expr_stmt)
3228 : {
3229 59005728 : if (TREE_CODE (expr_stmt) == EXPR_STMT)
3230 4 : body = EXPR_STMT_EXPR (expr_stmt);
3231 59005724 : else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
3232 : body = expr_stmt;
3233 : }
3234 :
3235 4 : if (body)
3236 : {
3237 58117068 : if (TREE_CODE (body) == STATEMENT_LIST)
3238 58117064 : 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 19863565 : perform_koenig_lookup (cp_expr fn_expr, vec<tree, va_gc> *args,
3251 : tsubst_flags_t complain)
3252 : {
3253 19863565 : tree identifier = NULL_TREE;
3254 19863565 : tree functions = NULL_TREE;
3255 19863565 : tree tmpl_args = NULL_TREE;
3256 19863565 : bool template_id = false;
3257 19863565 : location_t loc = fn_expr.get_location ();
3258 19863565 : tree fn = fn_expr.get_value ();
3259 :
3260 19863565 : STRIP_ANY_LOCATION_WRAPPER (fn);
3261 :
3262 19863565 : if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
3263 : {
3264 : /* Use a separate flag to handle null args. */
3265 4125581 : template_id = true;
3266 4125581 : tmpl_args = TREE_OPERAND (fn, 1);
3267 4125581 : fn = TREE_OPERAND (fn, 0);
3268 : }
3269 :
3270 : /* Find the name of the overloaded function. */
3271 19863565 : if (identifier_p (fn))
3272 : identifier = fn;
3273 : else
3274 : {
3275 28719432 : functions = fn;
3276 19615176 : 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 19863565 : if (!any_type_dependent_arguments_p (args)
3284 19863565 : && !any_dependent_template_arguments_p (tmpl_args))
3285 : {
3286 18980480 : fn = lookup_arg_dependent (identifier, functions, args);
3287 18980480 : if (!fn)
3288 : {
3289 : /* The unqualified name could not be resolved. */
3290 56556 : if (complain & tf_error)
3291 390 : fn = unqualified_fn_lookup_error (cp_expr (identifier, loc));
3292 : else
3293 : fn = identifier;
3294 : }
3295 : }
3296 :
3297 19863565 : if (fn && template_id && fn != error_mark_node)
3298 4125568 : fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
3299 :
3300 19863565 : 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 402264292 : finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
3316 : bool koenig_p, tsubst_flags_t complain)
3317 : {
3318 402264292 : tree result;
3319 402264292 : tree orig_fn;
3320 402264292 : vec<tree, va_gc> *orig_args = *args;
3321 402264292 : tsubst_flags_t orig_complain = complain;
3322 :
3323 402264292 : if (fn == error_mark_node)
3324 : return error_mark_node;
3325 :
3326 402263277 : complain &= ~tf_any_viable;
3327 402263277 : 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 402263277 : fn = maybe_undo_parenthesized_ref (fn);
3332 :
3333 402263277 : STRIP_ANY_LOCATION_WRAPPER (fn);
3334 :
3335 402263277 : orig_fn = fn;
3336 :
3337 402263277 : 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 402263271 : 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 224754293 : if (is_overloaded_fn (fn))
3349 : {
3350 137798989 : tree ifn = get_first_fn (fn);
3351 137798989 : if (TREE_CODE (ifn) == FUNCTION_DECL
3352 137798989 : && dependent_local_decl_p (ifn))
3353 38528 : 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 224754293 : if (type_dependent_expression_p (fn)
3360 224754293 : || any_type_dependent_arguments_p (*args))
3361 : {
3362 203606161 : if (koenig_p
3363 10095185 : && TREE_CODE (orig_fn) == FUNCTION_DECL
3364 206723354 : && !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 812587 : orig_fn = ovl_make (orig_fn, NULL_TREE);
3370 203606161 : result = build_min_nt_call_vec (orig_fn, *args);
3371 276638549 : SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
3372 203606161 : 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 203606161 : suppress_warning (result, OPT_Wpessimizing_move);
3377 :
3378 203606161 : if (cfun && cp_function_chain && !cp_unevaluated_operand)
3379 : {
3380 177753364 : bool abnormal = true;
3381 177963520 : for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter)
3382 : {
3383 98447189 : tree fndecl = STRIP_TEMPLATE (*iter);
3384 98447189 : if (TREE_CODE (fndecl) != FUNCTION_DECL
3385 98447111 : || !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 177753364 : if (abnormal)
3397 79516331 : current_function_returns_abnormally = 1;
3398 : }
3399 203606161 : if (TREE_CODE (fn) == COMPONENT_REF)
3400 94703260 : maybe_generic_this_capture (TREE_OPERAND (fn, 0),
3401 94703260 : TREE_OPERAND (fn, 1));
3402 203606161 : return result;
3403 : }
3404 21148132 : orig_args = make_tree_vector_copy (*args);
3405 : }
3406 :
3407 198657110 : if (TREE_CODE (fn) == COMPONENT_REF)
3408 : {
3409 42128741 : tree member = TREE_OPERAND (fn, 1);
3410 42128741 : if (BASELINK_P (member))
3411 : {
3412 41933557 : tree object = TREE_OPERAND (fn, 0);
3413 83429364 : 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 41933557 : complain);
3420 : }
3421 : }
3422 :
3423 : /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */
3424 156723553 : if (TREE_CODE (fn) == ADDR_EXPR
3425 156723553 : && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
3426 9 : fn = TREE_OPERAND (fn, 0);
3427 :
3428 156723553 : if (is_overloaded_fn (fn))
3429 145553915 : fn = baselink_for_fns (fn);
3430 :
3431 156723553 : result = NULL_TREE;
3432 156723553 : if (BASELINK_P (fn))
3433 : {
3434 14693928 : 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 14693928 : 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 14693889 : object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
3464 : NULL);
3465 :
3466 16533860 : 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 142029625 : else if (is_overloaded_fn (fn))
3474 : {
3475 : /* If the function is an overloaded builtin, resolve it. */
3476 130859987 : if (TREE_CODE (fn) == FUNCTION_DECL
3477 130859987 : && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3478 19146457 : || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
3479 10187789 : result = resolve_overloaded_builtin (input_location, fn, *args,
3480 : complain & tf_error);
3481 :
3482 10187789 : if (!result)
3483 : {
3484 130528988 : tree alloc_size_attr = NULL_TREE;
3485 130528988 : if (warn_calloc_transposed_args
3486 657029 : && TREE_CODE (fn) == FUNCTION_DECL
3487 130528988 : && (alloc_size_attr
3488 421477 : = lookup_attribute ("alloc_size",
3489 421477 : TYPE_ATTRIBUTES (TREE_TYPE (fn)))))
3490 3195 : if (TREE_VALUE (alloc_size_attr) == NULL_TREE
3491 3195 : || TREE_CHAIN (TREE_VALUE (alloc_size_attr)) == NULL_TREE)
3492 : alloc_size_attr = NULL_TREE;
3493 128866483 : if ((warn_sizeof_pointer_memaccess || alloc_size_attr)
3494 1662565 : && (complain & tf_warning)
3495 1475904 : && !vec_safe_is_empty (*args)
3496 131667294 : && !processing_template_decl)
3497 : {
3498 : location_t sizeof_arg_loc[6];
3499 : tree sizeof_arg[6];
3500 : unsigned int i;
3501 8172420 : for (i = 0; i < (alloc_size_attr ? 6 : 3); i++)
3502 : {
3503 3064860 : tree t;
3504 :
3505 3064860 : sizeof_arg_loc[i] = UNKNOWN_LOCATION;
3506 3064860 : sizeof_arg[i] = NULL_TREE;
3507 3064860 : if (i >= (*args)->length ())
3508 637090 : continue;
3509 2427770 : t = (**args)[i];
3510 2427770 : if (TREE_CODE (t) != SIZEOF_EXPR)
3511 2421193 : continue;
3512 6577 : if (SIZEOF_EXPR_TYPE_P (t))
3513 2601 : sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
3514 : else
3515 3976 : sizeof_arg[i] = TREE_OPERAND (t, 0);
3516 6577 : sizeof_arg_loc[i] = EXPR_LOCATION (t);
3517 : }
3518 1021560 : if (warn_sizeof_pointer_memaccess)
3519 : {
3520 1021500 : auto same_p = same_type_ignoring_top_level_qualifiers_p;
3521 1021500 : sizeof_pointer_memaccess_warning (sizeof_arg_loc, fn, *args,
3522 : sizeof_arg, same_p);
3523 : }
3524 1021560 : if (alloc_size_attr)
3525 60 : warn_for_calloc (sizeof_arg_loc, fn, *args, sizeof_arg,
3526 : alloc_size_attr);
3527 : }
3528 :
3529 130528988 : if ((complain & tf_warning)
3530 60471903 : && TREE_CODE (fn) == FUNCTION_DECL
3531 27637567 : && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
3532 197659 : && vec_safe_length (*args) == 3
3533 130726647 : && !any_type_dependent_arguments_p (*args))
3534 : {
3535 197659 : tree arg0 = (*orig_args)[0];
3536 197659 : tree arg1 = (*orig_args)[1];
3537 197659 : tree arg2 = (*orig_args)[2];
3538 197659 : int literal_mask = ((literal_integer_zerop (arg1) << 1)
3539 197659 : | (literal_integer_zerop (arg2) << 2));
3540 197659 : warn_for_memset (input_location, arg0, arg2, literal_mask);
3541 : }
3542 :
3543 : /* A call to a namespace-scope function. */
3544 130528988 : result = build_new_function_call (fn, args, orig_complain);
3545 : }
3546 : }
3547 11169638 : else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
3548 : {
3549 164445 : 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 164445 : tree ob = TREE_OPERAND (fn, 0);
3556 164445 : if (obvalue_p (ob))
3557 164427 : 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 11005193 : 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 4410177 : result = build_op_call (fn, args, complain);
3566 :
3567 149784020 : if (!result)
3568 : /* A call where the function is unknown. */
3569 6595016 : result = cp_build_function_call_vec (fn, args, complain);
3570 :
3571 156710035 : if (processing_template_decl && result != error_mark_node)
3572 : {
3573 15706102 : if (INDIRECT_REF_P (result))
3574 1133429 : 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 15706102 : if (TREE_CODE (result) == CALL_EXPR
3579 15696784 : && really_overloaded_fn (orig_fn))
3580 : {
3581 5916927 : tree sel_fn = CALL_EXPR_FN (result);
3582 5916927 : if (TREE_CODE (sel_fn) == COMPONENT_REF)
3583 : {
3584 : /* The non-dependent result of build_new_method_call. */
3585 245625 : sel_fn = TREE_OPERAND (sel_fn, 1);
3586 245625 : gcc_assert (BASELINK_P (sel_fn));
3587 : }
3588 5671302 : 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 5671302 : sel_fn = TREE_OPERAND (sel_fn, 0);
3592 : orig_fn = sel_fn;
3593 : }
3594 :
3595 15706102 : tree r = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
3596 15706102 : SET_EXPR_LOCATION (r, input_location);
3597 15706102 : KOENIG_LOOKUP_P (r) = koenig_p;
3598 15706102 : TREE_NO_WARNING (r) = TREE_NO_WARNING (result);
3599 15706102 : release_tree_vector (orig_args);
3600 15706102 : 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 2531722 : 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 2531722 : location_t combined_loc = make_location (input_location,
3620 : expr.get_start (),
3621 : get_finish (input_location));
3622 2531722 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3623 2531722 : NULL_TREE, tf_warning_or_error);
3624 : /* TODO: build_x_unary_op doesn't honor the location, so set it here. */
3625 2531722 : result.set_location (combined_loc);
3626 2531722 : return result;
3627 : }
3628 :
3629 : /* Finish a use of `this'. Returns an expression for `this'. */
3630 :
3631 : tree
3632 34656019 : finish_this_expr (void)
3633 : {
3634 34656019 : tree result = NULL_TREE;
3635 :
3636 69311924 : if (current_class_ref && !LAMBDA_TYPE_P (TREE_TYPE (current_class_ref)))
3637 34381799 : result = current_class_ptr;
3638 548424 : else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
3639 274146 : result = (lambda_expr_this_capture
3640 274146 : (CLASSTYPE_LAMBDA_EXPR (current_class_type), /*add*/true));
3641 : else
3642 74 : gcc_checking_assert (!current_class_ptr);
3643 :
3644 34655945 : if (result)
3645 : /* The keyword 'this' is a prvalue expression. */
3646 34655942 : 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 164496 : finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
3692 : location_t loc, tsubst_flags_t complain)
3693 : {
3694 164496 : if (object == error_mark_node || destructor == error_mark_node)
3695 : return error_mark_node;
3696 :
3697 164487 : gcc_assert (TYPE_P (destructor));
3698 :
3699 164487 : if (!processing_template_decl)
3700 : {
3701 164466 : 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 164466 : if (is_auto (destructor))
3708 3 : destructor = TREE_TYPE (object);
3709 164466 : 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 164463 : 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 164472 : tree type = (type_dependent_expression_p (object)
3742 164472 : ? NULL_TREE : void_type_node);
3743 :
3744 164472 : return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
3745 164472 : scope, destructor);
3746 : }
3747 :
3748 : /* Finish an expression of the form CODE EXPR. */
3749 :
3750 : cp_expr
3751 36623408 : 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 36623408 : location_t combined_loc = make_location (op_loc,
3760 : op_loc, expr.get_finish ());
3761 36623408 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3762 36623408 : NULL_TREE, complain);
3763 : /* TODO: build_x_unary_op doesn't always honor the location. */
3764 36623408 : result.set_location (combined_loc);
3765 :
3766 36623408 : if (result == error_mark_node)
3767 : return result;
3768 :
3769 36622944 : 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 36622944 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
3775 : return result;
3776 :
3777 19642978 : tree result_ovl = result;
3778 19642978 : tree expr_ovl = expr;
3779 :
3780 19642978 : if (!processing_template_decl)
3781 1741022 : expr_ovl = cp_fully_fold (expr_ovl);
3782 :
3783 19642978 : if (!CONSTANT_CLASS_P (expr_ovl)
3784 19642978 : || TREE_OVERFLOW_P (expr_ovl))
3785 : return result;
3786 :
3787 239420 : if (!processing_template_decl)
3788 230392 : result_ovl = cp_fully_fold (result_ovl);
3789 :
3790 239420 : 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 9995234 : finish_compound_literal (tree type, tree compound_literal,
3818 : tsubst_flags_t complain,
3819 : fcl_t fcl_context)
3820 : {
3821 9995234 : if (type == error_mark_node)
3822 : return error_mark_node;
3823 :
3824 9995203 : 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 9995191 : 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 9995167 : if (template_placeholder_p (type))
3861 : {
3862 172867 : type = do_auto_deduction (type, compound_literal, type, complain,
3863 : adc_variable_type);
3864 172867 : if (type == error_mark_node)
3865 : return error_mark_node;
3866 : }
3867 : /* C++23 auto{x}. */
3868 9822300 : else if (is_auto (type)
3869 109 : && !AUTO_IS_DECLTYPE (type)
3870 9822407 : && 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 9995048 : tree orig_cl = NULL_TREE;
3894 :
3895 9995048 : if (processing_template_decl)
3896 : {
3897 4792309 : const bool dependent_p
3898 4792309 : = (instantiation_dependent_expression_p (compound_literal)
3899 4792309 : || dependent_type_p (type));
3900 1580398 : 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 1580398 : orig_cl = unshare_constructor (compound_literal);
3906 4792309 : TREE_TYPE (orig_cl) = type;
3907 : /* Mark the expression as a compound literal. */
3908 4792309 : TREE_HAS_CONSTRUCTOR (orig_cl) = 1;
3909 : /* And as instantiation-dependent. */
3910 4792309 : CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p;
3911 4792309 : 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 4792309 : if (dependent_p)
3915 : return orig_cl;
3916 : /* Otherwise, do go on to e.g. check narrowing. */
3917 : }
3918 :
3919 6783137 : type = complete_type (type);
3920 :
3921 6783137 : 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 1064806 : CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
3928 1064806 : compound_literal = build_tree_list (NULL_TREE, compound_literal);
3929 1064806 : return build_functional_cast (input_location, type,
3930 1064806 : compound_literal, complain);
3931 : }
3932 :
3933 5718331 : if (TREE_CODE (type) == ARRAY_TYPE
3934 5718331 : && check_array_initializer (NULL_TREE, type, compound_literal))
3935 9 : return error_mark_node;
3936 5718322 : compound_literal = reshape_init (type, compound_literal, complain);
3937 5402421 : if (SCALAR_TYPE_P (type)
3938 821563 : && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
3939 5925657 : && !check_narrowing (type, compound_literal, complain))
3940 102 : return error_mark_node;
3941 5718220 : if (TREE_CODE (type) == ARRAY_TYPE
3942 5718220 : && 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 5718217 : compound_literal = digest_init_flags (type, compound_literal,
3950 : LOOKUP_NORMAL | LOOKUP_NO_NARROWING,
3951 : complain);
3952 5718217 : 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 5717619 : if (orig_cl)
3957 : return orig_cl;
3958 :
3959 4226986 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
3960 : {
3961 3457579 : TREE_HAS_CONSTRUCTOR (compound_literal) = true;
3962 3457579 : if (fcl_context == fcl_c99)
3963 38165 : 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 5761515 : if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
3970 2698122 : && fcl_context == fcl_c99
3971 80 : && TREE_CODE (type) == ARRAY_TYPE
3972 28 : && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
3973 4227014 : && 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 4226958 : if (!VECTOR_TYPE_P (type)
4004 4188292 : && (TREE_CODE (compound_literal) == CONSTRUCTOR
4005 769401 : || TREE_CODE (compound_literal) == VEC_INIT_EXPR))
4006 : {
4007 : /* The CONSTRUCTOR is now an initializer, not a compound literal. */
4008 3418891 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
4009 3418891 : TREE_HAS_CONSTRUCTOR (compound_literal) = false;
4010 3418891 : 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 808067 : 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 228448 : finish_fname (tree id)
4024 : {
4025 228448 : 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 228448 : if (current_function_decl
4031 228448 : && !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 228448 : if (processing_template_decl && current_function_decl
4035 157556 : && decl != error_mark_node)
4036 157556 : decl = DECL_NAME (decl);
4037 228448 : return decl;
4038 : }
4039 :
4040 : /* Finish a translation unit. */
4041 :
4042 : void
4043 96549 : finish_translation_unit (void)
4044 : {
4045 : /* In case there were missing closebraces,
4046 : get us back to the global binding level. */
4047 96549 : pop_everything ();
4048 193098 : while (current_namespace != global_namespace)
4049 0 : pop_namespace ();
4050 :
4051 : /* Do file scope __FUNCTION__ et al. */
4052 96549 : finish_fname_decls ();
4053 :
4054 96549 : 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 96549 : 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 96549 : 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 96549 : }
4080 :
4081 : /* Finish a template type parameter, specified as AGGR IDENTIFIER.
4082 : Returns the parameter. */
4083 :
4084 : tree
4085 153057397 : finish_template_type_parm (tree aggr, tree identifier)
4086 : {
4087 153057397 : 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 153057397 : 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 380444 : finish_template_template_parm (tree aggr, tree identifier)
4101 : {
4102 380444 : tree decl = build_decl (input_location,
4103 : TYPE_DECL, identifier, NULL_TREE);
4104 :
4105 380444 : tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
4106 380444 : DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
4107 380444 : DECL_TEMPLATE_RESULT (tmpl) = decl;
4108 380444 : DECL_ARTIFICIAL (decl) = 1;
4109 :
4110 : /* Associate the constraints with the underlying declaration,
4111 : not the template. */
4112 380444 : tree constr = current_template_constraints ();
4113 380444 : set_constraints (decl, constr);
4114 :
4115 380444 : end_template_decl ();
4116 :
4117 380444 : gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
4118 :
4119 380444 : check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
4120 : /*is_primary=*/true, /*is_partial=*/false,
4121 : /*is_friend=*/0);
4122 :
4123 380444 : 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 853 : check_template_template_default_arg (tree argument)
4132 : {
4133 853 : 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 29491942 : begin_class_definition (tree t)
4157 : {
4158 29491942 : if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
4159 33 : return error_mark_node;
4160 :
4161 29492037 : 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 29491900 : if (TREE_CODE (t) == RECORD_TYPE
4170 28998148 : && !processing_template_decl)
4171 : {
4172 10566949 : tree ns = TYPE_CONTEXT (t);
4173 10566947 : if (ns && TREE_CODE (ns) == NAMESPACE_DECL
4174 8456034 : && DECL_CONTEXT (ns) == std_node
4175 2067442 : && DECL_NAME (ns)
4176 12634371 : && 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 18924951 : 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 29491900 : 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 29491900 : 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 29491900 : maybe_process_partial_specialization (t);
4211 29491900 : pushclass (t);
4212 29491900 : TYPE_BEING_DEFINED (t) = 1;
4213 29491900 : class_binding_level->defining_class_p = 1;
4214 :
4215 29491900 : if (flag_pack_struct)
4216 : {
4217 99 : tree v;
4218 99 : TYPE_PACKED (t) = 1;
4219 : /* Even though the type is being defined for the first time
4220 : here, there might have been a forward declaration, so there
4221 : might be cv-qualified variants of T. */
4222 99 : for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
4223 0 : TYPE_PACKED (v) = 1;
4224 : }
4225 : /* Reset the interface data, at the earliest possible
4226 : moment, as it might have been set via a class foo;
4227 : before. */
4228 61475909 : if (! TYPE_UNNAMED_P (t))
4229 : {
4230 28781445 : struct c_fileinfo *finfo = \
4231 28781445 : get_fileinfo (LOCATION_FILE (input_location));
4232 28781445 : CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
4233 28781445 : SET_CLASSTYPE_INTERFACE_UNKNOWN_X
4234 : (t, finfo->interface_unknown);
4235 : }
4236 29491900 : reset_specialization ();
4237 :
4238 : /* Make a declaration for this class in its own scope. */
4239 29491900 : build_self_reference ();
4240 :
4241 29491900 : return t;
4242 : }
4243 :
4244 : /* Finish the member declaration given by DECL. */
4245 :
4246 : void
4247 416664829 : finish_member_declaration (tree decl)
4248 : {
4249 416664829 : if (decl == error_mark_node || decl == NULL_TREE)
4250 : return;
4251 :
4252 416663828 : if (decl == void_type_node)
4253 : /* The COMPONENT was a friend, not a member, and so there's
4254 : nothing for us to do. */
4255 : return;
4256 :
4257 : /* We should see only one DECL at a time. */
4258 416663828 : gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
4259 :
4260 : /* Don't add decls after definition. */
4261 416663849 : gcc_assert (TYPE_BEING_DEFINED (current_class_type)
4262 : /* We can add lambda types when late parsing default
4263 : arguments. */
4264 : || LAMBDA_TYPE_P (TREE_TYPE (decl)));
4265 :
4266 : /* Set up access control for DECL. */
4267 416663828 : TREE_PRIVATE (decl)
4268 416663828 : = (current_access_specifier == access_private_node);
4269 416663828 : TREE_PROTECTED (decl)
4270 416663828 : = (current_access_specifier == access_protected_node);
4271 416663828 : if (TREE_CODE (decl) == TEMPLATE_DECL)
4272 : {
4273 46677494 : TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
4274 46677494 : TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
4275 : }
4276 :
4277 : /* Mark the DECL as a member of the current class, unless it's
4278 : a member of an enumeration. */
4279 416663828 : if (TREE_CODE (decl) != CONST_DECL)
4280 414432138 : DECL_CONTEXT (decl) = current_class_type;
4281 :
4282 : /* Remember the single FIELD_DECL an anonymous aggregate type is used for. */
4283 416663828 : if (TREE_CODE (decl) == FIELD_DECL
4284 416663828 : && ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
4285 : {
4286 266924 : gcc_assert (!ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))));
4287 266924 : ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = decl;
4288 : }
4289 :
4290 416663828 : if (TREE_CODE (decl) == USING_DECL)
4291 : /* Avoid debug info for class-scope USING_DECLS for now, we'll
4292 : call cp_emit_debug_info_for_using later. */
4293 3093511 : DECL_IGNORED_P (decl) = 1;
4294 :
4295 : /* Check for bare parameter packs in the non-static data member
4296 : declaration. */
4297 416663828 : if (TREE_CODE (decl) == FIELD_DECL)
4298 : {
4299 31165466 : if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
4300 9 : TREE_TYPE (decl) = error_mark_node;
4301 31165466 : if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
4302 0 : DECL_ATTRIBUTES (decl) = NULL_TREE;
4303 : }
4304 :
4305 : /* [dcl.link]
4306 :
4307 : A C language linkage is ignored for the names of class members
4308 : and the member function type of class member functions. */
4309 416663828 : if (DECL_LANG_SPECIFIC (decl))
4310 380077049 : SET_DECL_LANGUAGE (decl, lang_cplusplus);
4311 :
4312 416663828 : bool add = false;
4313 :
4314 : /* Functions and non-functions are added differently. */
4315 416663828 : if (DECL_DECLARES_FUNCTION_P (decl))
4316 212168449 : add = add_method (current_class_type, decl, false);
4317 : /* Enter the DECL into the scope of the class, if the class
4318 : isn't a closure (whose fields are supposed to be unnamed). */
4319 204495379 : else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
4320 199876506 : || maybe_push_used_methods (decl)
4321 402637772 : || pushdecl_class_level (decl))
4322 : add = true;
4323 :
4324 212168449 : if (add)
4325 : {
4326 : /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
4327 : go at the beginning. The reason is that
4328 : legacy_nonfn_member_lookup searches the list in order, and we
4329 : want a field name to override a type name so that the "struct
4330 : stat hack" will work. In particular:
4331 :
4332 : struct S { enum E { }; static const int E = 5; int ary[S::E]; } s;
4333 :
4334 : is valid. */
4335 :
4336 416654483 : if (TREE_CODE (decl) == TYPE_DECL)
4337 146563701 : TYPE_FIELDS (current_class_type)
4338 293127402 : = chainon (TYPE_FIELDS (current_class_type), decl);
4339 : else
4340 : {
4341 270090782 : DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
4342 270090782 : TYPE_FIELDS (current_class_type) = decl;
4343 : }
4344 :
4345 416654483 : maybe_add_class_template_decl_list (current_class_type, decl,
4346 : /*friend_p=*/0);
4347 : }
4348 : }
4349 :
4350 : /* Finish processing a complete template declaration. The PARMS are
4351 : the template parameters. */
4352 :
4353 : void
4354 87496121 : finish_template_decl (tree parms)
4355 : {
4356 87496121 : if (parms)
4357 87496112 : end_template_decl ();
4358 : else
4359 9 : end_specialization ();
4360 87496121 : }
4361 :
4362 : // Returns the template type of the class scope being entered. If we're
4363 : // entering a constrained class scope. TYPE is the class template
4364 : // scope being entered and we may need to match the intended type with
4365 : // a constrained specialization. For example:
4366 : //
4367 : // template<Object T>
4368 : // struct S { void f(); }; #1
4369 : //
4370 : // template<Object T>
4371 : // void S<T>::f() { } #2
4372 : //
4373 : // We check, in #2, that S<T> refers precisely to the type declared by
4374 : // #1 (i.e., that the constraints match). Note that the following should
4375 : // be an error since there is no specialization of S<T> that is
4376 : // unconstrained, but this is not diagnosed here.
4377 : //
4378 : // template<typename T>
4379 : // void S<T>::f() { }
4380 : //
4381 : // We cannot diagnose this problem here since this function also matches
4382 : // qualified template names that are not part of a definition. For example:
4383 : //
4384 : // template<Integral T, Floating_point U>
4385 : // typename pair<T, U>::first_type void f(T, U);
4386 : //
4387 : // Here, it is unlikely that there is a partial specialization of
4388 : // pair constrained for Integral and Floating_point arguments.
4389 : //
4390 : // The general rule is: if a constrained specialization with matching
4391 : // constraints is found return that type. Also note that if TYPE is not a
4392 : // class-type (e.g. a typename type), then no fixup is needed.
4393 :
4394 : static tree
4395 17307896 : fixup_template_type (tree type)
4396 : {
4397 : // Find the template parameter list at the a depth appropriate to
4398 : // the scope we're trying to enter.
4399 17307896 : tree parms = current_template_parms;
4400 17307896 : int depth = template_class_depth (type);
4401 38585009 : for (int n = current_template_depth; n > depth && parms; --n)
4402 3969217 : parms = TREE_CHAIN (parms);
4403 17307896 : if (!parms)
4404 : return type;
4405 17307886 : tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms);
4406 17307886 : tree cur_constr = build_constraints (cur_reqs, NULL_TREE);
4407 :
4408 : // Search for a specialization whose type and constraints match.
4409 17307886 : tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
4410 17307886 : tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
4411 33684464 : while (specs)
4412 : {
4413 16782397 : tree spec_constr = get_constraints (TREE_VALUE (specs));
4414 :
4415 : // If the type and constraints match a specialization, then we
4416 : // are entering that type.
4417 16782397 : if (same_type_p (type, TREE_TYPE (specs))
4418 16782397 : && equivalent_constraints (cur_constr, spec_constr))
4419 405819 : return TREE_TYPE (specs);
4420 16376578 : specs = TREE_CHAIN (specs);
4421 : }
4422 :
4423 : // If no specialization matches, then must return the type
4424 : // previously found.
4425 : return type;
4426 : }
4427 :
4428 : /* Finish processing a template-id (which names a type) of the form
4429 : NAME < ARGS >. Return the TYPE_DECL for the type named by the
4430 : template-id. If ENTERING_SCOPE is nonzero we are about to enter
4431 : the scope of template-id indicated. */
4432 :
4433 : tree
4434 178511758 : finish_template_type (tree name, tree args, int entering_scope)
4435 : {
4436 178511758 : tree type;
4437 :
4438 178511758 : type = lookup_template_class (name, args,
4439 : NULL_TREE, NULL_TREE,
4440 : tf_warning_or_error | tf_user);
4441 178511755 : if (entering_scope)
4442 18294075 : type = adjust_type_for_entering_scope (type);
4443 :
4444 : /* If we might be entering the scope of a partial specialization,
4445 : find the one with the right constraints. */
4446 178511755 : if (flag_concepts
4447 175888681 : && entering_scope
4448 17945017 : && CLASS_TYPE_P (type)
4449 17789398 : && CLASSTYPE_TEMPLATE_INFO (type)
4450 17789389 : && dependent_type_p (type)
4451 195819651 : && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
4452 17307896 : type = fixup_template_type (type);
4453 :
4454 178511755 : if (type == error_mark_node)
4455 : return type;
4456 178509491 : else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
4457 141493021 : return TYPE_STUB_DECL (type);
4458 : else
4459 37016470 : return TYPE_NAME (type);
4460 : }
4461 :
4462 : /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER
4463 : and ANNOTATIONS.
4464 : Return a TREE_LIST containing the ACCESS_SPECIFIER (or if there are
4465 : ANNOTATIONS, TREE_LIST containing the ACCESS_SPECIFIER and ANNOTATIONS)
4466 : and the BASE_CLASS, or NULL_TREE if an error occurred. The
4467 : ACCESS_SPECIFIER is one of
4468 : access_{default,public,protected,private}_node. For a virtual base
4469 : we set TREE_TYPE. */
4470 :
4471 : tree
4472 10835716 : finish_base_specifier (tree base, tree access, bool virtual_p,
4473 : tree annotations)
4474 : {
4475 10835716 : tree result;
4476 :
4477 10835716 : if (base == error_mark_node)
4478 : {
4479 0 : error ("invalid base-class specification");
4480 0 : result = NULL_TREE;
4481 : }
4482 10835716 : else if (! MAYBE_CLASS_TYPE_P (base))
4483 : {
4484 3 : error ("%qT is not a class type", base);
4485 3 : result = NULL_TREE;
4486 : }
4487 : else
4488 : {
4489 10835713 : if (cp_type_quals (base) != 0)
4490 : {
4491 : /* DR 484: Can a base-specifier name a cv-qualified
4492 : class type? */
4493 12 : base = TYPE_MAIN_VARIANT (base);
4494 : }
4495 10835713 : if (annotations)
4496 9 : access = build_tree_list (access, nreverse (annotations));
4497 10835713 : result = build_tree_list (access, base);
4498 10835713 : if (virtual_p)
4499 24940 : TREE_TYPE (result) = integer_type_node;
4500 : }
4501 :
4502 10835716 : return result;
4503 : }
4504 :
4505 : /* If FNS is a member function, a set of member functions, or a
4506 : template-id referring to one or more member functions, return a
4507 : BASELINK for FNS, incorporating the current access context.
4508 : Otherwise, return FNS unchanged. */
4509 :
4510 : tree
4511 228030433 : baselink_for_fns (tree fns)
4512 : {
4513 228030433 : tree scope;
4514 228030433 : tree cl;
4515 :
4516 228030433 : if (BASELINK_P (fns)
4517 228030433 : || error_operand_p (fns))
4518 : return fns;
4519 :
4520 213451379 : scope = ovl_scope (fns);
4521 213451379 : if (!CLASS_TYPE_P (scope))
4522 : return fns;
4523 :
4524 8204881 : cl = currently_open_derived_class (scope);
4525 8204881 : if (!cl)
4526 5981484 : cl = scope;
4527 8204881 : tree access_path = TYPE_BINFO (cl);
4528 8204881 : tree conv_path = (cl == scope ? access_path
4529 660870 : : lookup_base (cl, scope, ba_any, NULL, tf_none));
4530 8204881 : return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE);
4531 : }
4532 :
4533 : /* Returns true iff we are currently parsing a lambda-declarator. */
4534 :
4535 : bool
4536 2214419008 : parsing_lambda_declarator ()
4537 : {
4538 2214419008 : cp_binding_level *b = current_binding_level;
4539 2216294968 : while (b->kind == sk_template_parms || b->kind == sk_function_parms)
4540 1875960 : b = b->level_chain;
4541 2214419008 : return b->kind == sk_lambda;
4542 : }
4543 :
4544 : /* Returns true iff DECL is a variable from a function outside
4545 : the current one. */
4546 :
4547 : static bool
4548 2916539410 : outer_var_p (tree decl)
4549 : {
4550 : /* These should have been stripped or otherwise handled by the caller. */
4551 2916539410 : gcc_checking_assert (!REFERENCE_REF_P (decl));
4552 :
4553 1849125077 : return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
4554 2711903072 : && DECL_FUNCTION_SCOPE_P (decl)
4555 : /* Don't get confused by temporaries. */
4556 2247810760 : && DECL_NAME (decl)
4557 5140292991 : && (DECL_CONTEXT (decl) != current_function_decl
4558 2212517505 : || parsing_nsdmi ()
4559 : /* Also consider captures as outer vars if we are in
4560 : decltype in a lambda declarator as in:
4561 : auto l = [j=0]() -> decltype((j)) { ... }
4562 : for the sake of finish_decltype_type.
4563 :
4564 : (Similar issue also affects non-lambdas, but vexing parse
4565 : makes it more difficult to handle than lambdas.) */
4566 2212516562 : || parsing_lambda_declarator ()));
4567 : }
4568 :
4569 : /* As above, but also checks that DECL is automatic. */
4570 :
4571 : bool
4572 2916539410 : outer_automatic_var_p (tree decl)
4573 : {
4574 2916539410 : return (outer_var_p (decl)
4575 2916539410 : && !TREE_STATIC (decl));
4576 : }
4577 :
4578 : /* DECL satisfies outer_automatic_var_p. Possibly complain about it or
4579 : rewrite it for lambda capture.
4580 :
4581 : If ODR_USE is true, we're being called from mark_use, and we complain about
4582 : use of constant variables. If ODR_USE is false, we're being called for the
4583 : id-expression, and we do lambda capture. */
4584 :
4585 : tree
4586 5364334 : process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use)
4587 : {
4588 5364334 : if (cp_unevaluated_operand)
4589 : {
4590 3461717 : tree type = TREE_TYPE (decl);
4591 3461717 : if (!dependent_type_p (type)
4592 3461717 : && variably_modified_type_p (type, NULL_TREE))
4593 : /* VLAs are used even in unevaluated context. */;
4594 : else
4595 : /* It's not a use (3.2) if we're in an unevaluated context. */
4596 3461711 : return decl;
4597 : }
4598 1902623 : if (decl == error_mark_node)
4599 : return decl;
4600 :
4601 1902617 : tree context = DECL_CONTEXT (decl);
4602 1902617 : tree containing_function = current_function_decl;
4603 1902617 : tree lambda_stack = NULL_TREE;
4604 1902617 : tree lambda_expr = NULL_TREE;
4605 1902617 : tree initializer = convert_from_reference (decl);
4606 1902617 : tree var = strip_normal_capture_proxy (decl);
4607 :
4608 : /* Mark it as used now even if the use is ill-formed. */
4609 1902617 : if (!mark_used (decl, complain))
4610 3 : return error_mark_node;
4611 :
4612 1902614 : if (parsing_nsdmi () || parsing_lambda_declarator ())
4613 : containing_function = NULL_TREE;
4614 :
4615 3804531 : if (containing_function && LAMBDA_FUNCTION_P (containing_function))
4616 : {
4617 : /* Check whether we've already built a proxy. */
4618 1902178 : tree d = retrieve_local_specialization (var);
4619 :
4620 1902178 : if (d && d != decl && is_capture_proxy (d))
4621 : {
4622 976669 : if (DECL_CONTEXT (d) == containing_function)
4623 : /* We already have an inner proxy. */
4624 : return d;
4625 : else
4626 : /* We need to capture an outer proxy. */
4627 2347 : return process_outer_var_ref (d, complain, odr_use);
4628 : }
4629 : }
4630 :
4631 : /* If we are in a lambda function, we can move out until we hit
4632 : 1. the context,
4633 : 2. a non-lambda function, or
4634 : 3. a non-default capturing lambda function. */
4635 1854415 : while (context != containing_function
4636 : /* containing_function can be null with invalid generic lambdas. */
4637 1854415 : && containing_function
4638 2783554 : && LAMBDA_FUNCTION_P (containing_function))
4639 : {
4640 929139 : tree closure = DECL_CONTEXT (containing_function);
4641 929139 : lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure);
4642 :
4643 929139 : if (TYPE_CLASS_SCOPE_P (closure))
4644 : /* A lambda in an NSDMI (c++/64496). */
4645 : break;
4646 :
4647 929136 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4648 : break;
4649 :
4650 928470 : lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack);
4651 :
4652 928470 : containing_function = decl_function_context (containing_function);
4653 : }
4654 :
4655 : /* In a lambda within a template, wait until instantiation time to implicitly
4656 : capture a parameter pack. We want to wait because we don't know if we're
4657 : capturing the whole pack or a single element, and it's OK to wait because
4658 : find_parameter_packs_r walks into the lambda body. */
4659 925945 : if (context == containing_function
4660 925945 : && DECL_PACK_P (decl))
4661 : return decl;
4662 :
4663 885491 : if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
4664 : {
4665 6 : if (complain & tf_error)
4666 6 : error ("cannot capture member %qD of anonymous union", decl);
4667 6 : return error_mark_node;
4668 : }
4669 : /* Do lambda capture when processing the id-expression, not when
4670 : odr-using a variable. */
4671 885485 : if (!odr_use && context == containing_function)
4672 1768760 : decl = add_default_capture (lambda_stack,
4673 884380 : /*id=*/DECL_NAME (decl), initializer);
4674 : /* Only an odr-use of an outer automatic variable causes an
4675 : error, and a constant variable can decay to a prvalue
4676 : constant without odr-use. So don't complain yet. */
4677 1105 : else if (!odr_use && decl_constant_var_p (var))
4678 : return var;
4679 308 : else if (lambda_expr)
4680 : {
4681 45 : if (complain & tf_error)
4682 : {
4683 43 : auto_diagnostic_group d;
4684 43 : error ("%qD is not captured", decl);
4685 43 : tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
4686 43 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4687 40 : inform (location_of (closure),
4688 : "the lambda has no capture-default");
4689 3 : else if (TYPE_CLASS_SCOPE_P (closure))
4690 3 : inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot "
4691 : "capture variables from the enclosing context",
4692 3 : TYPE_CONTEXT (closure));
4693 43 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4694 43 : }
4695 45 : return error_mark_node;
4696 : }
4697 263 : else if (processing_contract_condition && (TREE_CODE (decl) == PARM_DECL))
4698 : /* Use of a parameter in a contract condition is fine. */
4699 : return decl;
4700 : else
4701 : {
4702 46 : if (complain & tf_error)
4703 : {
4704 39 : auto_diagnostic_group d;
4705 57 : error (VAR_P (decl)
4706 : ? G_("use of local variable with automatic storage from "
4707 : "containing function")
4708 : : G_("use of parameter from containing function"));
4709 39 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4710 39 : }
4711 46 : return error_mark_node;
4712 : }
4713 884380 : return decl;
4714 : }
4715 :
4716 : /* ID_EXPRESSION is a representation of parsed, but unprocessed,
4717 : id-expression. (See cp_parser_id_expression for details.) SCOPE,
4718 : if non-NULL, is the type or namespace used to explicitly qualify
4719 : ID_EXPRESSION. DECL is the entity to which that name has been
4720 : resolved.
4721 :
4722 : *CONSTANT_EXPRESSION_P is true if we are presently parsing a
4723 : constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
4724 : be set to true if this expression isn't permitted in a
4725 : constant-expression, but it is otherwise not set by this function.
4726 : *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
4727 : constant-expression, but a non-constant expression is also
4728 : permissible.
4729 :
4730 : DONE is true if this expression is a complete postfix-expression;
4731 : it is false if this expression is followed by '->', '[', '(', etc.
4732 : ADDRESS_P is true iff this expression is the operand of '&'.
4733 : TEMPLATE_P is true iff the qualified-id was of the form
4734 : "A::template B". TEMPLATE_ARG_P is true iff this qualified name
4735 : appears as a template argument.
4736 :
4737 : If an error occurs, and it is the kind of error that might cause
4738 : the parser to abort a tentative parse, *ERROR_MSG is filled in. It
4739 : is the caller's responsibility to issue the message. *ERROR_MSG
4740 : will be a string with static storage duration, so the caller need
4741 : not "free" it.
4742 :
4743 : Return an expression for the entity, after issuing appropriate
4744 : diagnostics. This function is also responsible for transforming a
4745 : reference to a non-static member into a COMPONENT_REF that makes
4746 : the use of "this" explicit.
4747 :
4748 : Upon return, *IDK will be filled in appropriately. */
4749 : static cp_expr
4750 743637825 : finish_id_expression_1 (tree id_expression,
4751 : tree decl,
4752 : tree scope,
4753 : cp_id_kind *idk,
4754 : bool integral_constant_expression_p,
4755 : bool allow_non_integral_constant_expression_p,
4756 : bool *non_integral_constant_expression_p,
4757 : bool template_p,
4758 : bool done,
4759 : bool address_p,
4760 : bool template_arg_p,
4761 : const char **error_msg,
4762 : location_t location)
4763 : {
4764 743637825 : decl = strip_using_decl (decl);
4765 :
4766 : /* Initialize the output parameters. */
4767 743637825 : *idk = CP_ID_KIND_NONE;
4768 743637825 : *error_msg = NULL;
4769 :
4770 743637825 : if (id_expression == error_mark_node)
4771 12 : return error_mark_node;
4772 : /* If we have a template-id, then no further lookup is
4773 : required. If the template-id was for a template-class, we
4774 : will sometimes have a TYPE_DECL at this point. */
4775 743637813 : else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4776 693351947 : || TREE_CODE (decl) == TYPE_DECL)
4777 : ;
4778 : /* Look up the name. */
4779 : else
4780 : {
4781 693351050 : if (decl == error_mark_node)
4782 : {
4783 : /* Name lookup failed. */
4784 120660 : if (scope
4785 370 : && !dependent_namespace_p (scope)
4786 121030 : && (!TYPE_P (scope)
4787 116 : || (!dependentish_scope_p (scope)
4788 112 : && !(identifier_p (id_expression)
4789 97 : && IDENTIFIER_CONV_OP_P (id_expression)
4790 3 : && dependent_type_p (TREE_TYPE (id_expression))))))
4791 : {
4792 : /* If the qualifying type is non-dependent (and the name
4793 : does not name a conversion operator to a dependent
4794 : type), issue an error. */
4795 360 : qualified_name_lookup_error (scope, id_expression, decl, location);
4796 360 : return error_mark_node;
4797 : }
4798 120300 : else if (!scope)
4799 : {
4800 : /* It may be resolved via Koenig lookup. */
4801 120290 : *idk = CP_ID_KIND_UNQUALIFIED;
4802 120290 : return id_expression;
4803 : }
4804 : else
4805 : decl = id_expression;
4806 : }
4807 :
4808 : /* Remember that the name was used in the definition of
4809 : the current class so that we can check later to see if
4810 : the meaning would have been different after the class
4811 : was entirely defined. */
4812 693230390 : if (!scope && decl != error_mark_node && identifier_p (id_expression))
4813 620177312 : maybe_note_name_used_in_class (id_expression, decl);
4814 :
4815 : /* A use in unevaluated operand might not be instantiated appropriately
4816 : if tsubst_copy builds a dummy parm, or if we never instantiate a
4817 : generic lambda, so mark it now. */
4818 693230400 : if (processing_template_decl
4819 693230400 : && (cp_unevaluated_operand
4820 599616758 : || generic_lambda_fn_p (current_function_decl)))
4821 18669301 : mark_type_use (decl);
4822 :
4823 : /* Disallow uses of local variables from containing functions, except
4824 : within lambda-expressions. */
4825 693230400 : if (outer_automatic_var_p (decl))
4826 : {
4827 3389615 : decl = process_outer_var_ref (decl, tf_warning_or_error);
4828 3389615 : if (decl == error_mark_node)
4829 85 : return error_mark_node;
4830 : }
4831 :
4832 : /* Also disallow uses of function parameters outside the function
4833 : body, except inside an unevaluated context (i.e. decltype). */
4834 693230315 : if (TREE_CODE (decl) == PARM_DECL
4835 288990911 : && DECL_CONTEXT (decl) == NULL_TREE
4836 7717400 : && !CONSTRAINT_VAR_P (decl)
4837 4177068 : && !cp_unevaluated_operand
4838 374 : && !processing_contract_condition
4839 693230359 : && !processing_omp_trait_property_expr)
4840 : {
4841 26 : *error_msg = G_("use of parameter outside function body");
4842 26 : return error_mark_node;
4843 : }
4844 : }
4845 :
4846 : /* If we didn't find anything, or what we found was a type,
4847 : then this wasn't really an id-expression. */
4848 743517052 : if (TREE_CODE (decl) == TEMPLATE_DECL
4849 743517052 : && !DECL_FUNCTION_TEMPLATE_P (decl))
4850 : {
4851 51 : *error_msg = G_("missing template arguments");
4852 51 : return error_mark_node;
4853 : }
4854 743517001 : else if (TREE_CODE (decl) == TYPE_DECL
4855 743516104 : || TREE_CODE (decl) == NAMESPACE_DECL)
4856 : {
4857 912 : *error_msg = G_("expected primary-expression");
4858 912 : return error_mark_node;
4859 : }
4860 :
4861 : /* If the name resolved to a template parameter, there is no
4862 : need to look it up again later. */
4863 31437767 : if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
4864 756811161 : || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4865 : {
4866 18142695 : tree r;
4867 :
4868 18142695 : *idk = CP_ID_KIND_NONE;
4869 18142695 : if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4870 0 : decl = TEMPLATE_PARM_DECL (decl);
4871 18142695 : r = DECL_INITIAL (decl);
4872 18142695 : if (CLASS_TYPE_P (TREE_TYPE (r)) && !CP_TYPE_CONST_P (TREE_TYPE (r)))
4873 : {
4874 : /* If the entity is a template parameter object for a template
4875 : parameter of type T, the type of the expression is const T. */
4876 1085 : tree ctype = TREE_TYPE (r);
4877 1085 : ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
4878 : | TYPE_QUAL_CONST));
4879 1085 : r = build1 (VIEW_CONVERT_EXPR, ctype, r);
4880 : }
4881 18142695 : r = convert_from_reference (r);
4882 18142695 : if (integral_constant_expression_p
4883 3146226 : && !dependent_type_p (TREE_TYPE (decl))
4884 20815258 : && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
4885 : {
4886 480 : if (!allow_non_integral_constant_expression_p)
4887 6 : error ("template parameter %qD of type %qT is not allowed in "
4888 : "an integral constant expression because it is not of "
4889 6 : "integral or enumeration type", decl, TREE_TYPE (decl));
4890 480 : *non_integral_constant_expression_p = true;
4891 : }
4892 :
4893 18142695 : if (flag_contracts && processing_contract_condition)
4894 9 : r = constify_contract_access (r);
4895 :
4896 18142695 : return r;
4897 : }
4898 725373394 : else if (TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE)
4899 : {
4900 9 : gcc_checking_assert (scope);
4901 9 : *idk = CP_ID_KIND_QUALIFIED;
4902 9 : cp_warn_deprecated_use_scopes (scope);
4903 9 : decl = finish_qualified_id_expr (scope, decl, done, address_p,
4904 : template_p, template_arg_p,
4905 : tf_warning_or_error);
4906 : }
4907 : else
4908 : {
4909 725373385 : if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4910 50285866 : && variable_template_p (TREE_OPERAND (decl, 0))
4911 736725377 : && !concept_check_p (decl))
4912 : /* Try resolving this variable TEMPLATE_ID_EXPR (which is always
4913 : considered type-dependent) now, so that the dependence test that
4914 : follows gives us the right answer: if it represents a non-dependent
4915 : variable template-id then finish_template_variable will yield the
4916 : corresponding non-dependent VAR_DECL. */
4917 11351992 : decl = finish_template_variable (decl);
4918 :
4919 725373385 : bool dependent_p = type_dependent_expression_p (decl);
4920 :
4921 : /* If the declaration was explicitly qualified indicate
4922 : that. The semantics of `A::f(3)' are different than
4923 : `f(3)' if `f' is virtual. */
4924 1450746770 : *idk = (scope
4925 725373385 : ? CP_ID_KIND_QUALIFIED
4926 631664170 : : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4927 631664170 : ? CP_ID_KIND_TEMPLATE_ID
4928 : : (dependent_p
4929 602300662 : ? CP_ID_KIND_UNQUALIFIED_DEPENDENT
4930 : : CP_ID_KIND_UNQUALIFIED)));
4931 :
4932 725373385 : if (dependent_p
4933 725373385 : && !scope
4934 415141691 : && DECL_P (decl)
4935 1111754220 : && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
4936 : /* Dependent type attributes on the decl mean that the TREE_TYPE is
4937 : wrong, so just return the identifier. */
4938 39 : return id_expression;
4939 :
4940 725373346 : if (DECL_CLASS_TEMPLATE_P (decl))
4941 : {
4942 0 : error ("use of class template %qT as expression", decl);
4943 0 : return error_mark_node;
4944 : }
4945 :
4946 725373346 : if (TREE_CODE (decl) == TREE_LIST)
4947 : {
4948 : /* Ambiguous reference to base members. */
4949 0 : auto_diagnostic_group d;
4950 0 : error ("request for member %qD is ambiguous in "
4951 : "multiple inheritance lattice", id_expression);
4952 0 : print_candidates (input_location, decl);
4953 0 : return error_mark_node;
4954 0 : }
4955 :
4956 : /* Mark variable-like entities as used. Functions are similarly
4957 : marked either below or after overload resolution. */
4958 725373346 : if ((VAR_P (decl)
4959 525437848 : || TREE_CODE (decl) == PARM_DECL
4960 236446969 : || TREE_CODE (decl) == CONST_DECL
4961 223151897 : || TREE_CODE (decl) == RESULT_DECL)
4962 1027659297 : && !mark_used (decl))
4963 12 : return error_mark_node;
4964 :
4965 : /* Only certain kinds of names are allowed in constant
4966 : expression. Template parameters have already
4967 : been handled above. */
4968 725373331 : if (! error_operand_p (decl)
4969 725373030 : && !dependent_p
4970 725373030 : && integral_constant_expression_p
4971 73470336 : && !decl_constant_var_p (decl)
4972 59921677 : && TREE_CODE (decl) != CONST_DECL
4973 51793174 : && !builtin_valid_in_constant_expr_p (decl)
4974 777119064 : && !concept_check_p (decl))
4975 : {
4976 51244365 : if (!allow_non_integral_constant_expression_p)
4977 : {
4978 30 : error ("%qD cannot appear in a constant-expression", decl);
4979 30 : return error_mark_node;
4980 : }
4981 51244335 : *non_integral_constant_expression_p = true;
4982 : }
4983 :
4984 725373301 : if (tree wrap = maybe_get_tls_wrapper_call (decl))
4985 : /* Replace an evaluated use of the thread_local variable with
4986 : a call to its wrapper. */
4987 : decl = wrap;
4988 725372789 : else if (concept_check_p (decl))
4989 : {
4990 : /* Nothing more to do. All of the analysis for concept checks
4991 : is done by build_conept_id, called from the parser. */
4992 : }
4993 710048816 : else if (scope)
4994 : {
4995 91978023 : if (TREE_CODE (decl) == SCOPE_REF)
4996 : {
4997 72243 : gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0)));
4998 72243 : decl = TREE_OPERAND (decl, 1);
4999 : }
5000 :
5001 91978023 : decl = (adjust_result_of_qualified_name_lookup
5002 91978023 : (decl, scope, current_nonlambda_class_type()));
5003 :
5004 91978023 : cp_warn_deprecated_use_scopes (scope);
5005 :
5006 91978023 : if (TYPE_P (scope))
5007 13184982 : decl = finish_qualified_id_expr (scope,
5008 : decl,
5009 : done,
5010 : address_p,
5011 : template_p,
5012 : template_arg_p,
5013 : tf_warning_or_error);
5014 : else
5015 78793041 : decl = convert_from_reference (decl);
5016 : }
5017 618070793 : else if (TREE_CODE (decl) == FIELD_DECL)
5018 : {
5019 64838031 : if (flag_contracts && processing_contract_condition
5020 22 : && contract_class_ptr == current_class_ptr)
5021 : {
5022 4 : error ("%qD 'this' required when accessing a member within a "
5023 : "constructor precondition or destructor postcondition "
5024 : "contract check", decl);
5025 4 : return error_mark_node;
5026 : }
5027 : /* Since SCOPE is NULL here, this is an unqualified name.
5028 : Access checking has been performed during name lookup
5029 : already. Turn off checking to avoid duplicate errors. */
5030 64838027 : push_deferring_access_checks (dk_no_check);
5031 64838027 : decl = finish_non_static_data_member (decl, NULL_TREE,
5032 : /*qualifying_scope=*/NULL_TREE);
5033 64838027 : pop_deferring_access_checks ();
5034 : }
5035 553232762 : else if (is_overloaded_fn (decl))
5036 : {
5037 : /* We only need to look at the first function,
5038 : because all the fns share the attribute we're
5039 : concerned with (all member fns or all non-members). */
5040 58983212 : tree first_fn = get_first_fn (decl);
5041 58983212 : first_fn = STRIP_TEMPLATE (first_fn);
5042 :
5043 58983212 : if (!template_arg_p
5044 58983212 : && (TREE_CODE (first_fn) == USING_DECL
5045 58981364 : || (TREE_CODE (first_fn) == FUNCTION_DECL
5046 58981364 : && DECL_FUNCTION_MEMBER_P (first_fn)
5047 35756340 : && !shared_member_p (decl))))
5048 : {
5049 : /* A set of member functions. */
5050 27667198 : if (flag_contracts && processing_contract_condition
5051 16 : && contract_class_ptr == current_class_ptr)
5052 : {
5053 2 : error ("%qD 'this' required when accessing a member within a "
5054 : "constructor precondition or destructor postcondition "
5055 : "contract check", decl);
5056 2 : return error_mark_node;
5057 : }
5058 27667196 : decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
5059 27667196 : return finish_class_member_access_expr (decl, id_expression,
5060 : /*template_p=*/false,
5061 27667196 : tf_warning_or_error);
5062 : }
5063 :
5064 31316014 : decl = baselink_for_fns (decl);
5065 : }
5066 : else
5067 : {
5068 483769914 : if (DECL_P (decl) && DECL_NONLOCAL (decl)
5069 495699224 : && DECL_CLASS_SCOPE_P (decl))
5070 : {
5071 1449674 : tree context = context_for_name_lookup (decl);
5072 1449674 : if (context != current_class_type)
5073 : {
5074 762985 : tree path = currently_open_derived_class (context);
5075 762985 : if (!path)
5076 : /* PATH can be null for using an enum of an unrelated
5077 : class; we checked its access in lookup_using_decl.
5078 :
5079 : ??? Should this case make a clone instead, like
5080 : handle_using_decl? */
5081 23 : gcc_assert (TREE_CODE (decl) == CONST_DECL
5082 : /* This is for:
5083 : constexpr auto r = ^^S::i;
5084 : auto a = [:r:]; */
5085 : || flag_reflection);
5086 : else
5087 762962 : perform_or_defer_access_check (TYPE_BINFO (path),
5088 : decl, decl,
5089 : tf_warning_or_error);
5090 : }
5091 : }
5092 :
5093 494249550 : decl = convert_from_reference (decl);
5094 : }
5095 : }
5096 :
5097 697706108 : check_param_in_postcondition (decl, location);
5098 697706108 : if (flag_contracts && processing_contract_condition)
5099 1303 : decl = constify_contract_access (decl);
5100 :
5101 697706108 : return cp_expr (decl, location);
5102 : }
5103 :
5104 : /* As per finish_id_expression_1, but adding a wrapper node
5105 : around the result if needed to express LOCATION. */
5106 :
5107 : cp_expr
5108 743637825 : finish_id_expression (tree id_expression,
5109 : tree decl,
5110 : tree scope,
5111 : cp_id_kind *idk,
5112 : bool integral_constant_expression_p,
5113 : bool allow_non_integral_constant_expression_p,
5114 : bool *non_integral_constant_expression_p,
5115 : bool template_p,
5116 : bool done,
5117 : bool address_p,
5118 : bool template_arg_p,
5119 : const char **error_msg,
5120 : location_t location)
5121 : {
5122 743637825 : cp_expr result
5123 743637825 : = finish_id_expression_1 (id_expression, decl, scope, idk,
5124 : integral_constant_expression_p,
5125 : allow_non_integral_constant_expression_p,
5126 : non_integral_constant_expression_p,
5127 : template_p, done, address_p, template_arg_p,
5128 : error_msg, location);
5129 743637822 : return result.maybe_add_location_wrapper ();
5130 : }
5131 :
5132 : /* Implement the __typeof keyword: Return the type of EXPR, suitable for
5133 : use as a type-specifier. */
5134 :
5135 : tree
5136 20951879 : finish_typeof (tree expr)
5137 : {
5138 20951879 : tree type;
5139 :
5140 20951879 : if (type_dependent_expression_p (expr))
5141 : {
5142 20861638 : type = cxx_make_type (TYPEOF_TYPE);
5143 20861638 : TYPEOF_TYPE_EXPR (type) = expr;
5144 20861638 : SET_TYPE_STRUCTURAL_EQUALITY (type);
5145 :
5146 20861638 : return type;
5147 : }
5148 :
5149 90241 : expr = mark_type_use (expr);
5150 :
5151 90241 : type = unlowered_expr_type (expr);
5152 :
5153 90241 : if (!type || type == unknown_type_node)
5154 : {
5155 3 : error ("type of %qE is unknown", expr);
5156 3 : return error_mark_node;
5157 : }
5158 :
5159 : return type;
5160 : }
5161 :
5162 : /* Implement the __underlying_type keyword: Return the underlying
5163 : type of TYPE, suitable for use as a type-specifier. */
5164 :
5165 : tree
5166 46327 : finish_underlying_type (tree type)
5167 : {
5168 46327 : if (!complete_type_or_else (type, NULL_TREE))
5169 3 : return error_mark_node;
5170 :
5171 46324 : if (TREE_CODE (type) != ENUMERAL_TYPE)
5172 : {
5173 24 : error ("%qT is not an enumeration type", type);
5174 24 : return error_mark_node;
5175 : }
5176 :
5177 46300 : tree underlying_type = ENUM_UNDERLYING_TYPE (type);
5178 :
5179 : /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
5180 : includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
5181 : See finish_enum_value_list for details. */
5182 46300 : if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
5183 54 : underlying_type
5184 54 : = c_common_type_for_mode (TYPE_MODE (underlying_type),
5185 54 : TYPE_UNSIGNED (underlying_type));
5186 :
5187 : return underlying_type;
5188 : }
5189 :
5190 : /* Implement the __type_pack_element keyword: Return the type
5191 : at index IDX within TYPES. */
5192 :
5193 : static tree
5194 116763 : finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
5195 : {
5196 116763 : idx = maybe_constant_value (idx, NULL_TREE, mce_true);
5197 116763 : if (!INTEGRAL_TYPE_P (TREE_TYPE (idx)))
5198 : {
5199 6 : if (complain & tf_error)
5200 3 : error ("pack index has non-integral type %qT", TREE_TYPE (idx));
5201 6 : return error_mark_node;
5202 : }
5203 116757 : if (TREE_CODE (idx) != INTEGER_CST)
5204 : {
5205 1 : if (complain & tf_error)
5206 : {
5207 1 : error ("pack index is not an integral constant");
5208 1 : cxx_constant_value (idx);
5209 : }
5210 1 : return error_mark_node;
5211 : }
5212 116756 : if (tree_int_cst_sgn (idx) < 0)
5213 : {
5214 5 : if (complain & tf_error)
5215 5 : error ("pack index %qE is negative", idx);
5216 5 : return error_mark_node;
5217 : }
5218 116751 : if (wi::to_widest (idx) >= TREE_VEC_LENGTH (types))
5219 : {
5220 28 : if (complain & tf_error)
5221 22 : error ("pack index %qE is out of range for pack of length %qd",
5222 22 : idx, TREE_VEC_LENGTH (types));
5223 28 : return error_mark_node;
5224 : }
5225 116723 : return TREE_VEC_ELT (types, tree_to_shwi (idx));
5226 : }
5227 :
5228 : /* In a pack-index T...[N], return the element at index IDX within TYPES.
5229 : PARENTHESIZED_P is true iff the pack index was wrapped in (). */
5230 :
5231 : tree
5232 10599 : pack_index_element (tree idx, tree types, bool parenthesized_p,
5233 : tsubst_flags_t complain)
5234 : {
5235 10599 : tree r = finish_type_pack_element (idx, types, complain);
5236 10599 : if (parenthesized_p)
5237 : /* For the benefit of decltype(auto). */
5238 22 : r = force_paren_expr (r);
5239 10599 : return r;
5240 : }
5241 :
5242 : /* Implement the __direct_bases keyword: Return the direct base classes
5243 : of type. */
5244 :
5245 : tree
5246 15 : calculate_direct_bases (tree type, tsubst_flags_t complain)
5247 : {
5248 15 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5249 15 : || !NON_UNION_CLASS_TYPE_P (type))
5250 8 : return make_tree_vec (0);
5251 :
5252 7 : releasing_vec vector;
5253 7 : vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
5254 7 : tree binfo;
5255 7 : unsigned i;
5256 :
5257 : /* Virtual bases are initialized first */
5258 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5259 13 : if (BINFO_VIRTUAL_P (binfo))
5260 2 : vec_safe_push (vector, binfo);
5261 :
5262 : /* Now non-virtuals */
5263 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5264 13 : if (!BINFO_VIRTUAL_P (binfo))
5265 11 : vec_safe_push (vector, binfo);
5266 :
5267 7 : tree bases_vec = make_tree_vec (vector->length ());
5268 :
5269 27 : for (i = 0; i < vector->length (); ++i)
5270 13 : TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
5271 :
5272 7 : return bases_vec;
5273 7 : }
5274 :
5275 : /* Implement the __bases keyword: Return the base classes
5276 : of type */
5277 :
5278 : /* Find morally non-virtual base classes by walking binfo hierarchy */
5279 : /* Virtual base classes are handled separately in finish_bases */
5280 :
5281 : static tree
5282 73 : dfs_calculate_bases_pre (tree binfo, void * /*data_*/)
5283 : {
5284 : /* Don't walk bases of virtual bases */
5285 73 : return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE;
5286 : }
5287 :
5288 : static tree
5289 73 : dfs_calculate_bases_post (tree binfo, void *data_)
5290 : {
5291 73 : vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
5292 73 : if (!BINFO_VIRTUAL_P (binfo))
5293 48 : vec_safe_push (*data, BINFO_TYPE (binfo));
5294 73 : return NULL_TREE;
5295 : }
5296 :
5297 : /* Calculates the morally non-virtual base classes of a class */
5298 : static vec<tree, va_gc> *
5299 16 : calculate_bases_helper (tree type)
5300 : {
5301 16 : vec<tree, va_gc> *vector = make_tree_vector ();
5302 :
5303 : /* Now add non-virtual base classes in order of construction */
5304 16 : if (TYPE_BINFO (type))
5305 16 : dfs_walk_all (TYPE_BINFO (type),
5306 : dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector);
5307 16 : return vector;
5308 : }
5309 :
5310 : tree
5311 12 : calculate_bases (tree type, tsubst_flags_t complain)
5312 : {
5313 12 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5314 12 : || !NON_UNION_CLASS_TYPE_P (type))
5315 5 : return make_tree_vec (0);
5316 :
5317 7 : releasing_vec vector;
5318 7 : tree bases_vec = NULL_TREE;
5319 7 : unsigned i;
5320 7 : vec<tree, va_gc> *vbases;
5321 7 : tree binfo;
5322 :
5323 : /* First go through virtual base classes */
5324 7 : for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
5325 16 : vec_safe_iterate (vbases, i, &binfo); i++)
5326 : {
5327 9 : releasing_vec vbase_bases
5328 9 : = calculate_bases_helper (BINFO_TYPE (binfo));
5329 9 : vec_safe_splice (vector, vbase_bases);
5330 9 : }
5331 :
5332 : /* Now for the non-virtual bases */
5333 7 : releasing_vec nonvbases = calculate_bases_helper (type);
5334 7 : vec_safe_splice (vector, nonvbases);
5335 :
5336 : /* Note that during error recovery vector->length can even be zero. */
5337 7 : if (vector->length () > 1)
5338 : {
5339 : /* Last element is entire class, so don't copy */
5340 6 : bases_vec = make_tree_vec (vector->length () - 1);
5341 :
5342 53 : for (i = 0; i < vector->length () - 1; ++i)
5343 41 : TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
5344 : }
5345 : else
5346 1 : bases_vec = make_tree_vec (0);
5347 :
5348 7 : return bases_vec;
5349 7 : }
5350 :
5351 : tree
5352 28 : finish_bases (tree type, bool direct)
5353 : {
5354 28 : tree bases = NULL_TREE;
5355 :
5356 28 : if (!processing_template_decl)
5357 : {
5358 : /* Parameter packs can only be used in templates */
5359 0 : error ("parameter pack %<__bases%> only valid in template declaration");
5360 0 : return error_mark_node;
5361 : }
5362 :
5363 28 : bases = cxx_make_type (BASES);
5364 28 : BASES_TYPE (bases) = type;
5365 28 : BASES_DIRECT (bases) = direct;
5366 28 : SET_TYPE_STRUCTURAL_EQUALITY (bases);
5367 :
5368 28 : return bases;
5369 : }
5370 :
5371 : /* Perform C++-specific checks for __builtin_offsetof before calling
5372 : fold_offsetof. */
5373 :
5374 : tree
5375 2400 : finish_offsetof (tree object_ptr, tree expr, location_t loc)
5376 : {
5377 : /* If we're processing a template, we can't finish the semantics yet.
5378 : Otherwise we can fold the entire expression now. */
5379 2400 : if (processing_template_decl)
5380 : {
5381 60 : expr = build2 (OFFSETOF_EXPR, size_type_node, expr, object_ptr);
5382 60 : SET_EXPR_LOCATION (expr, loc);
5383 60 : return expr;
5384 : }
5385 :
5386 2340 : if (expr == error_mark_node)
5387 : return error_mark_node;
5388 :
5389 2323 : if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
5390 : {
5391 6 : error ("cannot apply %<offsetof%> to destructor %<~%T%>",
5392 6 : TREE_OPERAND (expr, 2));
5393 6 : return error_mark_node;
5394 : }
5395 4619 : if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr))
5396 4619 : || TREE_TYPE (expr) == unknown_type_node)
5397 : {
5398 30 : while (TREE_CODE (expr) == COMPONENT_REF
5399 30 : || TREE_CODE (expr) == COMPOUND_EXPR)
5400 12 : expr = TREE_OPERAND (expr, 1);
5401 :
5402 18 : if (DECL_P (expr))
5403 : {
5404 0 : auto_diagnostic_group d;
5405 0 : error ("cannot apply %<offsetof%> to member function %qD", expr);
5406 0 : inform (DECL_SOURCE_LOCATION (expr), "declared here");
5407 0 : }
5408 : else
5409 18 : error ("cannot apply %<offsetof%> to member function");
5410 18 : return error_mark_node;
5411 : }
5412 2299 : if (TREE_CODE (expr) == CONST_DECL)
5413 : {
5414 3 : error ("cannot apply %<offsetof%> to an enumerator %qD", expr);
5415 3 : return error_mark_node;
5416 : }
5417 2296 : if (REFERENCE_REF_P (expr))
5418 9 : expr = TREE_OPERAND (expr, 0);
5419 2296 : if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr))
5420 3 : return error_mark_node;
5421 2293 : if (warn_invalid_offsetof
5422 2293 : && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
5423 2293 : && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
5424 2338 : && cp_unevaluated_operand == 0)
5425 45 : warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within "
5426 : "non-standard-layout type %qT is conditionally-supported",
5427 45 : TREE_TYPE (TREE_TYPE (object_ptr)));
5428 2293 : return fold_offsetof (expr);
5429 : }
5430 :
5431 : /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
5432 : function is broken out from the above for the benefit of the tree-ssa
5433 : project. */
5434 :
5435 : void
5436 336152 : simplify_aggr_init_expr (tree *tp)
5437 : {
5438 336152 : tree aggr_init_expr = *tp;
5439 :
5440 : /* Form an appropriate CALL_EXPR. */
5441 336152 : tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
5442 336152 : tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
5443 336152 : tree type = TREE_TYPE (slot);
5444 :
5445 336152 : tree call_expr;
5446 336152 : enum style_t { ctor, arg, pcc } style;
5447 :
5448 336152 : if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
5449 : style = ctor;
5450 : #ifdef PCC_STATIC_STRUCT_RETURN
5451 : else if (1)
5452 : style = pcc;
5453 : #endif
5454 : else
5455 : {
5456 88845 : gcc_assert (TREE_ADDRESSABLE (type));
5457 : style = arg;
5458 : }
5459 :
5460 336152 : call_expr = build_call_array_loc (input_location,
5461 336152 : TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
5462 : fn,
5463 336152 : aggr_init_expr_nargs (aggr_init_expr),
5464 336152 : AGGR_INIT_EXPR_ARGP (aggr_init_expr));
5465 336152 : TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
5466 336152 : CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr);
5467 336152 : CALL_EXPR_OPERATOR_SYNTAX (call_expr)
5468 336152 : = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
5469 336152 : CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
5470 336152 : CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
5471 336152 : CALL_EXPR_MUST_TAIL_CALL (call_expr) = AGGR_INIT_EXPR_MUST_TAIL (aggr_init_expr);
5472 :
5473 336152 : if (style == ctor)
5474 : {
5475 : /* Replace the first argument to the ctor with the address of the
5476 : slot. */
5477 247307 : cxx_mark_addressable (slot);
5478 247307 : CALL_EXPR_ARG (call_expr, 0) =
5479 247307 : build1 (ADDR_EXPR, build_pointer_type (type), slot);
5480 : }
5481 88845 : else if (style == arg)
5482 : {
5483 : /* Just mark it addressable here, and leave the rest to
5484 : expand_call{,_inline}. */
5485 88845 : cxx_mark_addressable (slot);
5486 88845 : CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
5487 88845 : call_expr = cp_build_init_expr (slot, call_expr);
5488 : }
5489 : else if (style == pcc)
5490 : {
5491 : /* If we're using the non-reentrant PCC calling convention, then we
5492 : need to copy the returned value out of the static buffer into the
5493 : SLOT. */
5494 : push_deferring_access_checks (dk_no_check);
5495 : call_expr = build_aggr_init (slot, call_expr,
5496 : DIRECT_BIND | LOOKUP_ONLYCONVERTING,
5497 : tf_warning_or_error);
5498 : pop_deferring_access_checks ();
5499 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
5500 : }
5501 :
5502 336152 : if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
5503 : {
5504 3356 : tree init = build_zero_init (type, NULL_TREE,
5505 : /*static_storage_p=*/false);
5506 3356 : init = cp_build_init_expr (slot, init);
5507 3356 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
5508 : init, call_expr);
5509 : }
5510 :
5511 336152 : *tp = call_expr;
5512 336152 : }
5513 :
5514 : /* Emit all thunks to FN that should be emitted when FN is emitted. */
5515 :
5516 : void
5517 64955978 : emit_associated_thunks (tree fn)
5518 : {
5519 : /* When we use vcall offsets, we emit thunks with the virtual
5520 : functions to which they thunk. The whole point of vcall offsets
5521 : is so that you can know statically the entire set of thunks that
5522 : will ever be needed for a given virtual function, thereby
5523 : enabling you to output all the thunks with the function itself. */
5524 64955978 : if (DECL_VIRTUAL_P (fn)
5525 : /* Do not emit thunks for extern template instantiations. */
5526 1288064 : && ! DECL_REALLY_EXTERN (fn)
5527 : /* Do not emit thunks for tentative decls, those will be processed
5528 : again at_eof if really needed. */
5529 66079104 : && (DECL_INTERFACE_KNOWN (fn) || !DECL_DEFER_OUTPUT (fn)))
5530 : {
5531 1122449 : tree thunk;
5532 :
5533 2249106 : for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
5534 : {
5535 4208 : if (!THUNK_ALIAS (thunk))
5536 : {
5537 4208 : use_thunk (thunk, /*emit_p=*/1);
5538 4208 : if (DECL_RESULT_THUNK_P (thunk))
5539 : {
5540 178 : tree probe;
5541 :
5542 178 : for (probe = DECL_THUNKS (thunk);
5543 327 : probe; probe = DECL_CHAIN (probe))
5544 149 : use_thunk (probe, /*emit_p=*/1);
5545 : }
5546 : }
5547 : else
5548 0 : gcc_assert (!DECL_THUNKS (thunk));
5549 : }
5550 : }
5551 64955978 : }
5552 :
5553 : /* Generate RTL for FN. */
5554 :
5555 : bool
5556 164303230 : expand_or_defer_fn_1 (tree fn)
5557 : {
5558 : /* When the parser calls us after finishing the body of a template
5559 : function, we don't really want to expand the body. */
5560 164303230 : if (processing_template_decl)
5561 : {
5562 : /* Normally, collection only occurs in rest_of_compilation. So,
5563 : if we don't collect here, we never collect junk generated
5564 : during the processing of templates until we hit a
5565 : non-template function. It's not safe to do this inside a
5566 : nested class, though, as the parser may have local state that
5567 : is not a GC root. */
5568 90733978 : if (!function_depth)
5569 90307312 : ggc_collect ();
5570 90733978 : return false;
5571 : }
5572 :
5573 73569252 : gcc_assert (DECL_SAVED_TREE (fn));
5574 :
5575 : /* We make a decision about linkage for these functions at the end
5576 : of the compilation. Until that point, we do not want the back
5577 : end to output them -- but we do want it to see the bodies of
5578 : these functions so that it can inline them as appropriate. */
5579 73569252 : if (DECL_DECLARED_INLINE_P (fn)
5580 2033812 : || DECL_IMPLICIT_INSTANTIATION (fn)
5581 73825323 : || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
5582 : {
5583 73313208 : if (DECL_INTERFACE_KNOWN (fn))
5584 : /* We've already made a decision as to how this function will
5585 : be handled. */;
5586 52315298 : else if (!at_eof
5587 23358465 : || DECL_IMMEDIATE_FUNCTION_P (fn)
5588 74761731 : || DECL_OMP_DECLARE_REDUCTION_P (fn))
5589 29868865 : tentative_decl_linkage (fn);
5590 : else
5591 22446433 : import_export_decl (fn);
5592 :
5593 : /* If the user wants us to keep all inline functions, then mark
5594 : this function as needed so that finish_file will make sure to
5595 : output it later. Similarly, all dllexport'd functions must
5596 : be emitted; there may be callers in other DLLs. */
5597 73313208 : if (DECL_DECLARED_INLINE_P (fn)
5598 71535440 : && !DECL_REALLY_EXTERN (fn)
5599 68967564 : && !DECL_IMMEDIATE_FUNCTION_P (fn)
5600 67539190 : && !DECL_OMP_DECLARE_REDUCTION_P (fn)
5601 140852398 : && (flag_keep_inline_functions
5602 67536298 : || (flag_keep_inline_dllexport
5603 67536298 : && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))))
5604 : {
5605 2892 : mark_needed (fn);
5606 2892 : DECL_EXTERNAL (fn) = 0;
5607 : }
5608 : }
5609 :
5610 : /* If this is a constructor or destructor body, we have to clone
5611 : it. */
5612 73569252 : if (maybe_clone_body (fn))
5613 : {
5614 : /* We don't want to process FN again, so pretend we've written
5615 : it out, even though we haven't. */
5616 8585130 : TREE_ASM_WRITTEN (fn) = 1;
5617 : /* If this is a constexpr function we still need the body to be
5618 : able to evaluate it. Similarly, with modules we only stream
5619 : the maybe-in-charge cdtor and regenerate the clones from it on
5620 : demand, so we also need to keep the body. Otherwise we don't
5621 : need it anymore. */
5622 8585130 : if (!maybe_constexpr_fn (fn)
5623 8585130 : && !(module_maybe_has_cmi_p () && vague_linkage_p (fn)))
5624 3751198 : DECL_SAVED_TREE (fn) = void_node;
5625 8585130 : return false;
5626 : }
5627 :
5628 : /* There's no reason to do any of the work here if we're only doing
5629 : semantic analysis; this code just generates RTL. */
5630 64984122 : if (flag_syntax_only)
5631 : {
5632 : /* Pretend that this function has been written out so that we don't try
5633 : to expand it again. */
5634 28128 : TREE_ASM_WRITTEN (fn) = 1;
5635 28128 : return false;
5636 : }
5637 :
5638 64955994 : if (DECL_OMP_DECLARE_REDUCTION_P (fn))
5639 : return false;
5640 :
5641 : return true;
5642 : }
5643 :
5644 : void
5645 155736523 : expand_or_defer_fn (tree fn)
5646 : {
5647 155736523 : if (expand_or_defer_fn_1 (fn))
5648 : {
5649 56391762 : function_depth++;
5650 :
5651 : /* Expand or defer, at the whim of the compilation unit manager. */
5652 56391762 : cgraph_node::finalize_function (fn, function_depth > 1);
5653 56391762 : emit_associated_thunks (fn);
5654 :
5655 56391762 : function_depth--;
5656 :
5657 112783524 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
5658 : {
5659 1370383 : if (cgraph_node *node = cgraph_node::get (fn))
5660 : {
5661 1370383 : node->body_removed = true;
5662 1370383 : node->analyzed = false;
5663 1370383 : node->definition = false;
5664 1370383 : node->force_output = false;
5665 : }
5666 : }
5667 : }
5668 155736523 : }
5669 :
5670 504682 : class nrv_data
5671 : {
5672 : public:
5673 252341 : nrv_data () : visited (37) {}
5674 :
5675 : tree var;
5676 : tree result;
5677 : hash_set<tree> visited;
5678 : bool simple;
5679 : bool in_nrv_cleanup;
5680 : };
5681 :
5682 : /* Helper function for walk_tree, used by finalize_nrv below. */
5683 :
5684 : static tree
5685 26935920 : finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
5686 : {
5687 26935920 : class nrv_data *dp = (class nrv_data *)data;
5688 :
5689 : /* No need to walk into types. There wouldn't be any need to walk into
5690 : non-statements, except that we have to consider STMT_EXPRs. */
5691 26935920 : if (TYPE_P (*tp))
5692 200743 : *walk_subtrees = 0;
5693 :
5694 : /* Replace all uses of the NRV with the RESULT_DECL. */
5695 26735177 : else if (*tp == dp->var)
5696 573932 : *tp = dp->result;
5697 :
5698 : /* Avoid walking into the same tree more than once. Unfortunately, we
5699 : can't just use walk_tree_without duplicates because it would only call
5700 : us for the first occurrence of dp->var in the function body. */
5701 26161245 : else if (dp->visited.add (*tp))
5702 5763507 : *walk_subtrees = 0;
5703 :
5704 : /* If there's a label, we might need to destroy the NRV on goto (92407). */
5705 20397738 : else if (TREE_CODE (*tp) == LABEL_EXPR && !dp->in_nrv_cleanup)
5706 3 : dp->simple = false;
5707 : /* Change NRV returns to just refer to the RESULT_DECL; this is a nop,
5708 : but differs from using NULL_TREE in that it indicates that we care
5709 : about the value of the RESULT_DECL. But preserve anything appended
5710 : by check_return_expr. */
5711 20397735 : else if (TREE_CODE (*tp) == RETURN_EXPR)
5712 : {
5713 290268 : tree *p = &TREE_OPERAND (*tp, 0);
5714 750553 : while (TREE_CODE (*p) == COMPOUND_EXPR)
5715 170017 : p = &TREE_OPERAND (*p, 0);
5716 290268 : if (TREE_CODE (*p) == INIT_EXPR
5717 290268 : && INIT_EXPR_NRV_P (*p))
5718 289888 : *p = dp->result;
5719 : }
5720 : /* Change all cleanups for the NRV to only run when not returning. */
5721 20107467 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5722 20107467 : && CLEANUP_DECL (*tp) == dp->var)
5723 : {
5724 133025 : dp->in_nrv_cleanup = true;
5725 133025 : cp_walk_tree (&CLEANUP_BODY (*tp), finalize_nrv_r, data, 0);
5726 133025 : dp->in_nrv_cleanup = false;
5727 133025 : cp_walk_tree (&CLEANUP_EXPR (*tp), finalize_nrv_r, data, 0);
5728 133025 : *walk_subtrees = 0;
5729 :
5730 133025 : if (dp->simple)
5731 : /* For a simple NRV, just run it on the EH path. */
5732 132409 : CLEANUP_EH_ONLY (*tp) = true;
5733 : else
5734 : {
5735 : /* Not simple, we need to check current_retval_sentinel to decide
5736 : whether to run it. If it's set, we're returning normally and
5737 : don't want to destroy the NRV. If the sentinel is not set, we're
5738 : leaving scope some other way, either by flowing off the end of its
5739 : scope or throwing an exception. */
5740 1848 : tree cond = build3 (COND_EXPR, void_type_node,
5741 616 : current_retval_sentinel,
5742 616 : void_node, CLEANUP_EXPR (*tp));
5743 616 : CLEANUP_EXPR (*tp) = cond;
5744 : }
5745 :
5746 : /* If a cleanup might throw, we need to clear current_retval_sentinel on
5747 : the exception path, both so the check above succeeds and so an outer
5748 : cleanup added by maybe_splice_retval_cleanup doesn't run. */
5749 133025 : if (cp_function_chain->throwing_cleanup)
5750 : {
5751 168 : tree clear = build2 (MODIFY_EXPR, boolean_type_node,
5752 : current_retval_sentinel,
5753 : boolean_false_node);
5754 168 : if (dp->simple)
5755 : {
5756 : /* We're already only on the EH path, just prepend it. */
5757 158 : tree &exp = CLEANUP_EXPR (*tp);
5758 158 : exp = build2 (COMPOUND_EXPR, void_type_node, clear, exp);
5759 : }
5760 : else
5761 : {
5762 : /* The cleanup runs on both normal and EH paths, we need another
5763 : CLEANUP_STMT to clear the flag only on the EH path. */
5764 10 : tree &bod = CLEANUP_BODY (*tp);
5765 10 : bod = build_stmt (EXPR_LOCATION (*tp), CLEANUP_STMT,
5766 10 : bod, clear, current_retval_sentinel);
5767 10 : CLEANUP_EH_ONLY (bod) = true;
5768 : }
5769 : }
5770 : }
5771 : /* Disable maybe_splice_retval_cleanup within the NRV cleanup scope, we don't
5772 : want to destroy the retval before the variable goes out of scope. */
5773 19974442 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5774 20770 : && dp->in_nrv_cleanup
5775 19994108 : && CLEANUP_DECL (*tp) == dp->result)
5776 6 : CLEANUP_EXPR (*tp) = void_node;
5777 : /* Replace the DECL_EXPR for the NRV with an initialization of the
5778 : RESULT_DECL, if needed. */
5779 19974436 : else if (TREE_CODE (*tp) == DECL_EXPR
5780 19974436 : && DECL_EXPR_DECL (*tp) == dp->var)
5781 : {
5782 252343 : tree init;
5783 252343 : if (DECL_INITIAL (dp->var)
5784 252343 : && DECL_INITIAL (dp->var) != error_mark_node)
5785 94551 : init = cp_build_init_expr (dp->result,
5786 94551 : DECL_INITIAL (dp->var));
5787 : else
5788 157792 : init = build_empty_stmt (EXPR_LOCATION (*tp));
5789 252343 : DECL_INITIAL (dp->var) = NULL_TREE;
5790 252343 : SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
5791 252343 : *tp = init;
5792 : }
5793 :
5794 : /* Keep iterating. */
5795 26935920 : return NULL_TREE;
5796 : }
5797 :
5798 : /* Called from finish_function to implement the named return value
5799 : optimization by overriding all the RETURN_EXPRs and pertinent
5800 : CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
5801 : RESULT_DECL for the function. */
5802 :
5803 : void
5804 252341 : finalize_nrv (tree fndecl, tree var)
5805 : {
5806 252341 : class nrv_data data;
5807 252341 : tree result = DECL_RESULT (fndecl);
5808 :
5809 : /* Copy name from VAR to RESULT. */
5810 252341 : DECL_NAME (result) = DECL_NAME (var);
5811 : /* Don't forget that we take its address. */
5812 252341 : TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
5813 : /* Finally set DECL_VALUE_EXPR to avoid assigning
5814 : a stack slot at -O0 for the original var and debug info
5815 : uses RESULT location for VAR. */
5816 252341 : SET_DECL_VALUE_EXPR (var, result);
5817 252341 : DECL_HAS_VALUE_EXPR_P (var) = 1;
5818 :
5819 252341 : data.var = var;
5820 252341 : data.result = result;
5821 252341 : data.in_nrv_cleanup = false;
5822 :
5823 : /* This is simpler for variables declared in the outer scope of
5824 : the function so we know that their lifetime always ends with a
5825 : return; see g++.dg/opt/nrv6.C. */
5826 252341 : tree outer = outer_curly_brace_block (fndecl);
5827 252341 : data.simple = chain_member (var, BLOCK_VARS (outer));
5828 :
5829 252341 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), finalize_nrv_r, &data, 0);
5830 252341 : }
5831 :
5832 : /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */
5833 :
5834 : bool
5835 2239 : cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
5836 : bool need_copy_ctor, bool need_copy_assignment,
5837 : bool need_dtor)
5838 : {
5839 2239 : int save_errorcount = errorcount;
5840 2239 : tree info, t;
5841 :
5842 : /* Always allocate 3 elements for simplicity. These are the
5843 : function decls for the ctor, dtor, and assignment op.
5844 : This layout is known to the three lang hooks,
5845 : cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
5846 : and cxx_omp_clause_assign_op. */
5847 2239 : info = make_tree_vec (3);
5848 2239 : CP_OMP_CLAUSE_INFO (c) = info;
5849 :
5850 2239 : if (need_default_ctor || need_copy_ctor)
5851 : {
5852 1654 : if (need_default_ctor)
5853 1255 : t = get_default_ctor (type);
5854 : else
5855 399 : t = get_copy_ctor (type, tf_warning_or_error);
5856 :
5857 1654 : if (t && !trivial_fn_p (t))
5858 1400 : TREE_VEC_ELT (info, 0) = t;
5859 : }
5860 :
5861 2239 : if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
5862 1632 : TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error);
5863 :
5864 2239 : if (need_copy_assignment)
5865 : {
5866 397 : t = get_copy_assign (type);
5867 :
5868 397 : if (t && !trivial_fn_p (t))
5869 344 : TREE_VEC_ELT (info, 2) = t;
5870 : }
5871 :
5872 2239 : return errorcount != save_errorcount;
5873 : }
5874 :
5875 : /* If DECL is DECL_OMP_PRIVATIZED_MEMBER, return corresponding
5876 : FIELD_DECL, otherwise return DECL itself. */
5877 :
5878 : static tree
5879 26243 : omp_clause_decl_field (tree decl)
5880 : {
5881 26243 : if (VAR_P (decl)
5882 18396 : && DECL_HAS_VALUE_EXPR_P (decl)
5883 359 : && DECL_ARTIFICIAL (decl)
5884 359 : && DECL_LANG_SPECIFIC (decl)
5885 26578 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
5886 : {
5887 328 : tree f = DECL_VALUE_EXPR (decl);
5888 328 : if (INDIRECT_REF_P (f))
5889 0 : f = TREE_OPERAND (f, 0);
5890 328 : if (TREE_CODE (f) == COMPONENT_REF)
5891 : {
5892 328 : f = TREE_OPERAND (f, 1);
5893 328 : gcc_assert (TREE_CODE (f) == FIELD_DECL);
5894 : return f;
5895 : }
5896 : }
5897 : return NULL_TREE;
5898 : }
5899 :
5900 : /* Adjust DECL if needed for printing using %qE. */
5901 :
5902 : static tree
5903 187 : omp_clause_printable_decl (tree decl)
5904 : {
5905 0 : tree t = omp_clause_decl_field (decl);
5906 187 : if (t)
5907 45 : return t;
5908 : return decl;
5909 : }
5910 :
5911 : /* For a FIELD_DECL F and corresponding DECL_OMP_PRIVATIZED_MEMBER
5912 : VAR_DECL T that doesn't need a DECL_EXPR added, record it for
5913 : privatization. */
5914 :
5915 : static void
5916 219 : omp_note_field_privatization (tree f, tree t)
5917 : {
5918 219 : if (!omp_private_member_map)
5919 71 : omp_private_member_map = new hash_map<tree, tree>;
5920 219 : tree &v = omp_private_member_map->get_or_insert (f);
5921 219 : if (v == NULL_TREE)
5922 : {
5923 146 : v = t;
5924 146 : omp_private_member_vec.safe_push (f);
5925 : /* Signal that we don't want to create DECL_EXPR for this dummy var. */
5926 146 : omp_private_member_vec.safe_push (integer_zero_node);
5927 : }
5928 219 : }
5929 :
5930 : /* Privatize FIELD_DECL T, return corresponding DECL_OMP_PRIVATIZED_MEMBER
5931 : dummy VAR_DECL. */
5932 :
5933 : tree
5934 861 : omp_privatize_field (tree t, bool shared)
5935 : {
5936 861 : tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
5937 861 : if (m == error_mark_node)
5938 : return error_mark_node;
5939 861 : if (!omp_private_member_map && !shared)
5940 365 : omp_private_member_map = new hash_map<tree, tree>;
5941 861 : if (TYPE_REF_P (TREE_TYPE (t)))
5942 : {
5943 123 : gcc_assert (INDIRECT_REF_P (m));
5944 123 : m = TREE_OPERAND (m, 0);
5945 : }
5946 861 : tree vb = NULL_TREE;
5947 861 : tree &v = shared ? vb : omp_private_member_map->get_or_insert (t);
5948 861 : if (v == NULL_TREE)
5949 : {
5950 770 : v = create_temporary_var (TREE_TYPE (m));
5951 770 : retrofit_lang_decl (v);
5952 770 : DECL_OMP_PRIVATIZED_MEMBER (v) = 1;
5953 770 : SET_DECL_VALUE_EXPR (v, m);
5954 770 : DECL_HAS_VALUE_EXPR_P (v) = 1;
5955 770 : if (!shared)
5956 690 : omp_private_member_vec.safe_push (t);
5957 : }
5958 861 : return v;
5959 : }
5960 :
5961 : /* C++ specialisation of the c_omp_address_inspector class. */
5962 :
5963 : class cp_omp_address_inspector : public c_omp_address_inspector
5964 : {
5965 : public:
5966 30566 : cp_omp_address_inspector (location_t loc, tree t)
5967 30566 : : c_omp_address_inspector (loc, t)
5968 : {
5969 : }
5970 :
5971 30566 : ~cp_omp_address_inspector ()
5972 : {
5973 22265 : }
5974 :
5975 129620 : bool processing_template_decl_p ()
5976 : {
5977 129620 : return processing_template_decl;
5978 : }
5979 :
5980 0 : void emit_unmappable_type_notes (tree t)
5981 : {
5982 0 : if (TREE_TYPE (t) != error_mark_node
5983 0 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
5984 0 : cxx_incomplete_type_inform (TREE_TYPE (t));
5985 0 : }
5986 :
5987 1058 : tree convert_from_reference (tree x)
5988 : {
5989 1058 : return ::convert_from_reference (x);
5990 : }
5991 :
5992 141 : tree build_array_ref (location_t loc, tree arr, tree idx)
5993 : {
5994 141 : return ::build_array_ref (loc, arr, idx);
5995 : }
5996 :
5997 22207 : bool check_clause (tree clause)
5998 : {
5999 22207 : if (TREE_CODE (orig) == COMPONENT_REF
6000 22207 : && invalid_nonstatic_memfn_p (EXPR_LOCATION (orig), orig,
6001 : tf_warning_or_error))
6002 : return false;
6003 22204 : if (!c_omp_address_inspector::check_clause (clause))
6004 : return false;
6005 : return true;
6006 : }
6007 : };
6008 :
6009 : /* Helper function for handle_omp_array_sections. Called recursively
6010 : to handle multiple array-section-subscripts. C is the clause,
6011 : T current expression (initially OMP_CLAUSE_DECL), which is either
6012 : a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound
6013 : expression if specified, TREE_VALUE length expression if specified,
6014 : TREE_CHAIN is what it has been specified after, or some decl.
6015 : TYPES vector is populated with array section types, MAYBE_ZERO_LEN
6016 : set to true if any of the array-section-subscript could have length
6017 : of zero (explicit or implicit), FIRST_NON_ONE is the index of the
6018 : first array-section-subscript which is known not to have length
6019 : of one. Given say:
6020 : map(a[:b][2:1][:c][:2][:d][e:f][2:5])
6021 : FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c]
6022 : all are or may have length of 1, array-section-subscript [:2] is the
6023 : first one known not to have length 1. For array-section-subscript
6024 : <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't
6025 : 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we
6026 : can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above
6027 : case though, as some lengths could be zero. */
6028 :
6029 : static tree
6030 20464 : handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
6031 : bool &maybe_zero_len, unsigned int &first_non_one,
6032 : enum c_omp_region_type ort)
6033 : {
6034 20464 : tree ret, low_bound, length, type;
6035 20464 : bool openacc = (ort & C_ORT_ACC) != 0;
6036 20464 : if (TREE_CODE (t) != OMP_ARRAY_SECTION)
6037 : {
6038 9274 : if (error_operand_p (t))
6039 6 : return error_mark_node;
6040 :
6041 9268 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6042 9268 : tree t_refto = ai.maybe_unconvert_ref (t);
6043 :
6044 9268 : if (!ai.check_clause (c))
6045 0 : return error_mark_node;
6046 9268 : else if (ai.component_access_p ()
6047 10656 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6048 64 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
6049 40 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
6050 1388 : t = ai.get_root_term (true);
6051 : else
6052 7880 : t = ai.unconverted_ref_origin ();
6053 9268 : if (t == error_mark_node)
6054 : return error_mark_node;
6055 9268 : ret = t_refto;
6056 9268 : if (TREE_CODE (t) == FIELD_DECL)
6057 33 : ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6058 9235 : else if (!VAR_P (t)
6059 2702 : && (openacc || !EXPR_P (t))
6060 2507 : && TREE_CODE (t) != PARM_DECL)
6061 : {
6062 48 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
6063 : return NULL_TREE;
6064 30 : if (DECL_P (t))
6065 30 : error_at (OMP_CLAUSE_LOCATION (c),
6066 : "%qD is not a variable in %qs clause", t,
6067 30 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6068 : else
6069 0 : error_at (OMP_CLAUSE_LOCATION (c),
6070 : "%qE is not a variable in %qs clause", t,
6071 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6072 30 : return error_mark_node;
6073 : }
6074 9187 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6075 8997 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6076 17256 : && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
6077 : {
6078 17 : error_at (OMP_CLAUSE_LOCATION (c),
6079 : "%qD is threadprivate variable in %qs clause", t,
6080 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6081 17 : return error_mark_node;
6082 : }
6083 9203 : if (type_dependent_expression_p (ret))
6084 : return NULL_TREE;
6085 8516 : ret = convert_from_reference (ret);
6086 8516 : return ret;
6087 9268 : }
6088 :
6089 11190 : if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
6090 7387 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6091 6193 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6092 4909 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6093 13796 : && TREE_CODE (TREE_OPERAND (t, 0)) == FIELD_DECL)
6094 43 : TREE_OPERAND (t, 0) = omp_privatize_field (TREE_OPERAND (t, 0), false);
6095 11190 : ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
6096 : maybe_zero_len, first_non_one, ort);
6097 11190 : if (ret == error_mark_node || ret == NULL_TREE)
6098 : return ret;
6099 :
6100 10186 : type = TREE_TYPE (ret);
6101 10186 : low_bound = TREE_OPERAND (t, 1);
6102 10186 : length = TREE_OPERAND (t, 2);
6103 8239 : if ((low_bound && type_dependent_expression_p (low_bound))
6104 18342 : || (length && type_dependent_expression_p (length)))
6105 88 : return NULL_TREE;
6106 :
6107 10098 : if (low_bound == error_mark_node || length == error_mark_node)
6108 : return error_mark_node;
6109 :
6110 10098 : if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound)))
6111 : {
6112 69 : error_at (OMP_CLAUSE_LOCATION (c),
6113 : "low bound %qE of array section does not have integral type",
6114 : low_bound);
6115 69 : return error_mark_node;
6116 : }
6117 10029 : if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length)))
6118 : {
6119 63 : error_at (OMP_CLAUSE_LOCATION (c),
6120 : "length %qE of array section does not have integral type",
6121 : length);
6122 63 : return error_mark_node;
6123 : }
6124 9966 : if (low_bound)
6125 8073 : low_bound = mark_rvalue_use (low_bound);
6126 9966 : if (length)
6127 9020 : length = mark_rvalue_use (length);
6128 : /* We need to reduce to real constant-values for checks below. */
6129 9020 : if (length)
6130 9020 : length = fold_simple (length);
6131 9966 : if (low_bound)
6132 8073 : low_bound = fold_simple (low_bound);
6133 8073 : if (low_bound
6134 8073 : && TREE_CODE (low_bound) == INTEGER_CST
6135 15221 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6136 7148 : > TYPE_PRECISION (sizetype))
6137 0 : low_bound = fold_convert (sizetype, low_bound);
6138 9966 : if (length
6139 9020 : && TREE_CODE (length) == INTEGER_CST
6140 16975 : && TYPE_PRECISION (TREE_TYPE (length))
6141 7009 : > TYPE_PRECISION (sizetype))
6142 0 : length = fold_convert (sizetype, length);
6143 9966 : if (low_bound == NULL_TREE)
6144 1893 : low_bound = integer_zero_node;
6145 :
6146 9966 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6147 9966 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
6148 5082 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
6149 : {
6150 60 : if (length != integer_one_node)
6151 : {
6152 36 : error_at (OMP_CLAUSE_LOCATION (c),
6153 : "expected single pointer in %qs clause",
6154 : user_omp_clause_code_name (c, openacc));
6155 36 : return error_mark_node;
6156 : }
6157 : }
6158 9930 : if (length != NULL_TREE)
6159 : {
6160 9008 : if (!integer_nonzerop (length))
6161 : {
6162 2058 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6163 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6164 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6165 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6166 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6167 : {
6168 459 : if (integer_zerop (length))
6169 : {
6170 28 : error_at (OMP_CLAUSE_LOCATION (c),
6171 : "zero length array section in %qs clause",
6172 28 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6173 28 : return error_mark_node;
6174 : }
6175 : }
6176 : else
6177 1599 : maybe_zero_len = true;
6178 : }
6179 8980 : if (first_non_one == types.length ()
6180 8980 : && (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
6181 3930 : first_non_one++;
6182 : }
6183 9902 : if (TREE_CODE (type) == ARRAY_TYPE)
6184 : {
6185 5461 : if (length == NULL_TREE
6186 5461 : && (TYPE_DOMAIN (type) == NULL_TREE
6187 850 : || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE))
6188 : {
6189 30 : error_at (OMP_CLAUSE_LOCATION (c),
6190 : "for unknown bound array type length expression must "
6191 : "be specified");
6192 30 : return error_mark_node;
6193 : }
6194 5431 : if (TREE_CODE (low_bound) == INTEGER_CST
6195 5431 : && tree_int_cst_sgn (low_bound) == -1)
6196 : {
6197 153 : error_at (OMP_CLAUSE_LOCATION (c),
6198 : "negative low bound in array section in %qs clause",
6199 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6200 153 : return error_mark_node;
6201 : }
6202 5278 : if (length != NULL_TREE
6203 4476 : && TREE_CODE (length) == INTEGER_CST
6204 8836 : && tree_int_cst_sgn (length) == -1)
6205 : {
6206 153 : error_at (OMP_CLAUSE_LOCATION (c),
6207 : "negative length in array section in %qs clause",
6208 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6209 153 : return error_mark_node;
6210 : }
6211 5125 : if (TYPE_DOMAIN (type)
6212 5031 : && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
6213 10156 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
6214 : == INTEGER_CST)
6215 : {
6216 4635 : tree size
6217 4635 : = fold_convert (sizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
6218 4635 : size = size_binop (PLUS_EXPR, size, size_one_node);
6219 4635 : if (TREE_CODE (low_bound) == INTEGER_CST)
6220 : {
6221 3868 : if (tree_int_cst_lt (size, low_bound))
6222 : {
6223 54 : error_at (OMP_CLAUSE_LOCATION (c),
6224 : "low bound %qE above array section size "
6225 : "in %qs clause", low_bound,
6226 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6227 54 : return error_mark_node;
6228 : }
6229 3814 : if (tree_int_cst_equal (size, low_bound))
6230 : {
6231 17 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6232 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6233 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6234 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6235 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6236 : {
6237 17 : error_at (OMP_CLAUSE_LOCATION (c),
6238 : "zero length array section in %qs clause",
6239 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6240 17 : return error_mark_node;
6241 : }
6242 0 : maybe_zero_len = true;
6243 : }
6244 3797 : else if (length == NULL_TREE
6245 1420 : && first_non_one == types.length ()
6246 4095 : && tree_int_cst_equal
6247 298 : (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
6248 : low_bound))
6249 195 : first_non_one++;
6250 : }
6251 767 : else if (length == NULL_TREE)
6252 : {
6253 20 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6254 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6255 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6256 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6257 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6258 13 : maybe_zero_len = true;
6259 40 : if (first_non_one == types.length ())
6260 17 : first_non_one++;
6261 : }
6262 4564 : if (length && TREE_CODE (length) == INTEGER_CST)
6263 : {
6264 3290 : if (tree_int_cst_lt (size, length))
6265 : {
6266 57 : error_at (OMP_CLAUSE_LOCATION (c),
6267 : "length %qE above array section size "
6268 : "in %qs clause", length,
6269 57 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6270 57 : return error_mark_node;
6271 : }
6272 3233 : if (TREE_CODE (low_bound) == INTEGER_CST)
6273 : {
6274 2899 : tree lbpluslen
6275 2899 : = size_binop (PLUS_EXPR,
6276 : fold_convert (sizetype, low_bound),
6277 : fold_convert (sizetype, length));
6278 2899 : if (TREE_CODE (lbpluslen) == INTEGER_CST
6279 2899 : && tree_int_cst_lt (size, lbpluslen))
6280 : {
6281 54 : error_at (OMP_CLAUSE_LOCATION (c),
6282 : "high bound %qE above array section size "
6283 : "in %qs clause", lbpluslen,
6284 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6285 54 : return error_mark_node;
6286 : }
6287 : }
6288 : }
6289 : }
6290 490 : else if (length == NULL_TREE)
6291 : {
6292 1 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6293 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6294 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6295 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6296 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6297 0 : maybe_zero_len = true;
6298 2 : if (first_non_one == types.length ())
6299 1 : first_non_one++;
6300 : }
6301 :
6302 : /* For [lb:] we will need to evaluate lb more than once. */
6303 3911 : if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6304 : {
6305 650 : tree lb = cp_save_expr (low_bound);
6306 650 : if (lb != low_bound)
6307 : {
6308 9 : TREE_OPERAND (t, 1) = lb;
6309 9 : low_bound = lb;
6310 : }
6311 : }
6312 : }
6313 4441 : else if (TYPE_PTR_P (type))
6314 : {
6315 4384 : if (length == NULL_TREE)
6316 : {
6317 42 : if (TREE_CODE (ret) == PARM_DECL && DECL_ARRAY_PARAMETER_P (ret))
6318 36 : error_at (OMP_CLAUSE_LOCATION (c),
6319 : "for array function parameter length expression "
6320 : "must be specified");
6321 : else
6322 6 : error_at (OMP_CLAUSE_LOCATION (c),
6323 : "for pointer type length expression must be specified");
6324 42 : return error_mark_node;
6325 : }
6326 4342 : if (length != NULL_TREE
6327 4342 : && TREE_CODE (length) == INTEGER_CST
6328 3249 : && tree_int_cst_sgn (length) == -1)
6329 : {
6330 84 : error_at (OMP_CLAUSE_LOCATION (c),
6331 : "negative length in array section in %qs clause",
6332 84 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6333 84 : return error_mark_node;
6334 : }
6335 : /* If there is a pointer type anywhere but in the very first
6336 : array-section-subscript, the array section could be non-contiguous. */
6337 4258 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6338 4216 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6339 7990 : && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION)
6340 : {
6341 : /* If any prior dimension has a non-one length, then deem this
6342 : array section as non-contiguous. */
6343 158 : for (tree d = TREE_OPERAND (t, 0); TREE_CODE (d) == OMP_ARRAY_SECTION;
6344 69 : d = TREE_OPERAND (d, 0))
6345 : {
6346 89 : tree d_length = TREE_OPERAND (d, 2);
6347 89 : if (d_length == NULL_TREE || !integer_onep (d_length))
6348 : {
6349 20 : error_at (OMP_CLAUSE_LOCATION (c),
6350 : "array section is not contiguous in %qs clause",
6351 20 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6352 20 : return error_mark_node;
6353 : }
6354 : }
6355 : }
6356 : }
6357 : else
6358 : {
6359 57 : error_at (OMP_CLAUSE_LOCATION (c),
6360 : "%qE does not have pointer or array type", ret);
6361 57 : return error_mark_node;
6362 : }
6363 9181 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6364 8277 : types.safe_push (TREE_TYPE (ret));
6365 : /* We will need to evaluate lb more than once. */
6366 9181 : tree lb = cp_save_expr (low_bound);
6367 9181 : if (lb != low_bound)
6368 : {
6369 716 : TREE_OPERAND (t, 1) = lb;
6370 716 : low_bound = lb;
6371 : }
6372 : /* Temporarily disable -fstrong-eval-order for array reductions.
6373 : The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects
6374 : is something the middle-end can't cope with and more importantly,
6375 : it needs to be the actual base variable that is privatized, not some
6376 : temporary assigned previous value of it. That, together with OpenMP
6377 : saying how many times the side-effects are evaluated is unspecified,
6378 : makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified. */
6379 9181 : warning_sentinel s (flag_strong_eval_order,
6380 9181 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6381 8168 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6382 18481 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION);
6383 9181 : ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, NULL,
6384 : tf_warning_or_error);
6385 9181 : return ret;
6386 9181 : }
6387 :
6388 : /* Handle array sections for clause C. */
6389 :
6390 : static bool
6391 9274 : handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
6392 : {
6393 9274 : bool maybe_zero_len = false;
6394 9274 : unsigned int first_non_one = 0;
6395 9274 : auto_vec<tree, 10> types;
6396 9274 : tree *tp = &OMP_CLAUSE_DECL (c);
6397 9274 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6398 8316 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6399 9480 : && OMP_ITERATOR_DECL_P (*tp))
6400 258 : tp = &TREE_VALUE (*tp);
6401 9274 : tree first = handle_omp_array_sections_1 (c, *tp, types,
6402 : maybe_zero_len, first_non_one,
6403 : ort);
6404 9274 : if (first == error_mark_node)
6405 : return true;
6406 8304 : if (first == NULL_TREE)
6407 : return false;
6408 7511 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6409 7511 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6410 : {
6411 850 : tree t = *tp;
6412 850 : tree tem = NULL_TREE;
6413 850 : if (processing_template_decl)
6414 : return false;
6415 : /* Need to evaluate side effects in the length expressions
6416 : if any. */
6417 751 : while (TREE_CODE (t) == TREE_LIST)
6418 : {
6419 0 : if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t)))
6420 : {
6421 0 : if (tem == NULL_TREE)
6422 : tem = TREE_VALUE (t);
6423 : else
6424 0 : tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem),
6425 0 : TREE_VALUE (t), tem);
6426 : }
6427 0 : t = TREE_CHAIN (t);
6428 : }
6429 751 : if (tem)
6430 0 : first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
6431 751 : *tp = first;
6432 : }
6433 : else
6434 : {
6435 6661 : unsigned int num = types.length (), i;
6436 6661 : tree t, side_effects = NULL_TREE, size = NULL_TREE;
6437 6661 : tree condition = NULL_TREE;
6438 :
6439 6661 : if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
6440 3 : maybe_zero_len = true;
6441 6661 : if (processing_template_decl && maybe_zero_len)
6442 : return false;
6443 :
6444 14012 : for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
6445 7429 : t = TREE_OPERAND (t, 0))
6446 : {
6447 7500 : gcc_assert (TREE_CODE (t) == OMP_ARRAY_SECTION);
6448 :
6449 7500 : tree low_bound = TREE_OPERAND (t, 1);
6450 7500 : tree length = TREE_OPERAND (t, 2);
6451 :
6452 7500 : i--;
6453 7500 : if (low_bound
6454 6117 : && TREE_CODE (low_bound) == INTEGER_CST
6455 13006 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6456 5506 : > TYPE_PRECISION (sizetype))
6457 0 : low_bound = fold_convert (sizetype, low_bound);
6458 7500 : if (length
6459 6981 : && TREE_CODE (length) == INTEGER_CST
6460 12589 : && TYPE_PRECISION (TREE_TYPE (length))
6461 5089 : > TYPE_PRECISION (sizetype))
6462 0 : length = fold_convert (sizetype, length);
6463 7500 : if (low_bound == NULL_TREE)
6464 1383 : low_bound = integer_zero_node;
6465 7500 : if (!maybe_zero_len && i > first_non_one)
6466 : {
6467 629 : if (integer_nonzerop (low_bound))
6468 34 : goto do_warn_noncontiguous;
6469 595 : if (length != NULL_TREE
6470 273 : && TREE_CODE (length) == INTEGER_CST
6471 273 : && TYPE_DOMAIN (types[i])
6472 273 : && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))
6473 868 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])))
6474 : == INTEGER_CST)
6475 : {
6476 273 : tree size;
6477 273 : size = size_binop (PLUS_EXPR,
6478 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6479 : size_one_node);
6480 273 : if (!tree_int_cst_equal (length, size))
6481 : {
6482 37 : do_warn_noncontiguous:
6483 142 : error_at (OMP_CLAUSE_LOCATION (c),
6484 : "array section is not contiguous in %qs "
6485 : "clause",
6486 71 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6487 71 : return true;
6488 : }
6489 : }
6490 558 : if (!processing_template_decl
6491 390 : && length != NULL_TREE
6492 723 : && TREE_SIDE_EFFECTS (length))
6493 : {
6494 0 : if (side_effects == NULL_TREE)
6495 : side_effects = length;
6496 : else
6497 0 : side_effects = build2 (COMPOUND_EXPR,
6498 0 : TREE_TYPE (side_effects),
6499 : length, side_effects);
6500 : }
6501 : }
6502 6871 : else if (processing_template_decl)
6503 698 : continue;
6504 : else
6505 : {
6506 6173 : tree l;
6507 :
6508 6173 : if (i > first_non_one
6509 6173 : && ((length && integer_nonzerop (length))
6510 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6511 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6512 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION))
6513 0 : continue;
6514 6173 : if (length)
6515 6056 : l = fold_convert (sizetype, length);
6516 : else
6517 : {
6518 117 : l = size_binop (PLUS_EXPR,
6519 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6520 : size_one_node);
6521 117 : l = size_binop (MINUS_EXPR, l,
6522 : fold_convert (sizetype, low_bound));
6523 : }
6524 6173 : if (i > first_non_one)
6525 : {
6526 0 : l = fold_build2 (NE_EXPR, boolean_type_node, l,
6527 : size_zero_node);
6528 0 : if (condition == NULL_TREE)
6529 : condition = l;
6530 : else
6531 0 : condition = fold_build2 (BIT_AND_EXPR, boolean_type_node,
6532 : l, condition);
6533 : }
6534 6173 : else if (size == NULL_TREE)
6535 : {
6536 5895 : size = size_in_bytes (TREE_TYPE (types[i]));
6537 5895 : tree eltype = TREE_TYPE (types[num - 1]);
6538 5964 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6539 69 : eltype = TREE_TYPE (eltype);
6540 5895 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6541 5145 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6542 10287 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6543 1599 : size = size_binop (EXACT_DIV_EXPR, size,
6544 : size_in_bytes (eltype));
6545 5895 : size = size_binop (MULT_EXPR, size, l);
6546 5895 : if (condition)
6547 0 : size = fold_build3 (COND_EXPR, sizetype, condition,
6548 : size, size_zero_node);
6549 : }
6550 : else
6551 278 : size = size_binop (MULT_EXPR, size, l);
6552 : }
6553 : }
6554 6512 : if (!processing_template_decl)
6555 : {
6556 5895 : if (side_effects)
6557 0 : size = build2 (COMPOUND_EXPR, sizetype, side_effects, size);
6558 5895 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6559 5145 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6560 10287 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6561 : {
6562 1599 : size = size_binop (MINUS_EXPR, size, size_one_node);
6563 1599 : size = save_expr (size);
6564 1599 : tree index_type = build_index_type (size);
6565 1599 : tree eltype = TREE_TYPE (first);
6566 1628 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6567 29 : eltype = TREE_TYPE (eltype);
6568 1599 : tree type = build_array_type (eltype, index_type);
6569 1599 : tree ptype = build_pointer_type (eltype);
6570 1599 : if (TYPE_REF_P (TREE_TYPE (t))
6571 1599 : && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
6572 152 : t = convert_from_reference (t);
6573 1447 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6574 629 : t = build_fold_addr_expr (t);
6575 1599 : tree t2 = build_fold_addr_expr (first);
6576 1599 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6577 : ptrdiff_type_node, t2);
6578 1599 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
6579 : ptrdiff_type_node, t2,
6580 1599 : fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6581 : ptrdiff_type_node, t));
6582 1599 : if (tree_fits_shwi_p (t2))
6583 1261 : t = build2 (MEM_REF, type, t,
6584 1261 : build_int_cst (ptype, tree_to_shwi (t2)));
6585 : else
6586 : {
6587 338 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6588 : sizetype, t2);
6589 338 : t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR,
6590 338 : TREE_TYPE (t), t, t2);
6591 338 : t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
6592 : }
6593 1599 : OMP_CLAUSE_DECL (c) = t;
6594 7494 : return false;
6595 : }
6596 4296 : OMP_CLAUSE_DECL (c) = first;
6597 4296 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
6598 : return false;
6599 4270 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
6600 4270 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
6601 3730 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
6602 3718 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH))
6603 4246 : OMP_CLAUSE_SIZE (c) = size;
6604 4270 : if (TREE_CODE (t) == FIELD_DECL)
6605 3 : t = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6606 :
6607 4270 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
6608 : return false;
6609 :
6610 3742 : if (TREE_CODE (first) == INDIRECT_REF)
6611 : {
6612 : /* Detect and skip adding extra nodes for pointer-to-member
6613 : mappings. These are unsupported for now. */
6614 2407 : tree tmp = TREE_OPERAND (first, 0);
6615 :
6616 2407 : if (TREE_CODE (tmp) == NON_LVALUE_EXPR)
6617 1911 : tmp = TREE_OPERAND (tmp, 0);
6618 :
6619 2407 : if (TREE_CODE (tmp) == INDIRECT_REF)
6620 158 : tmp = TREE_OPERAND (tmp, 0);
6621 :
6622 2407 : if (TREE_CODE (tmp) == POINTER_PLUS_EXPR)
6623 : {
6624 466 : tree offset = TREE_OPERAND (tmp, 1);
6625 466 : STRIP_NOPS (offset);
6626 466 : if (TYPE_PTRMEM_P (TREE_TYPE (offset)))
6627 : {
6628 36 : sorry_at (OMP_CLAUSE_LOCATION (c),
6629 : "pointer-to-member mapping %qE not supported",
6630 18 : OMP_CLAUSE_DECL (c));
6631 18 : return true;
6632 : }
6633 : }
6634 : }
6635 :
6636 : /* FIRST represents the first item of data that we are mapping.
6637 : E.g. if we're mapping an array, FIRST might resemble
6638 : "foo.bar.myarray[0]". */
6639 :
6640 3724 : auto_vec<omp_addr_token *, 10> addr_tokens;
6641 :
6642 3724 : if (!omp_parse_expr (addr_tokens, first))
6643 : return true;
6644 :
6645 3724 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6646 :
6647 3724 : tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
6648 3724 : if (nc != error_mark_node)
6649 : {
6650 3724 : using namespace omp_addr_tokenizer;
6651 :
6652 3724 : if (ai.maybe_zero_length_array_section (c))
6653 3700 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
6654 :
6655 : /* !!! If we're accessing a base decl via chained access
6656 : methods (e.g. multiple indirections), duplicate clause
6657 : detection won't work properly. Skip it in that case. */
6658 3724 : if ((addr_tokens[0]->type == STRUCTURE_BASE
6659 2707 : || addr_tokens[0]->type == ARRAY_BASE)
6660 3724 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
6661 3713 : && addr_tokens[1]->type == ACCESS_METHOD
6662 7437 : && omp_access_chain_p (addr_tokens, 1))
6663 216 : c = nc;
6664 :
6665 3724 : return false;
6666 : }
6667 7448 : }
6668 : }
6669 : return false;
6670 9274 : }
6671 :
6672 : /* Return identifier to look up for omp declare reduction. */
6673 :
6674 : tree
6675 7085 : omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type)
6676 : {
6677 7085 : const char *p = NULL;
6678 7085 : const char *m = NULL;
6679 7085 : switch (reduction_code)
6680 : {
6681 4188 : case PLUS_EXPR:
6682 4188 : case MULT_EXPR:
6683 4188 : case MINUS_EXPR:
6684 4188 : case BIT_AND_EXPR:
6685 4188 : case BIT_XOR_EXPR:
6686 4188 : case BIT_IOR_EXPR:
6687 4188 : case TRUTH_ANDIF_EXPR:
6688 4188 : case TRUTH_ORIF_EXPR:
6689 4188 : reduction_id = ovl_op_identifier (false, reduction_code);
6690 4188 : break;
6691 : case MIN_EXPR:
6692 : p = "min";
6693 : break;
6694 : case MAX_EXPR:
6695 : p = "max";
6696 : break;
6697 : default:
6698 : break;
6699 : }
6700 :
6701 4188 : if (p == NULL)
6702 : {
6703 6921 : if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
6704 0 : return error_mark_node;
6705 6921 : p = IDENTIFIER_POINTER (reduction_id);
6706 : }
6707 :
6708 7085 : if (type != NULL_TREE)
6709 2033 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6710 :
6711 7085 : const char prefix[] = "omp declare reduction ";
6712 7085 : size_t lenp = sizeof (prefix);
6713 7085 : if (strncmp (p, prefix, lenp - 1) == 0)
6714 2033 : lenp = 1;
6715 7085 : size_t len = strlen (p);
6716 7085 : size_t lenm = m ? strlen (m) + 1 : 0;
6717 7085 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6718 7085 : if (lenp > 1)
6719 5052 : memcpy (name, prefix, lenp - 1);
6720 7085 : memcpy (name + lenp - 1, p, len + 1);
6721 7085 : if (m)
6722 : {
6723 2033 : name[lenp + len - 1] = '~';
6724 2033 : memcpy (name + lenp + len, m, lenm);
6725 : }
6726 7085 : return get_identifier (name);
6727 : }
6728 :
6729 : /* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial
6730 : FUNCTION_DECL or NULL_TREE if not found. */
6731 :
6732 : static tree
6733 1288 : omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
6734 : vec<tree> *ambiguousp)
6735 : {
6736 1288 : tree orig_id = id;
6737 1288 : tree baselink = NULL_TREE;
6738 1288 : if (identifier_p (id))
6739 : {
6740 1260 : cp_id_kind idk;
6741 1260 : bool nonint_cst_expression_p;
6742 1260 : const char *error_msg;
6743 1260 : id = omp_reduction_id (ERROR_MARK, id, type);
6744 1260 : tree decl = lookup_name (id);
6745 1260 : if (decl == NULL_TREE)
6746 80 : decl = error_mark_node;
6747 1260 : id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
6748 : &nonint_cst_expression_p, false, true, false,
6749 : false, &error_msg, loc);
6750 1260 : if (idk == CP_ID_KIND_UNQUALIFIED
6751 1340 : && identifier_p (id))
6752 : {
6753 80 : vec<tree, va_gc> *args = NULL;
6754 80 : vec_safe_push (args, build_reference_type (type));
6755 80 : id = perform_koenig_lookup (id, args, tf_none);
6756 : }
6757 : }
6758 28 : else if (TREE_CODE (id) == SCOPE_REF)
6759 28 : id = lookup_qualified_name (TREE_OPERAND (id, 0),
6760 : omp_reduction_id (ERROR_MARK,
6761 28 : TREE_OPERAND (id, 1),
6762 : type),
6763 : LOOK_want::NORMAL, false);
6764 1288 : tree fns = id;
6765 1288 : id = NULL_TREE;
6766 1288 : if (fns && is_overloaded_fn (fns))
6767 : {
6768 1214 : for (lkp_iterator iter (get_fns (fns)); iter; ++iter)
6769 : {
6770 1214 : tree fndecl = *iter;
6771 1214 : if (TREE_CODE (fndecl) == FUNCTION_DECL)
6772 : {
6773 1214 : tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
6774 1214 : if (same_type_p (TREE_TYPE (argtype), type))
6775 : {
6776 1214 : id = fndecl;
6777 1214 : break;
6778 : }
6779 : }
6780 : }
6781 :
6782 1214 : if (id && BASELINK_P (fns))
6783 : {
6784 74 : if (baselinkp)
6785 0 : *baselinkp = fns;
6786 : else
6787 74 : baselink = fns;
6788 : }
6789 : }
6790 :
6791 1288 : if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type))
6792 : {
6793 35 : auto_vec<tree> ambiguous;
6794 35 : tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
6795 35 : unsigned int ix;
6796 35 : if (ambiguousp == NULL)
6797 19 : ambiguousp = &ambiguous;
6798 73 : for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
6799 : {
6800 52 : id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo),
6801 : baselinkp ? baselinkp : &baselink,
6802 : ambiguousp);
6803 38 : if (id == NULL_TREE)
6804 14 : continue;
6805 24 : if (!ambiguousp->is_empty ())
6806 3 : ambiguousp->safe_push (id);
6807 21 : else if (ret != NULL_TREE)
6808 : {
6809 6 : ambiguousp->safe_push (ret);
6810 6 : ambiguousp->safe_push (id);
6811 6 : ret = NULL_TREE;
6812 : }
6813 : else
6814 15 : ret = id;
6815 : }
6816 35 : if (ambiguousp != &ambiguous)
6817 16 : return ret;
6818 19 : if (!ambiguous.is_empty ())
6819 : {
6820 6 : auto_diagnostic_group d;
6821 6 : const char *str = _("candidates are:");
6822 6 : unsigned int idx;
6823 6 : tree udr;
6824 6 : error_at (loc, "user defined reduction lookup is ambiguous");
6825 27 : FOR_EACH_VEC_ELT (ambiguous, idx, udr)
6826 : {
6827 15 : inform (DECL_SOURCE_LOCATION (udr), "%s %#qD", str, udr);
6828 15 : if (idx == 0)
6829 6 : str = get_spaces (str);
6830 : }
6831 6 : ret = error_mark_node;
6832 6 : baselink = NULL_TREE;
6833 6 : }
6834 19 : id = ret;
6835 35 : }
6836 1272 : if (id && baselink)
6837 74 : perform_or_defer_access_check (BASELINK_BINFO (baselink),
6838 : id, id, tf_warning_or_error);
6839 : return id;
6840 : }
6841 :
6842 : /* Return identifier to look up for omp declare mapper. */
6843 :
6844 : tree
6845 3877 : omp_mapper_id (tree mapper_id, tree type)
6846 : {
6847 3877 : const char *p = NULL;
6848 3877 : const char *m = NULL;
6849 :
6850 3877 : if (mapper_id == NULL_TREE)
6851 : p = "";
6852 68 : else if (TREE_CODE (mapper_id) == IDENTIFIER_NODE)
6853 68 : p = IDENTIFIER_POINTER (mapper_id);
6854 : else
6855 0 : return error_mark_node;
6856 :
6857 3877 : if (type != NULL_TREE)
6858 3875 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6859 :
6860 3877 : const char prefix[] = "omp declare mapper ";
6861 3877 : size_t lenp = sizeof (prefix);
6862 3877 : if (strncmp (p, prefix, lenp - 1) == 0)
6863 2 : lenp = 1;
6864 3877 : size_t len = strlen (p);
6865 3877 : size_t lenm = m ? strlen (m) + 1 : 0;
6866 3877 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6867 3877 : memcpy (name, prefix, lenp - 1);
6868 3877 : memcpy (name + lenp - 1, p, len + 1);
6869 3877 : if (m)
6870 : {
6871 3875 : name[lenp + len - 1] = '~';
6872 3875 : memcpy (name + lenp + len, m, lenm);
6873 : }
6874 3877 : return get_identifier (name);
6875 : }
6876 :
6877 : tree
6878 6955 : cxx_omp_mapper_lookup (tree id, tree type)
6879 : {
6880 6955 : if (!RECORD_OR_UNION_TYPE_P (type))
6881 : return NULL_TREE;
6882 3661 : id = omp_mapper_id (id, type);
6883 3661 : return lookup_name (id);
6884 : }
6885 :
6886 : tree
6887 282 : cxx_omp_extract_mapper_directive (tree vardecl)
6888 : {
6889 282 : gcc_assert (TREE_CODE (vardecl) == VAR_DECL);
6890 :
6891 : /* Instantiate the decl if we haven't already. */
6892 282 : mark_used (vardecl);
6893 282 : tree body = DECL_INITIAL (vardecl);
6894 :
6895 282 : if (TREE_CODE (body) == STATEMENT_LIST)
6896 : {
6897 0 : tree_stmt_iterator tsi = tsi_start (body);
6898 0 : gcc_assert (TREE_CODE (tsi_stmt (tsi)) == DECL_EXPR);
6899 0 : tsi_next (&tsi);
6900 0 : body = tsi_stmt (tsi);
6901 : }
6902 :
6903 282 : gcc_assert (TREE_CODE (body) == OMP_DECLARE_MAPPER);
6904 :
6905 282 : return body;
6906 : }
6907 :
6908 : /* For now we can handle singleton OMP_ARRAY_SECTIONs with custom mappers, but
6909 : nothing more complicated. */
6910 :
6911 : tree
6912 1510 : cxx_omp_map_array_section (location_t loc, tree t)
6913 : {
6914 1510 : tree low = TREE_OPERAND (t, 1);
6915 1510 : tree len = TREE_OPERAND (t, 2);
6916 :
6917 1510 : if (len && integer_onep (len))
6918 : {
6919 237 : t = TREE_OPERAND (t, 0);
6920 :
6921 237 : if (!low)
6922 9 : low = integer_zero_node;
6923 :
6924 237 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
6925 5 : t = convert_from_reference (t);
6926 :
6927 237 : t = build_array_ref (loc, t, low);
6928 : }
6929 :
6930 1510 : return t;
6931 : }
6932 :
6933 : /* Helper function for cp_parser_omp_declare_reduction_exprs
6934 : and tsubst_omp_udr.
6935 : Remove CLEANUP_STMT for data (omp_priv variable).
6936 : Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
6937 : DECL_EXPR. */
6938 :
6939 : tree
6940 4395 : cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data)
6941 : {
6942 4395 : if (TYPE_P (*tp))
6943 227 : *walk_subtrees = 0;
6944 4168 : else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data)
6945 52 : *tp = CLEANUP_BODY (*tp);
6946 4116 : else if (TREE_CODE (*tp) == DECL_EXPR)
6947 : {
6948 307 : tree decl = DECL_EXPR_DECL (*tp);
6949 307 : if (!processing_template_decl
6950 258 : && decl == (tree) data
6951 258 : && DECL_INITIAL (decl)
6952 399 : && DECL_INITIAL (decl) != error_mark_node)
6953 : {
6954 92 : tree list = NULL_TREE;
6955 92 : append_to_statement_list_force (*tp, &list);
6956 92 : tree init_expr = build2 (INIT_EXPR, void_type_node,
6957 92 : decl, DECL_INITIAL (decl));
6958 92 : DECL_INITIAL (decl) = NULL_TREE;
6959 92 : append_to_statement_list_force (init_expr, &list);
6960 92 : *tp = list;
6961 : }
6962 : }
6963 4395 : return NULL_TREE;
6964 : }
6965 :
6966 : /* Data passed from cp_check_omp_declare_reduction to
6967 : cp_check_omp_declare_reduction_r. */
6968 :
6969 : struct cp_check_omp_declare_reduction_data
6970 : {
6971 : location_t loc;
6972 : tree stmts[7];
6973 : bool combiner_p;
6974 : };
6975 :
6976 : /* Helper function for cp_check_omp_declare_reduction, called via
6977 : cp_walk_tree. */
6978 :
6979 : static tree
6980 14952 : cp_check_omp_declare_reduction_r (tree *tp, int *, void *data)
6981 : {
6982 14952 : struct cp_check_omp_declare_reduction_data *udr_data
6983 : = (struct cp_check_omp_declare_reduction_data *) data;
6984 14952 : if (SSA_VAR_P (*tp)
6985 2687 : && !DECL_ARTIFICIAL (*tp)
6986 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3])
6987 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4]))
6988 : {
6989 135 : location_t loc = udr_data->loc;
6990 135 : if (udr_data->combiner_p)
6991 45 : error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
6992 : "variable %qD which is not %<omp_out%> nor %<omp_in%>",
6993 : *tp);
6994 : else
6995 90 : error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
6996 : "to variable %qD which is not %<omp_priv%> nor "
6997 : "%<omp_orig%>",
6998 : *tp);
6999 135 : return *tp;
7000 : }
7001 : return NULL_TREE;
7002 : }
7003 :
7004 : /* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */
7005 :
7006 : bool
7007 1100 : cp_check_omp_declare_reduction (tree udr)
7008 : {
7009 1100 : tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
7010 1100 : gcc_assert (TYPE_REF_P (type));
7011 1100 : type = TREE_TYPE (type);
7012 1100 : int i;
7013 1100 : location_t loc = DECL_SOURCE_LOCATION (udr);
7014 :
7015 1100 : if (type == error_mark_node)
7016 : return false;
7017 1100 : if (ARITHMETIC_TYPE_P (type))
7018 : {
7019 : static enum tree_code predef_codes[]
7020 : = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR,
7021 : BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR };
7022 3276 : for (i = 0; i < 8; i++)
7023 : {
7024 2918 : tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE);
7025 2918 : const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr));
7026 2918 : const char *n2 = IDENTIFIER_POINTER (id);
7027 2918 : if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0
7028 2918 : && (n1[IDENTIFIER_LENGTH (id)] == '~'
7029 0 : || n1[IDENTIFIER_LENGTH (id)] == '\0'))
7030 : break;
7031 : }
7032 :
7033 376 : if (i == 8
7034 358 : && TREE_CODE (type) != COMPLEX_EXPR)
7035 : {
7036 358 : const char prefix_minmax[] = "omp declare reduction m";
7037 358 : size_t prefix_size = sizeof (prefix_minmax) - 1;
7038 358 : const char *n = IDENTIFIER_POINTER (DECL_NAME (udr));
7039 358 : if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)),
7040 : prefix_minmax, prefix_size) == 0
7041 10 : && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n')
7042 4 : || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x'))
7043 368 : && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0'))
7044 6 : i = 0;
7045 : }
7046 376 : if (i < 8)
7047 : {
7048 24 : error_at (loc, "predeclared arithmetic type %qT in "
7049 : "%<#pragma omp declare reduction%>", type);
7050 24 : return false;
7051 : }
7052 : }
7053 : else if (FUNC_OR_METHOD_TYPE_P (type)
7054 : || TREE_CODE (type) == ARRAY_TYPE)
7055 : {
7056 24 : error_at (loc, "function or array type %qT in "
7057 : "%<#pragma omp declare reduction%>", type);
7058 24 : return false;
7059 : }
7060 : else if (TYPE_REF_P (type))
7061 : {
7062 0 : error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
7063 : type);
7064 0 : return false;
7065 : }
7066 700 : else if (TYPE_QUALS_NO_ADDR_SPACE (type))
7067 : {
7068 24 : error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
7069 : "type %qT in %<#pragma omp declare reduction%>", type);
7070 24 : return false;
7071 : }
7072 :
7073 1028 : tree body = DECL_SAVED_TREE (udr);
7074 1028 : if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST)
7075 : return true;
7076 :
7077 842 : tree_stmt_iterator tsi;
7078 842 : struct cp_check_omp_declare_reduction_data data;
7079 842 : memset (data.stmts, 0, sizeof data.stmts);
7080 842 : for (i = 0, tsi = tsi_start (body);
7081 4679 : i < 7 && !tsi_end_p (tsi);
7082 3837 : i++, tsi_next (&tsi))
7083 3837 : data.stmts[i] = tsi_stmt (tsi);
7084 842 : data.loc = loc;
7085 842 : gcc_assert (tsi_end_p (tsi));
7086 842 : if (i >= 3)
7087 : {
7088 842 : gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
7089 : && TREE_CODE (data.stmts[1]) == DECL_EXPR);
7090 842 : if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */))
7091 : return true;
7092 797 : data.combiner_p = true;
7093 797 : if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
7094 : &data, NULL))
7095 45 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */);
7096 : }
7097 797 : if (i >= 6)
7098 : {
7099 336 : gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR
7100 : && TREE_CODE (data.stmts[4]) == DECL_EXPR);
7101 336 : data.combiner_p = false;
7102 336 : if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r,
7103 : &data, NULL)
7104 336 : || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
7105 : cp_check_omp_declare_reduction_r, &data, NULL))
7106 90 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */);
7107 336 : if (i == 7)
7108 198 : gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
7109 : }
7110 : return true;
7111 : }
7112 :
7113 : /* Helper function of finish_omp_clauses. Clone STMT as if we were making
7114 : an inline call. But, remap
7115 : the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER
7116 : and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */
7117 :
7118 : static tree
7119 2198 : clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
7120 : tree decl, tree placeholder)
7121 : {
7122 2198 : copy_body_data id;
7123 2198 : hash_map<tree, tree> decl_map;
7124 :
7125 2198 : decl_map.put (omp_decl1, placeholder);
7126 2198 : decl_map.put (omp_decl2, decl);
7127 2198 : memset (&id, 0, sizeof (id));
7128 2198 : id.src_fn = DECL_CONTEXT (omp_decl1);
7129 2198 : id.dst_fn = current_function_decl;
7130 2198 : id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
7131 2198 : id.decl_map = &decl_map;
7132 :
7133 2198 : id.copy_decl = copy_decl_no_change;
7134 2198 : id.transform_call_graph_edges = CB_CGE_DUPLICATE;
7135 2198 : id.transform_new_cfg = true;
7136 2198 : id.transform_return_to_modify = false;
7137 2198 : id.eh_lp_nr = 0;
7138 2198 : walk_tree (&stmt, copy_tree_body_r, &id, NULL);
7139 2198 : return stmt;
7140 2198 : }
7141 :
7142 : /* Helper function of finish_omp_clauses, called via cp_walk_tree.
7143 : Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */
7144 :
7145 : static tree
7146 15438 : find_omp_placeholder_r (tree *tp, int *, void *data)
7147 : {
7148 15438 : if (*tp == (tree) data)
7149 265 : return *tp;
7150 : return NULL_TREE;
7151 : }
7152 :
7153 : /* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C.
7154 : Return true if there is some error and the clause should be removed. */
7155 :
7156 : static bool
7157 8855 : finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
7158 : {
7159 8855 : tree t = OMP_CLAUSE_DECL (c);
7160 8855 : bool predefined = false;
7161 8855 : if (TREE_CODE (t) == TREE_LIST)
7162 : {
7163 0 : gcc_assert (processing_template_decl);
7164 : return false;
7165 : }
7166 8855 : tree type = TREE_TYPE (t);
7167 8855 : if (TREE_CODE (t) == MEM_REF)
7168 1596 : type = TREE_TYPE (type);
7169 8855 : if (TYPE_REF_P (type))
7170 527 : type = TREE_TYPE (type);
7171 8855 : if (TREE_CODE (type) == ARRAY_TYPE)
7172 : {
7173 350 : tree oatype = type;
7174 350 : gcc_assert (TREE_CODE (t) != MEM_REF);
7175 703 : while (TREE_CODE (type) == ARRAY_TYPE)
7176 353 : type = TREE_TYPE (type);
7177 350 : if (!processing_template_decl)
7178 : {
7179 255 : t = require_complete_type (t);
7180 255 : if (t == error_mark_node
7181 255 : || !complete_type_or_else (oatype, NULL_TREE))
7182 9 : return true;
7183 246 : tree size = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (oatype),
7184 : TYPE_SIZE_UNIT (type));
7185 246 : if (integer_zerop (size))
7186 : {
7187 6 : error_at (OMP_CLAUSE_LOCATION (c),
7188 : "%qE in %<reduction%> clause is a zero size array",
7189 : omp_clause_printable_decl (t));
7190 3 : return true;
7191 : }
7192 243 : size = size_binop (MINUS_EXPR, size, size_one_node);
7193 243 : size = save_expr (size);
7194 243 : tree index_type = build_index_type (size);
7195 243 : tree atype = build_array_type (type, index_type);
7196 243 : tree ptype = build_pointer_type (type);
7197 243 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7198 146 : t = build_fold_addr_expr (t);
7199 243 : t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0));
7200 243 : OMP_CLAUSE_DECL (c) = t;
7201 : }
7202 : }
7203 8843 : if (type == error_mark_node)
7204 : return true;
7205 8840 : else if (ARITHMETIC_TYPE_P (type))
7206 7590 : switch (OMP_CLAUSE_REDUCTION_CODE (c))
7207 : {
7208 : case PLUS_EXPR:
7209 : case MULT_EXPR:
7210 : case MINUS_EXPR:
7211 : case TRUTH_ANDIF_EXPR:
7212 : case TRUTH_ORIF_EXPR:
7213 : predefined = true;
7214 : break;
7215 246 : case MIN_EXPR:
7216 246 : case MAX_EXPR:
7217 246 : if (TREE_CODE (type) == COMPLEX_TYPE)
7218 : break;
7219 : predefined = true;
7220 : break;
7221 111 : case BIT_AND_EXPR:
7222 111 : case BIT_IOR_EXPR:
7223 111 : case BIT_XOR_EXPR:
7224 111 : if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
7225 : break;
7226 : predefined = true;
7227 : break;
7228 : default:
7229 : break;
7230 : }
7231 1250 : else if (TYPE_READONLY (type))
7232 : {
7233 18 : error_at (OMP_CLAUSE_LOCATION (c),
7234 : "%qE has const type for %<reduction%>",
7235 : omp_clause_printable_decl (t));
7236 9 : return true;
7237 : }
7238 1241 : else if (!processing_template_decl)
7239 : {
7240 1037 : t = require_complete_type (t);
7241 1037 : if (t == error_mark_node)
7242 : return true;
7243 1037 : OMP_CLAUSE_DECL (c) = t;
7244 : }
7245 :
7246 1037 : if (predefined)
7247 : {
7248 7368 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7249 7368 : return false;
7250 : }
7251 1463 : else if (processing_template_decl)
7252 : {
7253 213 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
7254 : return true;
7255 : return false;
7256 : }
7257 :
7258 1250 : tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
7259 :
7260 1250 : type = TYPE_MAIN_VARIANT (type);
7261 1250 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7262 1250 : if (id == NULL_TREE)
7263 924 : id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c),
7264 : NULL_TREE, NULL_TREE);
7265 1250 : id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL);
7266 1250 : if (id)
7267 : {
7268 1205 : if (id == error_mark_node)
7269 : return true;
7270 1199 : mark_used (id);
7271 1199 : tree body = DECL_SAVED_TREE (id);
7272 1199 : if (!body)
7273 : return true;
7274 1196 : if (TREE_CODE (body) == STATEMENT_LIST)
7275 : {
7276 1196 : tree_stmt_iterator tsi;
7277 1196 : tree placeholder = NULL_TREE, decl_placeholder = NULL_TREE;
7278 1196 : int i;
7279 1196 : tree stmts[7];
7280 1196 : tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id)));
7281 1196 : atype = TREE_TYPE (atype);
7282 1196 : bool need_static_cast = !same_type_p (type, atype);
7283 1196 : memset (stmts, 0, sizeof stmts);
7284 1196 : for (i = 0, tsi = tsi_start (body);
7285 8518 : i < 7 && !tsi_end_p (tsi);
7286 7322 : i++, tsi_next (&tsi))
7287 7322 : stmts[i] = tsi_stmt (tsi);
7288 1196 : gcc_assert (tsi_end_p (tsi));
7289 :
7290 1196 : if (i >= 3)
7291 : {
7292 1196 : gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
7293 : && TREE_CODE (stmts[1]) == DECL_EXPR);
7294 1196 : placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type);
7295 1196 : DECL_ARTIFICIAL (placeholder) = 1;
7296 1196 : DECL_IGNORED_P (placeholder) = 1;
7297 1196 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder;
7298 1196 : if (TREE_CODE (t) == MEM_REF)
7299 : {
7300 600 : decl_placeholder = build_lang_decl (VAR_DECL, NULL_TREE,
7301 : type);
7302 600 : DECL_ARTIFICIAL (decl_placeholder) = 1;
7303 600 : DECL_IGNORED_P (decl_placeholder) = 1;
7304 600 : OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = decl_placeholder;
7305 : }
7306 1196 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
7307 285 : cxx_mark_addressable (placeholder);
7308 1196 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
7309 1196 : && (decl_placeholder
7310 149 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7311 372 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7312 118 : : OMP_CLAUSE_DECL (c));
7313 1196 : tree omp_out = placeholder;
7314 1196 : tree omp_in = decl_placeholder ? decl_placeholder
7315 596 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7316 1196 : if (need_static_cast)
7317 : {
7318 7 : tree rtype = build_reference_type (atype);
7319 7 : omp_out = build_static_cast (input_location,
7320 : rtype, omp_out,
7321 : tf_warning_or_error);
7322 7 : omp_in = build_static_cast (input_location,
7323 : rtype, omp_in,
7324 : tf_warning_or_error);
7325 7 : if (omp_out == error_mark_node || omp_in == error_mark_node)
7326 3 : return true;
7327 7 : omp_out = convert_from_reference (omp_out);
7328 7 : omp_in = convert_from_reference (omp_in);
7329 : }
7330 1196 : OMP_CLAUSE_REDUCTION_MERGE (c)
7331 1196 : = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]),
7332 1196 : DECL_EXPR_DECL (stmts[1]), omp_in, omp_out);
7333 : }
7334 1196 : if (i >= 6)
7335 : {
7336 1005 : gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
7337 : && TREE_CODE (stmts[4]) == DECL_EXPR);
7338 1005 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3]))
7339 1005 : && (decl_placeholder
7340 232 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7341 844 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7342 170 : : OMP_CLAUSE_DECL (c));
7343 1005 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
7344 216 : cxx_mark_addressable (placeholder);
7345 1005 : tree omp_priv = decl_placeholder ? decl_placeholder
7346 429 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7347 1005 : tree omp_orig = placeholder;
7348 1005 : if (need_static_cast)
7349 : {
7350 5 : if (i == 7)
7351 : {
7352 3 : error_at (OMP_CLAUSE_LOCATION (c),
7353 : "user defined reduction with constructor "
7354 : "initializer for base class %qT", atype);
7355 3 : return true;
7356 : }
7357 2 : tree rtype = build_reference_type (atype);
7358 2 : omp_priv = build_static_cast (input_location,
7359 : rtype, omp_priv,
7360 : tf_warning_or_error);
7361 2 : omp_orig = build_static_cast (input_location,
7362 : rtype, omp_orig,
7363 : tf_warning_or_error);
7364 2 : if (omp_priv == error_mark_node
7365 2 : || omp_orig == error_mark_node)
7366 : return true;
7367 2 : omp_priv = convert_from_reference (omp_priv);
7368 2 : omp_orig = convert_from_reference (omp_orig);
7369 : }
7370 1002 : if (i == 6)
7371 286 : *need_default_ctor = true;
7372 1002 : OMP_CLAUSE_REDUCTION_INIT (c)
7373 1002 : = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]),
7374 1002 : DECL_EXPR_DECL (stmts[3]),
7375 : omp_priv, omp_orig);
7376 1002 : if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7377 : find_omp_placeholder_r, placeholder, NULL))
7378 238 : OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
7379 : }
7380 191 : else if (i >= 3)
7381 : {
7382 191 : if (CLASS_TYPE_P (type) && !pod_type_p (type))
7383 175 : *need_default_ctor = true;
7384 : else
7385 : {
7386 16 : tree init;
7387 16 : tree v = decl_placeholder ? decl_placeholder
7388 16 : : convert_from_reference (t);
7389 16 : if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
7390 7 : init = build_constructor (TREE_TYPE (v), NULL);
7391 : else
7392 9 : init = fold_convert (TREE_TYPE (v), integer_zero_node);
7393 32 : OMP_CLAUSE_REDUCTION_INIT (c)
7394 32 : = cp_build_init_expr (v, init);
7395 : }
7396 : }
7397 : }
7398 : }
7399 1238 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7400 1193 : *need_dtor = true;
7401 : else
7402 : {
7403 90 : error_at (OMP_CLAUSE_LOCATION (c),
7404 : "user defined reduction not found for %qE",
7405 : omp_clause_printable_decl (t));
7406 45 : return true;
7407 : }
7408 1193 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
7409 600 : gcc_assert (TYPE_SIZE_UNIT (type)
7410 : && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
7411 : return false;
7412 : }
7413 :
7414 : /* Check an instance of an "omp declare mapper" function. */
7415 :
7416 : bool
7417 182 : cp_check_omp_declare_mapper (tree udm)
7418 : {
7419 182 : tree type = TREE_TYPE (udm);
7420 182 : location_t loc = DECL_SOURCE_LOCATION (udm);
7421 :
7422 182 : if (type == error_mark_node)
7423 : return false;
7424 :
7425 182 : if (!processing_template_decl && !RECORD_OR_UNION_TYPE_P (type))
7426 : {
7427 15 : error_at (loc, "%qT is not a struct, union or class type in "
7428 : "%<#pragma omp declare mapper%>", type);
7429 15 : return false;
7430 : }
7431 167 : if (!processing_template_decl && CLASSTYPE_VBASECLASSES (type))
7432 : {
7433 3 : error_at (loc, "%qT must not be a virtual base class in "
7434 : "%<#pragma omp declare mapper%>", type);
7435 3 : return false;
7436 : }
7437 :
7438 : return true;
7439 : }
7440 :
7441 : /* Called from finish_struct_1. linear(this) or linear(this:step)
7442 : clauses might not be finalized yet because the class has been incomplete
7443 : when parsing #pragma omp declare simd methods. Fix those up now. */
7444 :
7445 : void
7446 117814 : finish_omp_declare_simd_methods (tree t)
7447 : {
7448 117814 : if (processing_template_decl)
7449 : return;
7450 :
7451 804097 : for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
7452 : {
7453 1135552 : if (TREE_CODE (x) == USING_DECL
7454 686283 : || !DECL_IOBJ_MEMBER_FUNCTION_P (x))
7455 449269 : continue;
7456 237014 : tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x));
7457 237122 : if (!ods || !TREE_VALUE (ods))
7458 236906 : continue;
7459 366 : for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c))
7460 258 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7461 66 : && integer_zerop (OMP_CLAUSE_DECL (c))
7462 18 : && OMP_CLAUSE_LINEAR_STEP (c)
7463 276 : && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c))))
7464 : {
7465 18 : tree s = OMP_CLAUSE_LINEAR_STEP (c);
7466 18 : s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
7467 18 : s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
7468 18 : sizetype, s, TYPE_SIZE_UNIT (t));
7469 18 : OMP_CLAUSE_LINEAR_STEP (c) = s;
7470 : }
7471 : }
7472 : }
7473 :
7474 : /* Adjust sink depend/doacross clause to take into account pointer offsets.
7475 :
7476 : Return TRUE if there was a problem processing the offset, and the
7477 : whole clause should be removed. */
7478 :
7479 : static bool
7480 298 : cp_finish_omp_clause_doacross_sink (tree sink_clause)
7481 : {
7482 298 : tree t = OMP_CLAUSE_DECL (sink_clause);
7483 298 : gcc_assert (TREE_CODE (t) == TREE_LIST);
7484 :
7485 : /* Make sure we don't adjust things twice for templates. */
7486 298 : if (processing_template_decl)
7487 : return false;
7488 :
7489 671 : for (; t; t = TREE_CHAIN (t))
7490 : {
7491 391 : tree decl = TREE_VALUE (t);
7492 391 : if (TYPE_PTR_P (TREE_TYPE (decl)))
7493 : {
7494 6 : tree offset = TREE_PURPOSE (t);
7495 6 : bool neg = wi::neg_p (wi::to_wide (offset));
7496 6 : offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset);
7497 6 : decl = mark_rvalue_use (decl);
7498 6 : decl = convert_from_reference (decl);
7499 12 : tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause),
7500 : neg ? MINUS_EXPR : PLUS_EXPR,
7501 : decl, offset);
7502 6 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
7503 : MINUS_EXPR, sizetype,
7504 : fold_convert (sizetype, t2),
7505 : fold_convert (sizetype, decl));
7506 6 : if (t2 == error_mark_node)
7507 : return true;
7508 6 : TREE_PURPOSE (t) = t2;
7509 : }
7510 : }
7511 : return false;
7512 : }
7513 :
7514 : /* Finish OpenMP iterators ITER. Return true if they are errorneous
7515 : and clauses containing them should be removed. */
7516 :
7517 : static bool
7518 614 : cp_omp_finish_iterators (tree iter)
7519 : {
7520 614 : bool ret = false;
7521 1393 : for (tree it = iter; it; it = TREE_CHAIN (it))
7522 : {
7523 779 : tree var = TREE_VEC_ELT (it, 0);
7524 779 : tree begin = TREE_VEC_ELT (it, 1);
7525 779 : tree end = TREE_VEC_ELT (it, 2);
7526 779 : tree step = TREE_VEC_ELT (it, 3);
7527 779 : tree orig_step;
7528 779 : tree type = TREE_TYPE (var);
7529 779 : location_t loc = DECL_SOURCE_LOCATION (var);
7530 779 : if (type == error_mark_node)
7531 : {
7532 0 : ret = true;
7533 218 : continue;
7534 : }
7535 779 : if (type_dependent_expression_p (var))
7536 59 : continue;
7537 720 : if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
7538 : {
7539 27 : error_at (loc, "iterator %qD has neither integral nor pointer type",
7540 : var);
7541 27 : ret = true;
7542 27 : continue;
7543 : }
7544 693 : else if (TYPE_READONLY (type))
7545 : {
7546 24 : error_at (loc, "iterator %qD has const qualified type", var);
7547 24 : ret = true;
7548 24 : continue;
7549 : }
7550 669 : if (type_dependent_expression_p (begin)
7551 660 : || type_dependent_expression_p (end)
7552 1329 : || type_dependent_expression_p (step))
7553 15 : continue;
7554 654 : else if (error_operand_p (step))
7555 : {
7556 0 : ret = true;
7557 0 : continue;
7558 : }
7559 654 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
7560 : {
7561 33 : error_at (EXPR_LOC_OR_LOC (step, loc),
7562 : "iterator step with non-integral type");
7563 21 : ret = true;
7564 21 : continue;
7565 : }
7566 :
7567 633 : begin = mark_rvalue_use (begin);
7568 633 : end = mark_rvalue_use (end);
7569 633 : step = mark_rvalue_use (step);
7570 633 : begin = cp_build_c_cast (input_location, type, begin,
7571 : tf_warning_or_error);
7572 633 : end = cp_build_c_cast (input_location, type, end,
7573 : tf_warning_or_error);
7574 633 : orig_step = step;
7575 633 : if (!processing_template_decl)
7576 556 : step = orig_step = save_expr (step);
7577 633 : tree stype = POINTER_TYPE_P (type) ? sizetype : type;
7578 633 : step = cp_build_c_cast (input_location, stype, step,
7579 : tf_warning_or_error);
7580 633 : if (POINTER_TYPE_P (type) && !processing_template_decl)
7581 : {
7582 66 : begin = save_expr (begin);
7583 66 : step = pointer_int_sum (loc, PLUS_EXPR, begin, step);
7584 66 : step = fold_build2_loc (loc, MINUS_EXPR, sizetype,
7585 : fold_convert (sizetype, step),
7586 : fold_convert (sizetype, begin));
7587 66 : step = fold_convert (ssizetype, step);
7588 : }
7589 633 : if (!processing_template_decl)
7590 : {
7591 556 : begin = maybe_constant_value (begin);
7592 556 : end = maybe_constant_value (end);
7593 556 : step = maybe_constant_value (step);
7594 556 : orig_step = maybe_constant_value (orig_step);
7595 : }
7596 633 : if (integer_zerop (step))
7597 : {
7598 27 : error_at (loc, "iterator %qD has zero step", var);
7599 27 : ret = true;
7600 27 : continue;
7601 : }
7602 :
7603 606 : if (begin == error_mark_node
7604 597 : || end == error_mark_node
7605 588 : || step == error_mark_node
7606 588 : || orig_step == error_mark_node)
7607 : {
7608 18 : ret = true;
7609 18 : continue;
7610 : }
7611 :
7612 588 : if (!processing_template_decl)
7613 : {
7614 511 : begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin);
7615 511 : end = fold_build_cleanup_point_expr (TREE_TYPE (end), end);
7616 511 : step = fold_build_cleanup_point_expr (TREE_TYPE (step), step);
7617 511 : orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step),
7618 : orig_step);
7619 : }
7620 588 : hash_set<tree> pset;
7621 588 : tree it2;
7622 744 : for (it2 = TREE_CHAIN (it); it2; it2 = TREE_CHAIN (it2))
7623 : {
7624 183 : tree var2 = TREE_VEC_ELT (it2, 0);
7625 183 : tree begin2 = TREE_VEC_ELT (it2, 1);
7626 183 : tree end2 = TREE_VEC_ELT (it2, 2);
7627 183 : tree step2 = TREE_VEC_ELT (it2, 3);
7628 183 : location_t loc2 = DECL_SOURCE_LOCATION (var2);
7629 183 : if (cp_walk_tree (&begin2, find_omp_placeholder_r, var, &pset))
7630 : {
7631 9 : error_at (EXPR_LOC_OR_LOC (begin2, loc2),
7632 : "begin expression refers to outer iterator %qD", var);
7633 36 : break;
7634 : }
7635 174 : else if (cp_walk_tree (&end2, find_omp_placeholder_r, var, &pset))
7636 : {
7637 9 : error_at (EXPR_LOC_OR_LOC (end2, loc2),
7638 : "end expression refers to outer iterator %qD", var);
7639 9 : break;
7640 : }
7641 165 : else if (cp_walk_tree (&step2, find_omp_placeholder_r, var, &pset))
7642 : {
7643 9 : error_at (EXPR_LOC_OR_LOC (step2, loc2),
7644 : "step expression refers to outer iterator %qD", var);
7645 9 : break;
7646 : }
7647 : }
7648 588 : if (it2)
7649 : {
7650 27 : ret = true;
7651 27 : continue;
7652 : }
7653 561 : TREE_VEC_ELT (it, 1) = begin;
7654 561 : TREE_VEC_ELT (it, 2) = end;
7655 561 : if (processing_template_decl)
7656 71 : TREE_VEC_ELT (it, 3) = orig_step;
7657 : else
7658 : {
7659 490 : TREE_VEC_ELT (it, 3) = step;
7660 490 : TREE_VEC_ELT (it, 4) = orig_step;
7661 : }
7662 588 : }
7663 614 : return ret;
7664 : }
7665 :
7666 : /* Ensure that pointers are used in OpenACC attach and detach clauses.
7667 : Return true if an error has been detected. */
7668 :
7669 : static bool
7670 18306 : cp_oacc_check_attachments (tree c)
7671 : {
7672 18306 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
7673 : return false;
7674 :
7675 : /* OpenACC attach / detach clauses must be pointers. */
7676 14411 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
7677 14411 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
7678 : {
7679 196 : tree t = OMP_CLAUSE_DECL (c);
7680 196 : tree type;
7681 :
7682 232 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7683 36 : t = TREE_OPERAND (t, 0);
7684 :
7685 196 : type = TREE_TYPE (t);
7686 :
7687 196 : if (TREE_CODE (type) == REFERENCE_TYPE)
7688 36 : type = TREE_TYPE (type);
7689 :
7690 196 : if (TREE_CODE (type) != POINTER_TYPE)
7691 : {
7692 36 : error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause",
7693 : user_omp_clause_code_name (c, true));
7694 36 : return true;
7695 : }
7696 : }
7697 :
7698 : return false;
7699 : }
7700 :
7701 : /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution
7702 : happened. */
7703 :
7704 : tree
7705 813 : cp_finish_omp_init_prefer_type (tree pref_type)
7706 : {
7707 813 : if (processing_template_decl
7708 741 : || pref_type == NULL_TREE
7709 356 : || TREE_CODE (pref_type) != TREE_LIST)
7710 : return pref_type;
7711 :
7712 81 : tree t = TREE_PURPOSE (pref_type);
7713 81 : char *str = const_cast<char *> (TREE_STRING_POINTER (t));
7714 81 : tree fr_list = TREE_VALUE (pref_type);
7715 81 : int len = TREE_VEC_LENGTH (fr_list);
7716 81 : int cnt = 0;
7717 :
7718 270 : while (str[0] == (char) GOMP_INTEROP_IFR_SEPARATOR)
7719 : {
7720 270 : str++;
7721 270 : if (str[0] == (char) GOMP_INTEROP_IFR_UNKNOWN)
7722 : {
7723 : /* Assume a no or a single 'fr'. */
7724 150 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7725 150 : location_t loc = UNKNOWN_LOCATION;
7726 150 : tree value = TREE_VEC_ELT (fr_list, cnt);
7727 150 : if (value != NULL_TREE && value != error_mark_node)
7728 : {
7729 126 : loc = EXPR_LOCATION (value);
7730 126 : if (value && TREE_CODE (value) == NOP_EXPR)
7731 39 : value = TREE_OPERAND (value, 0);
7732 126 : value = cp_fully_fold (value);
7733 : }
7734 126 : if (value != NULL_TREE && value != error_mark_node)
7735 : {
7736 126 : if (TREE_CODE (value) != INTEGER_CST
7737 126 : || !tree_fits_shwi_p (value))
7738 0 : error_at (loc,
7739 : "expected string literal or "
7740 : "constant integer expression instead of %qE", value);
7741 : else
7742 : {
7743 126 : HOST_WIDE_INT n = tree_to_shwi (value);
7744 126 : if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
7745 : {
7746 48 : warning_at (loc, OPT_Wopenmp,
7747 : "unknown foreign runtime identifier %qwd", n);
7748 48 : n = GOMP_INTEROP_IFR_UNKNOWN;
7749 : }
7750 126 : str[0] = (char) n;
7751 : }
7752 : }
7753 150 : str++;
7754 : }
7755 120 : else if (str[0] != (char) GOMP_INTEROP_IFR_SEPARATOR)
7756 : {
7757 : /* Assume a no or a single 'fr'. */
7758 120 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7759 120 : str++;
7760 : }
7761 270 : str++;
7762 294 : while (str[0] != '\0')
7763 24 : str += strlen (str) + 1;
7764 270 : str++;
7765 270 : cnt++;
7766 270 : if (cnt >= len)
7767 : break;
7768 : }
7769 : return t;
7770 : }
7771 :
7772 : /* For all elements of CLAUSES, validate them vs OpenMP constraints.
7773 : Remove any elements from the list that are invalid. */
7774 :
7775 : tree
7776 62520 : finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
7777 : {
7778 62520 : bitmap_head generic_head, firstprivate_head, lastprivate_head;
7779 62520 : bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head;
7780 62520 : bitmap_head oacc_reduction_head, is_on_device_head;
7781 62520 : tree c, t, *pc;
7782 62520 : tree safelen = NULL_TREE;
7783 62520 : bool openacc = (ort & C_ORT_ACC) != 0;
7784 62520 : bool branch_seen = false;
7785 62520 : bool copyprivate_seen = false;
7786 62520 : bool ordered_seen = false;
7787 62520 : bool order_seen = false;
7788 62520 : bool schedule_seen = false;
7789 62520 : bool oacc_async = false;
7790 62520 : bool indir_component_ref_p = false;
7791 62520 : tree last_iterators = NULL_TREE;
7792 62520 : bool last_iterators_remove = false;
7793 : /* 1 if normal/task reduction has been seen, -1 if inscan reduction
7794 : has been seen, -2 if mixed inscan/normal reduction diagnosed. */
7795 62520 : int reduction_seen = 0;
7796 62520 : bool allocate_seen = false;
7797 62520 : tree detach_seen = NULL_TREE;
7798 62520 : bool mergeable_seen = false;
7799 62520 : bool implicit_moved = false;
7800 62520 : bool target_in_reduction_seen = false;
7801 62520 : bool num_tasks_seen = false;
7802 62520 : bool partial_seen = false;
7803 62520 : bool init_seen = false;
7804 62520 : bool init_use_destroy_seen = false;
7805 62520 : tree init_no_targetsync_clause = NULL_TREE;
7806 62520 : tree depend_clause = NULL_TREE;
7807 :
7808 62520 : bitmap_obstack_initialize (NULL);
7809 62520 : bitmap_initialize (&generic_head, &bitmap_default_obstack);
7810 62520 : bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
7811 62520 : bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
7812 62520 : bitmap_initialize (&aligned_head, &bitmap_default_obstack);
7813 : /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
7814 62520 : bitmap_initialize (&map_head, &bitmap_default_obstack);
7815 62520 : bitmap_initialize (&map_field_head, &bitmap_default_obstack);
7816 62520 : bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack);
7817 : /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
7818 : instead and for ort == C_ORT_OMP_TARGET used as in_reduction_head. */
7819 62520 : bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
7820 62520 : bitmap_initialize (&is_on_device_head, &bitmap_default_obstack);
7821 :
7822 62520 : if (openacc)
7823 28281 : for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
7824 15935 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
7825 : {
7826 : oacc_async = true;
7827 : break;
7828 : }
7829 :
7830 62520 : tree *grp_start_p = NULL, grp_sentinel = NULL_TREE;
7831 :
7832 160125 : for (pc = &clauses, c = clauses; c ; c = *pc)
7833 : {
7834 97605 : bool remove = false;
7835 97605 : bool field_ok = false;
7836 :
7837 : /* We've reached the end of a list of expanded nodes. Reset the group
7838 : start pointer. */
7839 97605 : if (c == grp_sentinel)
7840 : {
7841 5481 : if (grp_start_p
7842 5481 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
7843 96 : for (tree gc = *grp_start_p; gc != grp_sentinel;
7844 66 : gc = OMP_CLAUSE_CHAIN (gc))
7845 66 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
7846 : grp_start_p = NULL;
7847 : }
7848 :
7849 97605 : switch (OMP_CLAUSE_CODE (c))
7850 : {
7851 2100 : case OMP_CLAUSE_SHARED:
7852 2100 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7853 2100 : goto check_dup_generic;
7854 2576 : case OMP_CLAUSE_PRIVATE:
7855 2576 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7856 2576 : goto check_dup_generic;
7857 7337 : case OMP_CLAUSE_REDUCTION:
7858 7337 : if (reduction_seen == 0)
7859 6233 : reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
7860 1104 : else if (reduction_seen != -2
7861 2208 : && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
7862 1104 : ? -1 : 1))
7863 : {
7864 6 : error_at (OMP_CLAUSE_LOCATION (c),
7865 : "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
7866 : "on the same construct");
7867 6 : reduction_seen = -2;
7868 : }
7869 : /* FALLTHRU */
7870 9482 : case OMP_CLAUSE_IN_REDUCTION:
7871 9482 : case OMP_CLAUSE_TASK_REDUCTION:
7872 9482 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7873 9482 : t = OMP_CLAUSE_DECL (c);
7874 9482 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
7875 : {
7876 2207 : if (handle_omp_array_sections (c, ort))
7877 : {
7878 : remove = true;
7879 : break;
7880 : }
7881 2165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
7882 2165 : && OMP_CLAUSE_REDUCTION_INSCAN (c))
7883 : {
7884 3 : error_at (OMP_CLAUSE_LOCATION (c),
7885 : "%<inscan%> %<reduction%> clause with array "
7886 : "section");
7887 3 : remove = true;
7888 3 : break;
7889 : }
7890 2162 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
7891 : {
7892 4672 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7893 2510 : t = TREE_OPERAND (t, 0);
7894 : }
7895 : else
7896 : {
7897 0 : gcc_assert (TREE_CODE (t) == MEM_REF);
7898 0 : t = TREE_OPERAND (t, 0);
7899 0 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
7900 0 : t = TREE_OPERAND (t, 0);
7901 0 : if (TREE_CODE (t) == ADDR_EXPR
7902 0 : || INDIRECT_REF_P (t))
7903 0 : t = TREE_OPERAND (t, 0);
7904 : }
7905 2162 : tree n = omp_clause_decl_field (t);
7906 2162 : if (n)
7907 59 : t = n;
7908 2162 : goto check_dup_generic_t;
7909 : }
7910 7275 : if (oacc_async)
7911 7 : cxx_mark_addressable (t);
7912 7275 : goto check_dup_generic;
7913 98 : case OMP_CLAUSE_COPYPRIVATE:
7914 98 : copyprivate_seen = true;
7915 98 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7916 98 : goto check_dup_generic;
7917 277 : case OMP_CLAUSE_COPYIN:
7918 277 : goto check_dup_generic;
7919 1631 : case OMP_CLAUSE_LINEAR:
7920 1631 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7921 1631 : t = OMP_CLAUSE_DECL (c);
7922 1631 : if (ort != C_ORT_OMP_DECLARE_SIMD
7923 1631 : && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
7924 : {
7925 84 : if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
7926 : {
7927 42 : error_at (OMP_CLAUSE_LOCATION (c),
7928 : "modifier should not be specified in %<linear%> "
7929 : "clause on %<simd%> or %<for%> constructs when "
7930 : "not using OpenMP 5.2 modifiers");
7931 42 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
7932 : }
7933 42 : else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_VAL)
7934 : {
7935 18 : error_at (OMP_CLAUSE_LOCATION (c),
7936 : "modifier other than %<val%> specified in "
7937 : "%<linear%> clause on %<simd%> or %<for%> "
7938 : "constructs when using OpenMP 5.2 modifiers");
7939 18 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
7940 : }
7941 : }
7942 1011 : if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
7943 2571 : && !type_dependent_expression_p (t))
7944 : {
7945 1529 : tree type = TREE_TYPE (t);
7946 1529 : if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
7947 1448 : || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL)
7948 1598 : && !TYPE_REF_P (type))
7949 : {
7950 12 : error_at (OMP_CLAUSE_LOCATION (c),
7951 : "linear clause with %qs modifier applied to "
7952 : "non-reference variable with %qT type",
7953 12 : OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
7954 12 : ? "ref" : "uval", TREE_TYPE (t));
7955 12 : remove = true;
7956 12 : break;
7957 : }
7958 1517 : if (TYPE_REF_P (type))
7959 281 : type = TREE_TYPE (type);
7960 1517 : if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
7961 : {
7962 1442 : if (!INTEGRAL_TYPE_P (type)
7963 85 : && !TYPE_PTR_P (type))
7964 : {
7965 18 : error_at (OMP_CLAUSE_LOCATION (c),
7966 : "linear clause applied to non-integral "
7967 : "non-pointer variable with %qT type",
7968 18 : TREE_TYPE (t));
7969 18 : remove = true;
7970 18 : break;
7971 : }
7972 : }
7973 : }
7974 1601 : t = OMP_CLAUSE_LINEAR_STEP (c);
7975 1601 : if (t == NULL_TREE)
7976 6 : t = integer_one_node;
7977 1601 : if (t == error_mark_node)
7978 : {
7979 : remove = true;
7980 : break;
7981 : }
7982 1601 : else if (!type_dependent_expression_p (t)
7983 1599 : && !INTEGRAL_TYPE_P (TREE_TYPE (t))
7984 1613 : && (ort != C_ORT_OMP_DECLARE_SIMD
7985 9 : || TREE_CODE (t) != PARM_DECL
7986 6 : || !TYPE_REF_P (TREE_TYPE (t))
7987 6 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
7988 : {
7989 6 : error_at (OMP_CLAUSE_LOCATION (c),
7990 : "linear step expression must be integral");
7991 6 : remove = true;
7992 6 : break;
7993 : }
7994 : else
7995 : {
7996 1595 : t = mark_rvalue_use (t);
7997 1595 : if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL)
7998 : {
7999 42 : OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
8000 42 : goto check_dup_generic;
8001 : }
8002 1553 : if (!processing_template_decl
8003 1553 : && (VAR_P (OMP_CLAUSE_DECL (c))
8004 835 : || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
8005 : {
8006 1372 : if (ort == C_ORT_OMP_DECLARE_SIMD)
8007 : {
8008 589 : t = maybe_constant_value (t);
8009 589 : if (TREE_CODE (t) != INTEGER_CST)
8010 : {
8011 6 : error_at (OMP_CLAUSE_LOCATION (c),
8012 : "%<linear%> clause step %qE is neither "
8013 : "constant nor a parameter", t);
8014 6 : remove = true;
8015 6 : break;
8016 : }
8017 : }
8018 1366 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8019 1366 : tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
8020 1366 : if (TYPE_REF_P (type))
8021 257 : type = TREE_TYPE (type);
8022 1366 : if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
8023 : {
8024 66 : type = build_pointer_type (type);
8025 66 : tree d = fold_convert (type, OMP_CLAUSE_DECL (c));
8026 66 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8027 : d, t);
8028 66 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8029 : MINUS_EXPR, sizetype,
8030 : fold_convert (sizetype, t),
8031 : fold_convert (sizetype, d));
8032 66 : if (t == error_mark_node)
8033 : {
8034 : remove = true;
8035 : break;
8036 : }
8037 : }
8038 1300 : else if (TYPE_PTR_P (type)
8039 : /* Can't multiply the step yet if *this
8040 : is still incomplete type. */
8041 1300 : && (ort != C_ORT_OMP_DECLARE_SIMD
8042 45 : || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
8043 45 : || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
8044 30 : || DECL_NAME (OMP_CLAUSE_DECL (c))
8045 30 : != this_identifier
8046 30 : || !TYPE_BEING_DEFINED (TREE_TYPE (type))))
8047 : {
8048 37 : tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
8049 37 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8050 : d, t);
8051 37 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8052 : MINUS_EXPR, sizetype,
8053 : fold_convert (sizetype, t),
8054 : fold_convert (sizetype, d));
8055 37 : if (t == error_mark_node)
8056 : {
8057 : remove = true;
8058 : break;
8059 : }
8060 : }
8061 : else
8062 1263 : t = fold_convert (type, t);
8063 : }
8064 1547 : OMP_CLAUSE_LINEAR_STEP (c) = t;
8065 : }
8066 1547 : goto check_dup_generic;
8067 14881 : check_dup_generic:
8068 14881 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8069 14881 : if (t)
8070 : {
8071 101 : if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED)
8072 101 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8073 : }
8074 : else
8075 14780 : t = OMP_CLAUSE_DECL (c);
8076 17310 : check_dup_generic_t:
8077 17310 : if (t == current_class_ptr
8078 17310 : && ((ort != C_ORT_OMP_DECLARE_SIMD && !openacc)
8079 102 : || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
8080 72 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
8081 : {
8082 24 : error_at (OMP_CLAUSE_LOCATION (c),
8083 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8084 : " clauses");
8085 24 : remove = true;
8086 24 : break;
8087 : }
8088 17286 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8089 586 : && (!field_ok || TREE_CODE (t) != FIELD_DECL))
8090 : {
8091 59 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8092 : break;
8093 39 : if (DECL_P (t))
8094 30 : error_at (OMP_CLAUSE_LOCATION (c),
8095 : "%qD is not a variable in clause %qs", t,
8096 15 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8097 : else
8098 48 : error_at (OMP_CLAUSE_LOCATION (c),
8099 : "%qE is not a variable in clause %qs", t,
8100 24 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8101 : remove = true;
8102 : }
8103 17227 : else if ((openacc
8104 2707 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
8105 14758 : || (ort == C_ORT_OMP
8106 12427 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
8107 12396 : || (OMP_CLAUSE_CODE (c)
8108 : == OMP_CLAUSE_USE_DEVICE_ADDR)))
8109 31878 : || (ort == C_ORT_OMP_TARGET
8110 936 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION))
8111 : {
8112 2854 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8113 2854 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8114 275 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))))
8115 : {
8116 6 : error_at (OMP_CLAUSE_LOCATION (c),
8117 : "%qD appears more than once in data-sharing "
8118 : "clauses", t);
8119 6 : remove = true;
8120 6 : break;
8121 : }
8122 2848 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
8123 272 : target_in_reduction_seen = true;
8124 2848 : if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8125 : {
8126 12 : error_at (OMP_CLAUSE_LOCATION (c),
8127 : openacc
8128 : ? "%qD appears more than once in reduction clauses"
8129 : : "%qD appears more than once in data clauses",
8130 : t);
8131 6 : remove = true;
8132 : }
8133 : else
8134 2842 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8135 : }
8136 14373 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8137 14298 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8138 14295 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t))
8139 28668 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8140 : {
8141 78 : error_at (OMP_CLAUSE_LOCATION (c),
8142 : "%qD appears more than once in data clauses", t);
8143 78 : remove = true;
8144 : }
8145 14295 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
8146 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
8147 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
8148 3115 : && bitmap_bit_p (&map_head, DECL_UID (t)))
8149 : {
8150 9 : if (openacc)
8151 0 : error_at (OMP_CLAUSE_LOCATION (c),
8152 : "%qD appears more than once in data clauses", t);
8153 : else
8154 9 : error_at (OMP_CLAUSE_LOCATION (c),
8155 : "%qD appears both in data and map clauses", t);
8156 : remove = true;
8157 : }
8158 : else
8159 14286 : bitmap_set_bit (&generic_head, DECL_UID (t));
8160 17260 : if (!field_ok)
8161 : break;
8162 12852 : handle_field_decl:
8163 21366 : if (!remove
8164 21169 : && TREE_CODE (t) == FIELD_DECL
8165 16494 : && t == OMP_CLAUSE_DECL (c))
8166 : {
8167 795 : OMP_CLAUSE_DECL (c)
8168 795 : = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
8169 : == OMP_CLAUSE_SHARED));
8170 795 : if (OMP_CLAUSE_DECL (c) == error_mark_node)
8171 97104 : remove = true;
8172 : }
8173 : break;
8174 :
8175 3473 : case OMP_CLAUSE_FIRSTPRIVATE:
8176 3473 : if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved)
8177 : {
8178 447 : move_implicit:
8179 447 : implicit_moved = true;
8180 : /* Move firstprivate and map clauses with
8181 : OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of
8182 : clauses chain. */
8183 447 : tree cl1 = NULL_TREE, cl2 = NULL_TREE;
8184 447 : tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2;
8185 2804 : while (*pc1)
8186 2357 : if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE
8187 2357 : && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1))
8188 : {
8189 275 : *pc3 = *pc1;
8190 275 : pc3 = &OMP_CLAUSE_CHAIN (*pc3);
8191 275 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8192 : }
8193 2082 : else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP
8194 2082 : && OMP_CLAUSE_MAP_IMPLICIT (*pc1))
8195 : {
8196 403 : *pc2 = *pc1;
8197 403 : pc2 = &OMP_CLAUSE_CHAIN (*pc2);
8198 403 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8199 : }
8200 : else
8201 1679 : pc1 = &OMP_CLAUSE_CHAIN (*pc1);
8202 447 : *pc3 = NULL;
8203 447 : *pc2 = cl2;
8204 447 : *pc1 = cl1;
8205 447 : continue;
8206 447 : }
8207 3216 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8208 3216 : if (t)
8209 69 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8210 : else
8211 3147 : t = OMP_CLAUSE_DECL (c);
8212 3216 : if (!openacc && t == current_class_ptr)
8213 : {
8214 6 : error_at (OMP_CLAUSE_LOCATION (c),
8215 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8216 : " clauses");
8217 6 : remove = true;
8218 6 : break;
8219 : }
8220 3210 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8221 333 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8222 333 : || TREE_CODE (t) != FIELD_DECL))
8223 : {
8224 41 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8225 : break;
8226 18 : if (DECL_P (t))
8227 12 : error_at (OMP_CLAUSE_LOCATION (c),
8228 : "%qD is not a variable in clause %<firstprivate%>",
8229 : t);
8230 : else
8231 6 : error_at (OMP_CLAUSE_LOCATION (c),
8232 : "%qE is not a variable in clause %<firstprivate%>",
8233 : t);
8234 18 : remove = true;
8235 : }
8236 3169 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8237 275 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c)
8238 3423 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8239 : remove = true;
8240 3169 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8241 3160 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8242 6326 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8243 : {
8244 15 : error_at (OMP_CLAUSE_LOCATION (c),
8245 : "%qD appears more than once in data clauses", t);
8246 15 : remove = true;
8247 : }
8248 3154 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
8249 3154 : || bitmap_bit_p (&map_field_head, DECL_UID (t)))
8250 : {
8251 21 : if (openacc)
8252 0 : error_at (OMP_CLAUSE_LOCATION (c),
8253 : "%qD appears more than once in data clauses", t);
8254 21 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8255 21 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c))
8256 : /* Silently drop the clause. */;
8257 : else
8258 18 : error_at (OMP_CLAUSE_LOCATION (c),
8259 : "%qD appears both in data and map clauses", t);
8260 21 : remove = true;
8261 : }
8262 : else
8263 3133 : bitmap_set_bit (&firstprivate_head, DECL_UID (t));
8264 3187 : goto handle_field_decl;
8265 :
8266 2790 : case OMP_CLAUSE_LASTPRIVATE:
8267 2790 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8268 2790 : if (t)
8269 35 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8270 : else
8271 2755 : t = OMP_CLAUSE_DECL (c);
8272 2790 : if (!openacc && t == current_class_ptr)
8273 : {
8274 6 : error_at (OMP_CLAUSE_LOCATION (c),
8275 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8276 : " clauses");
8277 6 : remove = true;
8278 6 : break;
8279 : }
8280 2784 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8281 259 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8282 259 : || TREE_CODE (t) != FIELD_DECL))
8283 : {
8284 35 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8285 : break;
8286 9 : if (DECL_P (t))
8287 3 : error_at (OMP_CLAUSE_LOCATION (c),
8288 : "%qD is not a variable in clause %<lastprivate%>",
8289 : t);
8290 : else
8291 6 : error_at (OMP_CLAUSE_LOCATION (c),
8292 : "%qE is not a variable in clause %<lastprivate%>",
8293 : t);
8294 9 : remove = true;
8295 : }
8296 2749 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8297 2749 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8298 : {
8299 12 : error_at (OMP_CLAUSE_LOCATION (c),
8300 : "%qD appears more than once in data clauses", t);
8301 12 : remove = true;
8302 : }
8303 : else
8304 2737 : bitmap_set_bit (&lastprivate_head, DECL_UID (t));
8305 2758 : goto handle_field_decl;
8306 :
8307 2218 : case OMP_CLAUSE_IF:
8308 2218 : case OMP_CLAUSE_SELF:
8309 2218 : t = OMP_CLAUSE_OPERAND (c, 0);
8310 2218 : t = maybe_convert_cond (t);
8311 2218 : if (t == error_mark_node)
8312 : remove = true;
8313 2203 : else if (!processing_template_decl)
8314 2142 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8315 2218 : OMP_CLAUSE_OPERAND (c, 0) = t;
8316 2218 : break;
8317 :
8318 289 : case OMP_CLAUSE_FINAL:
8319 289 : t = OMP_CLAUSE_FINAL_EXPR (c);
8320 289 : t = maybe_convert_cond (t);
8321 289 : if (t == error_mark_node)
8322 : remove = true;
8323 289 : else if (!processing_template_decl)
8324 283 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8325 289 : OMP_CLAUSE_FINAL_EXPR (c) = t;
8326 289 : break;
8327 :
8328 92 : case OMP_CLAUSE_NOCONTEXT:
8329 92 : t = OMP_CLAUSE_NOCONTEXT_EXPR (c);
8330 92 : t = maybe_convert_cond (t);
8331 92 : if (t == error_mark_node)
8332 : remove = true;
8333 89 : else if (!processing_template_decl)
8334 83 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8335 92 : OMP_CLAUSE_NOCONTEXT_EXPR (c) = t;
8336 92 : break;
8337 :
8338 80 : case OMP_CLAUSE_NOVARIANTS:
8339 80 : t = OMP_CLAUSE_NOVARIANTS_EXPR (c);
8340 80 : t = maybe_convert_cond (t);
8341 80 : if (t == error_mark_node)
8342 : remove = true;
8343 77 : else if (!processing_template_decl)
8344 71 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8345 80 : OMP_CLAUSE_NOVARIANTS_EXPR (c) = t;
8346 80 : break;
8347 :
8348 1249 : case OMP_CLAUSE_GANG:
8349 : /* Operand 1 is the gang static: argument. */
8350 1249 : t = OMP_CLAUSE_OPERAND (c, 1);
8351 1249 : if (t != NULL_TREE)
8352 : {
8353 129 : if (t == error_mark_node)
8354 : remove = true;
8355 129 : else if (!type_dependent_expression_p (t)
8356 129 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8357 : {
8358 6 : error_at (OMP_CLAUSE_LOCATION (c),
8359 : "%<gang%> static expression must be integral");
8360 6 : remove = true;
8361 : }
8362 : else
8363 : {
8364 123 : t = mark_rvalue_use (t);
8365 123 : if (!processing_template_decl)
8366 : {
8367 123 : t = maybe_constant_value (t);
8368 123 : if (TREE_CODE (t) == INTEGER_CST
8369 109 : && tree_int_cst_sgn (t) != 1
8370 176 : && t != integer_minus_one_node)
8371 : {
8372 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8373 : "%<gang%> static value must be "
8374 : "positive");
8375 0 : t = integer_one_node;
8376 : }
8377 123 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8378 : }
8379 : }
8380 129 : OMP_CLAUSE_OPERAND (c, 1) = t;
8381 : }
8382 : /* Check operand 0, the num argument. */
8383 : /* FALLTHRU */
8384 :
8385 3480 : case OMP_CLAUSE_WORKER:
8386 3480 : case OMP_CLAUSE_VECTOR:
8387 3480 : if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
8388 : break;
8389 : /* FALLTHRU */
8390 :
8391 484 : case OMP_CLAUSE_NUM_TASKS:
8392 484 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TASKS)
8393 136 : num_tasks_seen = true;
8394 : /* FALLTHRU */
8395 :
8396 3034 : case OMP_CLAUSE_NUM_TEAMS:
8397 3034 : case OMP_CLAUSE_NUM_THREADS:
8398 3034 : case OMP_CLAUSE_NUM_GANGS:
8399 3034 : case OMP_CLAUSE_NUM_WORKERS:
8400 3034 : case OMP_CLAUSE_DYN_GROUPPRIVATE:
8401 3034 : case OMP_CLAUSE_VECTOR_LENGTH:
8402 3034 : t = OMP_CLAUSE_OPERAND (c, 0);
8403 3034 : if (t == error_mark_node)
8404 : remove = true;
8405 3034 : else if (!type_dependent_expression_p (t)
8406 3034 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8407 : {
8408 99 : switch (OMP_CLAUSE_CODE (c))
8409 : {
8410 12 : case OMP_CLAUSE_GANG:
8411 12 : error_at (OMP_CLAUSE_LOCATION (c),
8412 12 : "%<gang%> num expression must be integral"); break;
8413 12 : case OMP_CLAUSE_VECTOR:
8414 12 : error_at (OMP_CLAUSE_LOCATION (c),
8415 : "%<vector%> length expression must be integral");
8416 12 : break;
8417 12 : case OMP_CLAUSE_WORKER:
8418 12 : error_at (OMP_CLAUSE_LOCATION (c),
8419 : "%<worker%> num expression must be integral");
8420 12 : break;
8421 63 : default:
8422 63 : error_at (OMP_CLAUSE_LOCATION (c),
8423 : "%qs expression must be integral",
8424 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8425 : }
8426 : remove = true;
8427 : }
8428 : else
8429 : {
8430 2935 : t = mark_rvalue_use (t);
8431 2935 : if (!processing_template_decl)
8432 : {
8433 2687 : t = maybe_constant_value (t);
8434 2687 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
8435 2652 : && TREE_CODE (t) == INTEGER_CST
8436 4142 : && tree_int_cst_sgn (t) != 1)
8437 : {
8438 85 : switch (OMP_CLAUSE_CODE (c))
8439 : {
8440 3 : case OMP_CLAUSE_GANG:
8441 3 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8442 : "%<gang%> num value must be positive");
8443 3 : break;
8444 0 : case OMP_CLAUSE_VECTOR:
8445 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8446 : "%<vector%> length value must be "
8447 : "positive");
8448 0 : break;
8449 0 : case OMP_CLAUSE_WORKER:
8450 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8451 : "%<worker%> num value must be "
8452 : "positive");
8453 0 : break;
8454 82 : default:
8455 82 : warning_at (OMP_CLAUSE_LOCATION (c),
8456 46 : (flag_openmp || flag_openmp_simd)
8457 82 : ? OPT_Wopenmp : 0,
8458 : "%qs value must be positive",
8459 : omp_clause_code_name
8460 82 : [OMP_CLAUSE_CODE (c)]);
8461 : }
8462 85 : t = integer_one_node;
8463 : }
8464 2602 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
8465 35 : && TREE_CODE (t) == INTEGER_CST
8466 2625 : && tree_int_cst_sgn (t) < 0)
8467 : {
8468 8 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8469 : "%<dyn_groupprivate%> value must be "
8470 : "non-negative");
8471 8 : t = integer_zero_node;
8472 : }
8473 2687 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8474 : }
8475 2935 : OMP_CLAUSE_OPERAND (c, 0) = t;
8476 : }
8477 3034 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
8478 752 : && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
8479 3313 : && !remove)
8480 : {
8481 279 : t = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
8482 279 : if (t == error_mark_node)
8483 : remove = true;
8484 279 : else if (!type_dependent_expression_p (t)
8485 279 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8486 : {
8487 0 : error_at (OMP_CLAUSE_LOCATION (c),
8488 : "%qs expression must be integral",
8489 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8490 0 : remove = true;
8491 : }
8492 : else
8493 : {
8494 279 : t = mark_rvalue_use (t);
8495 279 : if (!processing_template_decl)
8496 : {
8497 213 : t = maybe_constant_value (t);
8498 213 : if (TREE_CODE (t) == INTEGER_CST
8499 213 : && tree_int_cst_sgn (t) != 1)
8500 : {
8501 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8502 : "%qs value must be positive",
8503 : omp_clause_code_name
8504 18 : [OMP_CLAUSE_CODE (c)]);
8505 18 : t = NULL_TREE;
8506 : }
8507 : else
8508 195 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8509 213 : tree upper = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
8510 213 : if (t
8511 195 : && TREE_CODE (t) == INTEGER_CST
8512 43 : && TREE_CODE (upper) == INTEGER_CST
8513 250 : && tree_int_cst_lt (upper, t))
8514 : {
8515 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8516 : "%<num_teams%> lower bound %qE bigger "
8517 : "than upper bound %qE", t, upper);
8518 18 : t = NULL_TREE;
8519 : }
8520 : }
8521 279 : OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = t;
8522 : }
8523 : }
8524 : break;
8525 :
8526 3862 : case OMP_CLAUSE_SCHEDULE:
8527 3862 : t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
8528 3862 : if (t == NULL)
8529 : ;
8530 2078 : else if (t == error_mark_node)
8531 : remove = true;
8532 2078 : else if (!type_dependent_expression_p (t)
8533 2078 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8534 : {
8535 9 : error_at (OMP_CLAUSE_LOCATION (c),
8536 : "schedule chunk size expression must be integral");
8537 9 : remove = true;
8538 : }
8539 : else
8540 : {
8541 2069 : t = mark_rvalue_use (t);
8542 2069 : if (!processing_template_decl)
8543 : {
8544 2029 : t = maybe_constant_value (t);
8545 2029 : if (TREE_CODE (t) == INTEGER_CST
8546 2029 : && tree_int_cst_sgn (t) != 1)
8547 : {
8548 6 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8549 : "chunk size value must be positive");
8550 6 : t = integer_one_node;
8551 : }
8552 2029 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8553 : }
8554 2069 : OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
8555 : }
8556 2078 : if (!remove)
8557 : schedule_seen = true;
8558 : break;
8559 :
8560 1268 : case OMP_CLAUSE_SIMDLEN:
8561 1268 : case OMP_CLAUSE_SAFELEN:
8562 1268 : t = OMP_CLAUSE_OPERAND (c, 0);
8563 1268 : if (t == error_mark_node)
8564 : remove = true;
8565 1268 : else if (!type_dependent_expression_p (t)
8566 1268 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8567 : {
8568 0 : error_at (OMP_CLAUSE_LOCATION (c),
8569 : "%qs length expression must be integral",
8570 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8571 0 : remove = true;
8572 : }
8573 : else
8574 : {
8575 1268 : t = mark_rvalue_use (t);
8576 1268 : if (!processing_template_decl)
8577 : {
8578 1219 : t = maybe_constant_value (t);
8579 1219 : if (TREE_CODE (t) != INTEGER_CST
8580 1219 : || tree_int_cst_sgn (t) != 1)
8581 : {
8582 0 : error_at (OMP_CLAUSE_LOCATION (c),
8583 : "%qs length expression must be positive "
8584 : "constant integer expression",
8585 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8586 0 : remove = true;
8587 : }
8588 : }
8589 1268 : OMP_CLAUSE_OPERAND (c, 0) = t;
8590 1268 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN)
8591 470 : safelen = c;
8592 : }
8593 : break;
8594 :
8595 388 : case OMP_CLAUSE_ASYNC:
8596 388 : t = OMP_CLAUSE_ASYNC_EXPR (c);
8597 388 : if (t == error_mark_node)
8598 : remove = true;
8599 373 : else if (!type_dependent_expression_p (t)
8600 373 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8601 : {
8602 12 : error_at (OMP_CLAUSE_LOCATION (c),
8603 : "%<async%> expression must be integral");
8604 12 : remove = true;
8605 : }
8606 : else
8607 : {
8608 361 : t = mark_rvalue_use (t);
8609 361 : if (!processing_template_decl)
8610 352 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8611 361 : OMP_CLAUSE_ASYNC_EXPR (c) = t;
8612 : }
8613 : break;
8614 :
8615 204 : case OMP_CLAUSE_WAIT:
8616 204 : t = OMP_CLAUSE_WAIT_EXPR (c);
8617 204 : if (t == error_mark_node)
8618 : remove = true;
8619 204 : else if (!processing_template_decl)
8620 196 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8621 204 : OMP_CLAUSE_WAIT_EXPR (c) = t;
8622 204 : break;
8623 :
8624 637 : case OMP_CLAUSE_THREAD_LIMIT:
8625 637 : t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
8626 637 : if (t == error_mark_node)
8627 : remove = true;
8628 637 : else if (!type_dependent_expression_p (t)
8629 637 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8630 : {
8631 0 : error_at (OMP_CLAUSE_LOCATION (c),
8632 : "%<thread_limit%> expression must be integral");
8633 0 : remove = true;
8634 : }
8635 : else
8636 : {
8637 637 : t = mark_rvalue_use (t);
8638 637 : if (!processing_template_decl)
8639 : {
8640 583 : t = maybe_constant_value (t);
8641 583 : if (TREE_CODE (t) == INTEGER_CST
8642 583 : && tree_int_cst_sgn (t) != 1)
8643 : {
8644 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8645 : "%<thread_limit%> value must be positive");
8646 0 : t = integer_one_node;
8647 : }
8648 583 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8649 : }
8650 637 : OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
8651 : }
8652 : break;
8653 :
8654 770 : case OMP_CLAUSE_DEVICE:
8655 770 : t = OMP_CLAUSE_DEVICE_ID (c);
8656 770 : if (t == error_mark_node)
8657 : remove = true;
8658 770 : else if (!type_dependent_expression_p (t)
8659 770 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8660 : {
8661 6 : error_at (OMP_CLAUSE_LOCATION (c),
8662 : "%<device%> id must be integral");
8663 6 : remove = true;
8664 : }
8665 764 : else if (OMP_CLAUSE_DEVICE_ANCESTOR (c)
8666 66 : && TREE_CODE (t) == INTEGER_CST
8667 824 : && !integer_onep (t))
8668 : {
8669 3 : error_at (OMP_CLAUSE_LOCATION (c),
8670 : "the %<device%> clause expression must evaluate to "
8671 : "%<1%>");
8672 3 : remove = true;
8673 : }
8674 : else
8675 : {
8676 761 : t = mark_rvalue_use (t);
8677 761 : if (!processing_template_decl)
8678 750 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8679 761 : OMP_CLAUSE_DEVICE_ID (c) = t;
8680 : }
8681 : break;
8682 :
8683 1836 : case OMP_CLAUSE_DIST_SCHEDULE:
8684 1836 : t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c);
8685 1836 : if (t == NULL)
8686 : ;
8687 1815 : else if (t == error_mark_node)
8688 : remove = true;
8689 1815 : else if (!type_dependent_expression_p (t)
8690 1815 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8691 : {
8692 0 : error_at (OMP_CLAUSE_LOCATION (c),
8693 : "%<dist_schedule%> chunk size expression must be "
8694 : "integral");
8695 0 : remove = true;
8696 : }
8697 : else
8698 : {
8699 1815 : t = mark_rvalue_use (t);
8700 1815 : if (!processing_template_decl)
8701 1815 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8702 1815 : OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
8703 : }
8704 : break;
8705 :
8706 807 : case OMP_CLAUSE_ALIGNED:
8707 807 : t = OMP_CLAUSE_DECL (c);
8708 807 : if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD)
8709 : {
8710 0 : error_at (OMP_CLAUSE_LOCATION (c),
8711 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8712 : " clauses");
8713 0 : remove = true;
8714 0 : break;
8715 : }
8716 807 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8717 : {
8718 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8719 : break;
8720 0 : if (DECL_P (t))
8721 0 : error_at (OMP_CLAUSE_LOCATION (c),
8722 : "%qD is not a variable in %<aligned%> clause", t);
8723 : else
8724 0 : error_at (OMP_CLAUSE_LOCATION (c),
8725 : "%qE is not a variable in %<aligned%> clause", t);
8726 : remove = true;
8727 : }
8728 807 : else if (!type_dependent_expression_p (t)
8729 789 : && !TYPE_PTR_P (TREE_TYPE (t))
8730 111 : && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
8731 864 : && (!TYPE_REF_P (TREE_TYPE (t))
8732 39 : || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
8733 30 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
8734 : != ARRAY_TYPE))))
8735 : {
8736 33 : error_at (OMP_CLAUSE_LOCATION (c),
8737 : "%qE in %<aligned%> clause is neither a pointer nor "
8738 : "an array nor a reference to pointer or array", t);
8739 33 : remove = true;
8740 : }
8741 774 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8742 : {
8743 0 : error_at (OMP_CLAUSE_LOCATION (c),
8744 : "%qD appears more than once in %<aligned%> clauses",
8745 : t);
8746 0 : remove = true;
8747 : }
8748 : else
8749 774 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8750 807 : t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c);
8751 807 : if (t == error_mark_node)
8752 : remove = true;
8753 807 : else if (t == NULL_TREE)
8754 : break;
8755 744 : else if (!type_dependent_expression_p (t)
8756 744 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8757 : {
8758 0 : error_at (OMP_CLAUSE_LOCATION (c),
8759 : "%<aligned%> clause alignment expression must "
8760 : "be integral");
8761 0 : remove = true;
8762 : }
8763 : else
8764 : {
8765 744 : t = mark_rvalue_use (t);
8766 744 : if (!processing_template_decl)
8767 : {
8768 690 : t = maybe_constant_value (t);
8769 690 : if (TREE_CODE (t) != INTEGER_CST
8770 690 : || tree_int_cst_sgn (t) != 1)
8771 : {
8772 0 : error_at (OMP_CLAUSE_LOCATION (c),
8773 : "%<aligned%> clause alignment expression must "
8774 : "be positive constant integer expression");
8775 0 : remove = true;
8776 : }
8777 : }
8778 744 : OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t;
8779 : }
8780 : break;
8781 :
8782 369 : case OMP_CLAUSE_NONTEMPORAL:
8783 369 : t = OMP_CLAUSE_DECL (c);
8784 369 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8785 : {
8786 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8787 : break;
8788 0 : if (DECL_P (t))
8789 0 : error_at (OMP_CLAUSE_LOCATION (c),
8790 : "%qD is not a variable in %<nontemporal%> clause",
8791 : t);
8792 : else
8793 0 : error_at (OMP_CLAUSE_LOCATION (c),
8794 : "%qE is not a variable in %<nontemporal%> clause",
8795 : t);
8796 : remove = true;
8797 : }
8798 369 : else if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8799 : {
8800 6 : error_at (OMP_CLAUSE_LOCATION (c),
8801 : "%qD appears more than once in %<nontemporal%> "
8802 : "clauses", t);
8803 6 : remove = true;
8804 : }
8805 : else
8806 363 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8807 : break;
8808 :
8809 2585 : case OMP_CLAUSE_ALLOCATE:
8810 2585 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8811 2585 : if (t)
8812 14 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8813 : else
8814 2571 : t = OMP_CLAUSE_DECL (c);
8815 2585 : if (t == current_class_ptr)
8816 : {
8817 0 : error_at (OMP_CLAUSE_LOCATION (c),
8818 : "%<this%> not allowed in %<allocate%> clause");
8819 0 : remove = true;
8820 0 : break;
8821 : }
8822 2585 : if (!VAR_P (t)
8823 558 : && TREE_CODE (t) != PARM_DECL
8824 45 : && TREE_CODE (t) != FIELD_DECL)
8825 : {
8826 3 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8827 : break;
8828 3 : if (DECL_P (t))
8829 3 : error_at (OMP_CLAUSE_LOCATION (c),
8830 : "%qD is not a variable in %<allocate%> clause", t);
8831 : else
8832 0 : error_at (OMP_CLAUSE_LOCATION (c),
8833 : "%qE is not a variable in %<allocate%> clause", t);
8834 : remove = true;
8835 : }
8836 2582 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8837 : {
8838 12 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8839 : "%qD appears more than once in %<allocate%> clauses",
8840 : t);
8841 12 : remove = true;
8842 : }
8843 : else
8844 : {
8845 2570 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8846 2570 : allocate_seen = true;
8847 : }
8848 2585 : tree allocator, align;
8849 2585 : align = OMP_CLAUSE_ALLOCATE_ALIGN (c);
8850 2585 : if (error_operand_p (align))
8851 : {
8852 : remove = true;
8853 : break;
8854 : }
8855 2585 : if (align)
8856 : {
8857 207 : if (!type_dependent_expression_p (align)
8858 207 : && !INTEGRAL_TYPE_P (TREE_TYPE (align)))
8859 : {
8860 4 : error_at (OMP_CLAUSE_LOCATION (c),
8861 : "%<allocate%> clause %<align%> modifier "
8862 : "argument needs to be positive constant "
8863 : "power of two integer expression");
8864 4 : remove = true;
8865 : }
8866 : else
8867 : {
8868 203 : align = mark_rvalue_use (align);
8869 203 : if (!processing_template_decl)
8870 : {
8871 188 : align = maybe_constant_value (align);
8872 188 : if (TREE_CODE (align) != INTEGER_CST
8873 185 : || !tree_fits_uhwi_p (align)
8874 373 : || !integer_pow2p (align))
8875 : {
8876 10 : error_at (OMP_CLAUSE_LOCATION (c),
8877 : "%<allocate%> clause %<align%> modifier "
8878 : "argument needs to be positive constant "
8879 : "power of two integer expression");
8880 10 : remove = true;
8881 : }
8882 : }
8883 : }
8884 207 : OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
8885 : }
8886 2585 : allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
8887 2585 : if (error_operand_p (allocator))
8888 : {
8889 : remove = true;
8890 : break;
8891 : }
8892 2585 : if (allocator == NULL_TREE)
8893 1537 : goto handle_field_decl;
8894 1048 : tree allocatort;
8895 1048 : allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator));
8896 1048 : if (!type_dependent_expression_p (allocator)
8897 1048 : && (TREE_CODE (allocatort) != ENUMERAL_TYPE
8898 1029 : || TYPE_NAME (allocatort) == NULL_TREE
8899 1029 : || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL
8900 2058 : || (DECL_NAME (TYPE_NAME (allocatort))
8901 1029 : != get_identifier ("omp_allocator_handle_t"))
8902 1029 : || (TYPE_CONTEXT (allocatort)
8903 1029 : != DECL_CONTEXT (global_namespace))))
8904 : {
8905 16 : error_at (OMP_CLAUSE_LOCATION (c),
8906 : "%<allocate%> clause allocator expression has "
8907 : "type %qT rather than %<omp_allocator_handle_t%>",
8908 16 : TREE_TYPE (allocator));
8909 16 : remove = true;
8910 16 : break;
8911 : }
8912 : else
8913 : {
8914 1032 : allocator = mark_rvalue_use (allocator);
8915 1032 : if (!processing_template_decl)
8916 1013 : allocator = maybe_constant_value (allocator);
8917 1032 : OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
8918 : }
8919 1032 : goto handle_field_decl;
8920 :
8921 654 : case OMP_CLAUSE_DOACROSS:
8922 654 : t = OMP_CLAUSE_DECL (c);
8923 654 : if (t == NULL_TREE)
8924 : break;
8925 298 : if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
8926 : {
8927 298 : if (cp_finish_omp_clause_doacross_sink (c))
8928 12 : remove = true;
8929 : break;
8930 : }
8931 0 : gcc_unreachable ();
8932 141 : case OMP_CLAUSE_USES_ALLOCATORS:
8933 141 : t = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
8934 141 : t = convert_from_reference (t);
8935 141 : if (t == error_mark_node)
8936 : {
8937 : remove = true;
8938 : break;
8939 : }
8940 129 : if (DECL_P (t)
8941 129 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8942 120 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8943 117 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
8944 : {
8945 3 : error_at (OMP_CLAUSE_LOCATION (c),
8946 : "%qE appears more than once in data clauses", t);
8947 3 : remove = true;
8948 : }
8949 126 : else if (DECL_P (t))
8950 117 : bitmap_set_bit (&generic_head, DECL_UID (t));
8951 129 : if (type_dependent_expression_p (t))
8952 : break;
8953 114 : if (TREE_CODE (t) == FIELD_DECL)
8954 : {
8955 0 : sorry_at (OMP_CLAUSE_LOCATION (c), "class member %qE not yet "
8956 : "supported in %<uses_allocators%> clause", t);
8957 0 : remove = true;
8958 0 : break;
8959 : }
8960 114 : if (TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
8961 219 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
8962 : "omp_allocator_handle_t") != 0)
8963 : {
8964 9 : error_at (OMP_CLAUSE_LOCATION (c),
8965 : "allocator %qE must be of %<omp_allocator_handle_t%> "
8966 : "type", t);
8967 9 : remove = true;
8968 9 : break;
8969 : }
8970 105 : tree init;
8971 105 : if (TREE_CODE (t) == CONST_DECL)
8972 15 : init = DECL_INITIAL(t);
8973 : else
8974 : init = t;
8975 105 : if (!DECL_P (t)
8976 105 : && (init == NULL_TREE
8977 9 : || TREE_CODE (init) != INTEGER_CST
8978 9 : || ((wi::to_widest (init) < 0
8979 9 : || wi::to_widest (init) > GOMP_OMP_PREDEF_ALLOC_MAX)
8980 3 : && (wi::to_widest (init) < GOMP_OMPX_PREDEF_ALLOC_MIN
8981 3 : || (wi::to_widest (init)
8982 6 : > GOMP_OMPX_PREDEF_ALLOC_MAX)))))
8983 : {
8984 3 : remove = true;
8985 3 : error_at (OMP_CLAUSE_LOCATION (c),
8986 : "allocator %qE must be either a variable or a "
8987 : "predefined allocator", t);
8988 3 : break;
8989 : }
8990 102 : else if (TREE_CODE (t) == CONST_DECL)
8991 : {
8992 : /* omp_null_allocator is ignored and for predefined allocators,
8993 : not special handling is required; thus, remove them removed. */
8994 15 : remove = true;
8995 :
8996 15 : if (OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c)
8997 15 : || OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c))
8998 : {
8999 0 : error_at (OMP_CLAUSE_LOCATION (c),
9000 : "modifiers cannot be used with predefined "
9001 : "allocators");
9002 0 : break;
9003 : }
9004 : }
9005 102 : t = OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c);
9006 102 : if (t == error_mark_node)
9007 : {
9008 : remove = true;
9009 : break;
9010 : }
9011 99 : if (t != NULL_TREE
9012 18 : && !type_dependent_expression_p (t)
9013 117 : && ((TREE_CODE (t) != CONST_DECL && TREE_CODE (t) != INTEGER_CST)
9014 15 : || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9015 24 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9016 : "omp_memspace_handle_t") != 0))
9017 : {
9018 6 : error_at (OMP_CLAUSE_LOCATION (c), "memspace modifier %qE must be"
9019 : " constant enum of %<omp_memspace_handle_t%> type", t);
9020 6 : remove = true;
9021 6 : break;
9022 : }
9023 93 : t = OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c);
9024 93 : if (t == error_mark_node)
9025 : {
9026 : remove = true;
9027 : break;
9028 : }
9029 90 : if (type_dependent_expression_p (t))
9030 : break;
9031 90 : if (t != NULL_TREE
9032 39 : && t != error_mark_node
9033 39 : && !type_dependent_expression_p (t)
9034 129 : && (!DECL_P (t)
9035 39 : || DECL_EXTERNAL (t)
9036 33 : || TREE_CODE (t) == PARM_DECL))
9037 : {
9038 12 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must be "
9039 : "defined in same scope as the construct on which the "
9040 : "clause appears", t);
9041 12 : remove = true;
9042 : }
9043 90 : if (t != NULL_TREE)
9044 : {
9045 39 : bool type_err = false;
9046 :
9047 39 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
9048 33 : || DECL_SIZE (t) == NULL_TREE
9049 69 : || !COMPLETE_TYPE_P (TREE_TYPE (t)))
9050 : type_err = true;
9051 : else
9052 : {
9053 30 : tree elem_t = TREE_TYPE (TREE_TYPE (t));
9054 30 : if (TREE_CODE (elem_t) != RECORD_TYPE
9055 60 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (elem_t)),
9056 : "omp_alloctrait_t") != 0
9057 60 : || !TYPE_READONLY (elem_t))
9058 : type_err = true;
9059 : }
9060 27 : if (type_err)
9061 : {
9062 12 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must "
9063 : "be of %<const omp_alloctrait_t []%> type", t);
9064 12 : remove = true;
9065 : }
9066 27 : else if (TREE_CODE (array_type_nelts_top (TREE_TYPE (t)))
9067 : != INTEGER_CST)
9068 : {
9069 3 : error_at (OMP_CLAUSE_LOCATION (c), "variable length traits "
9070 : "arrays are not supported");
9071 3 : remove = true;
9072 : }
9073 : else
9074 : {
9075 24 : tree cst_val = decl_constant_value (t);
9076 24 : if (cst_val == t)
9077 : {
9078 3 : error_at (OMP_CLAUSE_LOCATION (c), "traits array must be "
9079 : "initialized with constants");
9080 3 : remove = true;
9081 : }
9082 : }
9083 : }
9084 90 : if (remove)
9085 : break;
9086 54 : pc = &OMP_CLAUSE_CHAIN (c);
9087 54 : continue;
9088 1805 : case OMP_CLAUSE_DEPEND:
9089 1805 : depend_clause = c;
9090 : /* FALLTHRU */
9091 2171 : case OMP_CLAUSE_AFFINITY:
9092 2171 : t = OMP_CLAUSE_DECL (c);
9093 2171 : if (OMP_ITERATOR_DECL_P (t))
9094 : {
9095 622 : if (TREE_PURPOSE (t) != last_iterators)
9096 524 : last_iterators_remove
9097 524 : = cp_omp_finish_iterators (TREE_PURPOSE (t));
9098 622 : last_iterators = TREE_PURPOSE (t);
9099 622 : t = TREE_VALUE (t);
9100 622 : if (last_iterators_remove)
9101 144 : t = error_mark_node;
9102 : }
9103 : else
9104 : last_iterators = NULL_TREE;
9105 :
9106 2171 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9107 : {
9108 1164 : if (handle_omp_array_sections (c, ort))
9109 : remove = true;
9110 913 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9111 913 : && (OMP_CLAUSE_DEPEND_KIND (c)
9112 : == OMP_CLAUSE_DEPEND_DEPOBJ))
9113 : {
9114 6 : error_at (OMP_CLAUSE_LOCATION (c),
9115 : "%<depend%> clause with %<depobj%> dependence "
9116 : "type on array section");
9117 6 : remove = true;
9118 : }
9119 : break;
9120 : }
9121 1007 : if (t == error_mark_node)
9122 : remove = true;
9123 845 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9124 845 : && t == ridpointers[RID_OMP_ALL_MEMORY])
9125 : {
9126 33 : if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_OUT
9127 33 : && OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_INOUT)
9128 : {
9129 9 : error_at (OMP_CLAUSE_LOCATION (c),
9130 : "%<omp_all_memory%> used with %<depend%> kind "
9131 : "other than %<out%> or %<inout%>");
9132 9 : remove = true;
9133 : }
9134 33 : if (processing_template_decl)
9135 : break;
9136 : }
9137 812 : else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9138 : break;
9139 620 : else if (!lvalue_p (t))
9140 : {
9141 19 : if (DECL_P (t))
9142 24 : error_at (OMP_CLAUSE_LOCATION (c),
9143 : "%qD is not lvalue expression nor array section "
9144 : "in %qs clause", t,
9145 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9146 : else
9147 14 : error_at (OMP_CLAUSE_LOCATION (c),
9148 : "%qE is not lvalue expression nor array section "
9149 : "in %qs clause", t,
9150 7 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9151 : remove = true;
9152 : }
9153 601 : else if (TREE_CODE (t) == COMPONENT_REF
9154 24 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
9155 625 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
9156 : {
9157 8 : error_at (OMP_CLAUSE_LOCATION (c),
9158 : "bit-field %qE in %qs clause", t,
9159 4 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9160 4 : remove = true;
9161 : }
9162 597 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9163 597 : && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ)
9164 : {
9165 130 : if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9166 8 : ? TREE_TYPE (TREE_TYPE (t))
9167 57 : : TREE_TYPE (t)))
9168 : {
9169 12 : error_at (OMP_CLAUSE_LOCATION (c),
9170 : "%qE does not have %<omp_depend_t%> type in "
9171 : "%<depend%> clause with %<depobj%> dependence "
9172 : "type", t);
9173 12 : remove = true;
9174 : }
9175 : }
9176 532 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9177 972 : && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9178 4 : ? TREE_TYPE (TREE_TYPE (t))
9179 436 : : TREE_TYPE (t)))
9180 : {
9181 15 : error_at (OMP_CLAUSE_LOCATION (c),
9182 : "%qE should not have %<omp_depend_t%> type in "
9183 : "%<depend%> clause with dependence type other than "
9184 : "%<depobj%>", t);
9185 15 : remove = true;
9186 : }
9187 64 : if (!remove)
9188 : {
9189 594 : if (t == ridpointers[RID_OMP_ALL_MEMORY])
9190 24 : t = null_pointer_node;
9191 : else
9192 : {
9193 570 : tree addr = cp_build_addr_expr (t, tf_warning_or_error);
9194 570 : if (addr == error_mark_node)
9195 : {
9196 : remove = true;
9197 : break;
9198 : }
9199 570 : t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c),
9200 : addr, RO_UNARY_STAR,
9201 : tf_warning_or_error);
9202 570 : if (t == error_mark_node)
9203 : {
9204 : remove = true;
9205 : break;
9206 : }
9207 : }
9208 594 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST
9209 136 : && TREE_PURPOSE (OMP_CLAUSE_DECL (c))
9210 730 : && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c)))
9211 : == TREE_VEC))
9212 136 : TREE_VALUE (OMP_CLAUSE_DECL (c)) = t;
9213 : else
9214 458 : OMP_CLAUSE_DECL (c) = t;
9215 : }
9216 : break;
9217 69 : case OMP_CLAUSE_DETACH:
9218 69 : t = OMP_CLAUSE_DECL (c);
9219 69 : if (detach_seen)
9220 : {
9221 3 : error_at (OMP_CLAUSE_LOCATION (c),
9222 : "too many %qs clauses on a task construct",
9223 : "detach");
9224 3 : remove = true;
9225 3 : break;
9226 : }
9227 66 : else if (error_operand_p (t))
9228 : {
9229 : remove = true;
9230 : break;
9231 : }
9232 : else
9233 : {
9234 63 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
9235 63 : if (!type_dependent_expression_p (t)
9236 63 : && (!INTEGRAL_TYPE_P (type)
9237 : || TREE_CODE (type) != ENUMERAL_TYPE
9238 51 : || TYPE_NAME (type) == NULL_TREE
9239 102 : || (DECL_NAME (TYPE_NAME (type))
9240 51 : != get_identifier ("omp_event_handle_t"))))
9241 : {
9242 6 : error_at (OMP_CLAUSE_LOCATION (c),
9243 : "%<detach%> clause event handle "
9244 : "has type %qT rather than "
9245 : "%<omp_event_handle_t%>",
9246 : type);
9247 6 : remove = true;
9248 : }
9249 63 : detach_seen = c;
9250 63 : cxx_mark_addressable (t);
9251 : }
9252 63 : break;
9253 :
9254 15942 : case OMP_CLAUSE_MAP:
9255 15942 : if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved)
9256 190 : goto move_implicit;
9257 15752 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME
9258 15752 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POP_MAPPER_NAME)
9259 : {
9260 : remove = true;
9261 : break;
9262 : }
9263 : /* FALLTHRU */
9264 18870 : case OMP_CLAUSE_TO:
9265 18870 : case OMP_CLAUSE_FROM:
9266 18870 : if (OMP_CLAUSE_ITERATORS (c)
9267 18870 : && cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
9268 : {
9269 97104 : t = error_mark_node;
9270 : break;
9271 : }
9272 : /* FALLTHRU */
9273 19706 : case OMP_CLAUSE__CACHE_:
9274 19706 : {
9275 19706 : using namespace omp_addr_tokenizer;
9276 19706 : auto_vec<omp_addr_token *, 10> addr_tokens;
9277 :
9278 19706 : t = OMP_CLAUSE_DECL (c);
9279 19706 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9280 : {
9281 5875 : grp_start_p = pc;
9282 5875 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9283 :
9284 5875 : if (handle_omp_array_sections (c, ort))
9285 : remove = true;
9286 : else
9287 : {
9288 5109 : t = OMP_CLAUSE_DECL (c);
9289 5109 : if (TREE_CODE (t) != OMP_ARRAY_SECTION
9290 4252 : && !type_dependent_expression_p (t)
9291 9361 : && !omp_mappable_type (TREE_TYPE (t)))
9292 : {
9293 3 : auto_diagnostic_group d;
9294 6 : error_at (OMP_CLAUSE_LOCATION (c),
9295 : "array section does not have mappable type "
9296 : "in %qs clause",
9297 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9298 3 : if (TREE_TYPE (t) != error_mark_node
9299 3 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9300 3 : cxx_incomplete_type_inform (TREE_TYPE (t));
9301 3 : remove = true;
9302 3 : }
9303 6959 : while (TREE_CODE (t) == ARRAY_REF)
9304 1850 : t = TREE_OPERAND (t, 0);
9305 :
9306 5109 : if (type_dependent_expression_p (t))
9307 : break;
9308 :
9309 4635 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9310 :
9311 4635 : if (!ai.map_supported_p ()
9312 4635 : || !omp_parse_expr (addr_tokens, t))
9313 : {
9314 18 : sorry_at (OMP_CLAUSE_LOCATION (c),
9315 : "unsupported map expression %qE",
9316 9 : OMP_CLAUSE_DECL (c));
9317 9 : remove = true;
9318 9 : break;
9319 : }
9320 :
9321 : /* This check is to determine if this will be the only map
9322 : node created for this clause. Otherwise, we'll check
9323 : the following FIRSTPRIVATE_POINTER,
9324 : FIRSTPRIVATE_REFERENCE or ATTACH_DETACH node on the next
9325 : iteration(s) of the loop. */
9326 9203 : if (addr_tokens.length () >= 4
9327 1063 : && addr_tokens[0]->type == STRUCTURE_BASE
9328 1057 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
9329 1057 : && addr_tokens[1]->type == ACCESS_METHOD
9330 1057 : && addr_tokens[2]->type == COMPONENT_SELECTOR
9331 977 : && addr_tokens[3]->type == ACCESS_METHOD
9332 5340 : && (addr_tokens[3]->u.access_kind == ACCESS_DIRECT
9333 551 : || (addr_tokens[3]->u.access_kind
9334 : == ACCESS_INDEXED_ARRAY)))
9335 : {
9336 165 : tree rt = addr_tokens[1]->expr;
9337 :
9338 165 : gcc_assert (DECL_P (rt));
9339 :
9340 165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9341 154 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9342 165 : && (bitmap_bit_p (&map_head, DECL_UID (rt))
9343 0 : || bitmap_bit_p (&map_field_head, DECL_UID (rt))
9344 0 : || bitmap_bit_p (&map_firstprivate_head,
9345 0 : DECL_UID (rt))))
9346 : {
9347 : remove = true;
9348 : break;
9349 : }
9350 165 : if (bitmap_bit_p (&map_field_head, DECL_UID (rt)))
9351 : break;
9352 116 : if (bitmap_bit_p (&map_head, DECL_UID (rt)))
9353 : {
9354 0 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9355 0 : error_at (OMP_CLAUSE_LOCATION (c),
9356 : "%qD appears more than once in motion"
9357 : " clauses", rt);
9358 0 : else if (openacc)
9359 0 : error_at (OMP_CLAUSE_LOCATION (c),
9360 : "%qD appears more than once in data"
9361 : " clauses", rt);
9362 : else
9363 0 : error_at (OMP_CLAUSE_LOCATION (c),
9364 : "%qD appears more than once in map"
9365 : " clauses", rt);
9366 : remove = true;
9367 : }
9368 : else
9369 : {
9370 116 : bitmap_set_bit (&map_head, DECL_UID (rt));
9371 116 : bitmap_set_bit (&map_field_head, DECL_UID (rt));
9372 : }
9373 : }
9374 4635 : }
9375 5343 : if (cp_oacc_check_attachments (c))
9376 12 : remove = true;
9377 5343 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9378 4409 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9379 4345 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9380 5441 : && !OMP_CLAUSE_SIZE (c))
9381 : /* In this case, we have a single array element which is a
9382 : pointer, and we already set OMP_CLAUSE_SIZE in
9383 : handle_omp_array_sections above. For attach/detach
9384 : clauses, reset the OMP_CLAUSE_SIZE (representing a bias)
9385 : to zero here. */
9386 60 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9387 : break;
9388 : }
9389 13831 : else if (type_dependent_expression_p (t))
9390 : break;
9391 13057 : else if (!omp_parse_expr (addr_tokens, t))
9392 : {
9393 0 : sorry_at (OMP_CLAUSE_LOCATION (c),
9394 : "unsupported map expression %qE",
9395 0 : OMP_CLAUSE_DECL (c));
9396 0 : remove = true;
9397 0 : break;
9398 : }
9399 13057 : if (t == error_mark_node)
9400 : {
9401 : remove = true;
9402 : break;
9403 : }
9404 : /* OpenACC attach / detach clauses must be pointers. */
9405 12963 : if (cp_oacc_check_attachments (c))
9406 : {
9407 : remove = true;
9408 : break;
9409 : }
9410 12939 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9411 9978 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9412 9929 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9413 13013 : && !OMP_CLAUSE_SIZE (c))
9414 : /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a
9415 : bias) to zero here, so it is not set erroneously to the
9416 : pointer size later on in gimplify.cc. */
9417 66 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9418 :
9419 12939 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9420 :
9421 12939 : if (!ai.check_clause (c))
9422 : {
9423 : remove = true;
9424 : break;
9425 : }
9426 :
9427 12918 : if (!ai.map_supported_p ())
9428 : {
9429 88 : sorry_at (OMP_CLAUSE_LOCATION (c),
9430 : "unsupported map expression %qE",
9431 44 : OMP_CLAUSE_DECL (c));
9432 44 : remove = true;
9433 44 : break;
9434 : }
9435 :
9436 25748 : gcc_assert ((addr_tokens[0]->type == ARRAY_BASE
9437 : || addr_tokens[0]->type == STRUCTURE_BASE)
9438 : && addr_tokens[1]->type == ACCESS_METHOD);
9439 :
9440 12874 : t = addr_tokens[1]->expr;
9441 :
9442 : /* This is used to prevent cxx_mark_addressable from being called
9443 : on 'this' for expressions like 'this->a', i.e. typical member
9444 : accesses. */
9445 12874 : indir_component_ref_p
9446 25748 : = (addr_tokens[0]->type == STRUCTURE_BASE
9447 12874 : && addr_tokens[1]->u.access_kind != ACCESS_DIRECT);
9448 :
9449 12874 : if (addr_tokens[0]->u.structure_base_kind != BASE_DECL)
9450 1 : goto skip_decl_checks;
9451 :
9452 : /* For OpenMP, we can access a struct "t" and "t.d" on the same
9453 : mapping. OpenACC allows multiple fields of the same structure
9454 : to be written. */
9455 12873 : if (addr_tokens[0]->type == STRUCTURE_BASE
9456 12873 : && (bitmap_bit_p (&map_field_head, DECL_UID (t))
9457 1197 : || (!openacc && bitmap_bit_p (&map_head, DECL_UID (t)))))
9458 1168 : goto skip_decl_checks;
9459 :
9460 11705 : if (!processing_template_decl && TREE_CODE (t) == FIELD_DECL)
9461 : {
9462 0 : OMP_CLAUSE_DECL (c)
9463 0 : = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
9464 0 : break;
9465 : }
9466 11705 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
9467 : {
9468 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9469 : break;
9470 0 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9471 0 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9472 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9473 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9474 0 : || (!openacc && EXPR_P (t))))
9475 : break;
9476 0 : if (DECL_P (t))
9477 0 : error_at (OMP_CLAUSE_LOCATION (c),
9478 : "%qD is not a variable in %qs clause", t,
9479 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9480 : else
9481 0 : error_at (OMP_CLAUSE_LOCATION (c),
9482 : "%qE is not a variable in %qs clause", t,
9483 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9484 : remove = true;
9485 : }
9486 11705 : else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
9487 : {
9488 0 : error_at (OMP_CLAUSE_LOCATION (c),
9489 : "%qD is threadprivate variable in %qs clause", t,
9490 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9491 0 : remove = true;
9492 : }
9493 11705 : else if (!processing_template_decl
9494 11529 : && !TYPE_REF_P (TREE_TYPE (t))
9495 10856 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9496 7945 : || (OMP_CLAUSE_MAP_KIND (c)
9497 : != GOMP_MAP_FIRSTPRIVATE_POINTER))
9498 8898 : && !indir_component_ref_p
9499 8534 : && (t != current_class_ptr
9500 18 : || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9501 6 : || OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
9502 20239 : && !cxx_mark_addressable (t))
9503 : remove = true;
9504 11705 : else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9505 8776 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9506 8776 : || (OMP_CLAUSE_MAP_KIND (c)
9507 : == GOMP_MAP_FIRSTPRIVATE_POINTER)
9508 6818 : || (OMP_CLAUSE_MAP_KIND (c)
9509 : == GOMP_MAP_ATTACH_DETACH)))
9510 9092 : && t == OMP_CLAUSE_DECL (c)
9511 8460 : && !type_dependent_expression_p (t)
9512 28625 : && !omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
9513 274 : ? TREE_TYPE (TREE_TYPE (t))
9514 8186 : : TREE_TYPE (t)))
9515 : {
9516 42 : auto_diagnostic_group d;
9517 84 : error_at (OMP_CLAUSE_LOCATION (c),
9518 : "%qD does not have a mappable type in %qs clause", t,
9519 42 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9520 42 : if (TREE_TYPE (t) != error_mark_node
9521 42 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9522 39 : cxx_incomplete_type_inform (TREE_TYPE (t));
9523 42 : remove = true;
9524 42 : }
9525 11663 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9526 8740 : && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR
9527 93 : && !type_dependent_expression_p (t)
9528 11756 : && !INDIRECT_TYPE_P (TREE_TYPE (t)))
9529 : {
9530 6 : error_at (OMP_CLAUSE_LOCATION (c),
9531 : "%qD is not a pointer variable", t);
9532 6 : remove = true;
9533 : }
9534 11657 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9535 8734 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9536 12060 : && (bitmap_bit_p (&map_head, DECL_UID (t))
9537 367 : || bitmap_bit_p (&map_field_head, DECL_UID (t))
9538 367 : || bitmap_bit_p (&map_firstprivate_head,
9539 367 : DECL_UID (t))))
9540 : remove = true;
9541 11618 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9542 11618 : && (OMP_CLAUSE_MAP_KIND (c)
9543 : == GOMP_MAP_FIRSTPRIVATE_POINTER))
9544 : {
9545 1952 : if (bitmap_bit_p (&generic_head, DECL_UID (t))
9546 1952 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9547 3901 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
9548 : {
9549 15 : error_at (OMP_CLAUSE_LOCATION (c),
9550 : "%qD appears more than once in data clauses", t);
9551 15 : remove = true;
9552 : }
9553 1937 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9554 12 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9555 1945 : && openacc)
9556 : {
9557 3 : error_at (OMP_CLAUSE_LOCATION (c),
9558 : "%qD appears more than once in data clauses", t);
9559 3 : remove = true;
9560 : }
9561 : else
9562 1934 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9563 : }
9564 9666 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9565 9666 : && (OMP_CLAUSE_MAP_KIND (c)
9566 : == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9567 115 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9568 9551 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9569 171 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9570 28 : && ort != C_ORT_OMP
9571 9579 : && ort != C_ORT_OMP_EXIT_DATA)
9572 : {
9573 18 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9574 0 : error_at (OMP_CLAUSE_LOCATION (c),
9575 : "%qD appears more than once in motion clauses", t);
9576 18 : else if (openacc)
9577 9 : error_at (OMP_CLAUSE_LOCATION (c),
9578 : "%qD appears more than once in data clauses", t);
9579 : else
9580 9 : error_at (OMP_CLAUSE_LOCATION (c),
9581 : "%qD appears more than once in map clauses", t);
9582 : remove = true;
9583 : }
9584 9533 : else if (openacc && bitmap_bit_p (&generic_head, DECL_UID (t)))
9585 : {
9586 0 : error_at (OMP_CLAUSE_LOCATION (c),
9587 : "%qD appears more than once in data clauses", t);
9588 0 : remove = true;
9589 : }
9590 9533 : else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9591 9533 : || bitmap_bit_p (&is_on_device_head, DECL_UID (t)))
9592 : {
9593 27 : if (openacc)
9594 0 : error_at (OMP_CLAUSE_LOCATION (c),
9595 : "%qD appears more than once in data clauses", t);
9596 : else
9597 27 : error_at (OMP_CLAUSE_LOCATION (c),
9598 : "%qD appears both in data and map clauses", t);
9599 : remove = true;
9600 : }
9601 9506 : else if (!omp_access_chain_p (addr_tokens, 1))
9602 : {
9603 9426 : bitmap_set_bit (&map_head, DECL_UID (t));
9604 :
9605 9426 : tree decl = OMP_CLAUSE_DECL (c);
9606 9426 : if (t != decl
9607 9426 : && (TREE_CODE (decl) == COMPONENT_REF
9608 162 : || (INDIRECT_REF_P (decl)
9609 162 : && (TREE_CODE (TREE_OPERAND (decl, 0))
9610 : == COMPONENT_REF)
9611 150 : && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (decl,
9612 : 0))))))
9613 1099 : bitmap_set_bit (&map_field_head, DECL_UID (t));
9614 : }
9615 :
9616 4383 : skip_decl_checks:
9617 : /* If we call ai.expand_map_clause in handle_omp_array_sections,
9618 : the containing loop (here) iterates through the new nodes
9619 : created by that expansion. Avoid expanding those again (just
9620 : by checking the node type). */
9621 4383 : if (!remove
9622 12724 : && !processing_template_decl
9623 12551 : && ort != C_ORT_DECLARE_SIMD
9624 12551 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9625 9608 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9626 7674 : && (OMP_CLAUSE_MAP_KIND (c)
9627 : != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9628 7559 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9629 7559 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9630 6565 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9631 6516 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)))
9632 : {
9633 9434 : grp_start_p = pc;
9634 9434 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9635 9434 : tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
9636 : addr_tokens, ort);
9637 9434 : if (nc != error_mark_node)
9638 9434 : c = nc;
9639 : }
9640 19771 : }
9641 12874 : break;
9642 :
9643 596 : case OMP_CLAUSE_ENTER:
9644 596 : case OMP_CLAUSE_LINK:
9645 596 : t = OMP_CLAUSE_DECL (c);
9646 596 : const char *cname;
9647 596 : cname = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9648 596 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER
9649 596 : && OMP_CLAUSE_ENTER_TO (c))
9650 : cname = "to";
9651 596 : if (TREE_CODE (t) == FUNCTION_DECL
9652 596 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9653 : ;
9654 379 : else if (!VAR_P (t))
9655 : {
9656 12 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9657 : {
9658 9 : if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
9659 6 : error_at (OMP_CLAUSE_LOCATION (c),
9660 : "template %qE in clause %qs", t, cname);
9661 3 : else if (really_overloaded_fn (t))
9662 3 : error_at (OMP_CLAUSE_LOCATION (c),
9663 : "overloaded function name %qE in clause %qs", t,
9664 : cname);
9665 : else
9666 0 : error_at (OMP_CLAUSE_LOCATION (c),
9667 : "%qE is neither a variable nor a function name "
9668 : "in clause %qs", t, cname);
9669 : }
9670 : else
9671 3 : error_at (OMP_CLAUSE_LOCATION (c),
9672 : "%qE is not a variable in clause %qs", t, cname);
9673 : remove = true;
9674 : }
9675 367 : else if (DECL_THREAD_LOCAL_P (t))
9676 : {
9677 6 : error_at (OMP_CLAUSE_LOCATION (c),
9678 : "%qD is threadprivate variable in %qs clause", t,
9679 : cname);
9680 6 : remove = true;
9681 : }
9682 361 : else if (!omp_mappable_type (TREE_TYPE (t)))
9683 : {
9684 18 : auto_diagnostic_group d;
9685 18 : error_at (OMP_CLAUSE_LOCATION (c),
9686 : "%qD does not have a mappable type in %qs clause", t,
9687 : cname);
9688 18 : if (TREE_TYPE (t) != error_mark_node
9689 18 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9690 18 : cxx_incomplete_type_inform (TREE_TYPE (t));
9691 18 : remove = true;
9692 18 : }
9693 24 : if (remove)
9694 : break;
9695 560 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
9696 : {
9697 24 : error_at (OMP_CLAUSE_LOCATION (c),
9698 : "%qE appears more than once on the same "
9699 : "%<declare target%> directive", t);
9700 24 : remove = true;
9701 : }
9702 : else
9703 536 : bitmap_set_bit (&generic_head, DECL_UID (t));
9704 : break;
9705 :
9706 457 : case OMP_CLAUSE_UNIFORM:
9707 457 : t = OMP_CLAUSE_DECL (c);
9708 457 : if (TREE_CODE (t) != PARM_DECL)
9709 : {
9710 0 : if (processing_template_decl)
9711 : break;
9712 0 : if (DECL_P (t))
9713 0 : error_at (OMP_CLAUSE_LOCATION (c),
9714 : "%qD is not an argument in %<uniform%> clause", t);
9715 : else
9716 0 : error_at (OMP_CLAUSE_LOCATION (c),
9717 : "%qE is not an argument in %<uniform%> clause", t);
9718 : remove = true;
9719 : break;
9720 : }
9721 : /* map_head bitmap is used as uniform_head if declare_simd. */
9722 457 : bitmap_set_bit (&map_head, DECL_UID (t));
9723 457 : goto check_dup_generic;
9724 :
9725 165 : case OMP_CLAUSE_GRAINSIZE:
9726 165 : t = OMP_CLAUSE_GRAINSIZE_EXPR (c);
9727 165 : if (t == error_mark_node)
9728 : remove = true;
9729 165 : else if (!type_dependent_expression_p (t)
9730 165 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9731 : {
9732 0 : error_at (OMP_CLAUSE_LOCATION (c),
9733 : "%<grainsize%> expression must be integral");
9734 0 : remove = true;
9735 : }
9736 : else
9737 : {
9738 165 : t = mark_rvalue_use (t);
9739 165 : if (!processing_template_decl)
9740 : {
9741 164 : t = maybe_constant_value (t);
9742 164 : if (TREE_CODE (t) == INTEGER_CST
9743 164 : && tree_int_cst_sgn (t) != 1)
9744 : {
9745 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9746 : "%<grainsize%> value must be positive");
9747 0 : t = integer_one_node;
9748 : }
9749 164 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9750 : }
9751 165 : OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
9752 : }
9753 : break;
9754 :
9755 276 : case OMP_CLAUSE_PRIORITY:
9756 276 : t = OMP_CLAUSE_PRIORITY_EXPR (c);
9757 276 : if (t == error_mark_node)
9758 : remove = true;
9759 276 : else if (!type_dependent_expression_p (t)
9760 276 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9761 : {
9762 0 : error_at (OMP_CLAUSE_LOCATION (c),
9763 : "%<priority%> expression must be integral");
9764 0 : remove = true;
9765 : }
9766 : else
9767 : {
9768 276 : t = mark_rvalue_use (t);
9769 276 : if (!processing_template_decl)
9770 : {
9771 276 : t = maybe_constant_value (t);
9772 276 : if (TREE_CODE (t) == INTEGER_CST
9773 276 : && tree_int_cst_sgn (t) == -1)
9774 : {
9775 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9776 : "%<priority%> value must be non-negative");
9777 0 : t = integer_one_node;
9778 : }
9779 276 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9780 : }
9781 276 : OMP_CLAUSE_PRIORITY_EXPR (c) = t;
9782 : }
9783 : break;
9784 :
9785 228 : case OMP_CLAUSE_HINT:
9786 228 : t = OMP_CLAUSE_HINT_EXPR (c);
9787 228 : if (t == error_mark_node)
9788 : remove = true;
9789 228 : else if (!type_dependent_expression_p (t)
9790 228 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9791 : {
9792 9 : error_at (OMP_CLAUSE_LOCATION (c),
9793 : "%<hint%> expression must be integral");
9794 9 : remove = true;
9795 : }
9796 : else
9797 : {
9798 219 : t = mark_rvalue_use (t);
9799 219 : if (!processing_template_decl)
9800 : {
9801 171 : t = maybe_constant_value (t);
9802 171 : if (TREE_CODE (t) != INTEGER_CST)
9803 : {
9804 16 : error_at (OMP_CLAUSE_LOCATION (c),
9805 : "%<hint%> expression must be constant integer "
9806 : "expression");
9807 16 : remove = true;
9808 : }
9809 : }
9810 219 : OMP_CLAUSE_HINT_EXPR (c) = t;
9811 : }
9812 : break;
9813 :
9814 186 : case OMP_CLAUSE_FILTER:
9815 186 : t = OMP_CLAUSE_FILTER_EXPR (c);
9816 186 : if (t == error_mark_node)
9817 : remove = true;
9818 186 : else if (!type_dependent_expression_p (t)
9819 186 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9820 : {
9821 6 : error_at (OMP_CLAUSE_LOCATION (c),
9822 : "%<filter%> expression must be integral");
9823 6 : remove = true;
9824 : }
9825 : else
9826 : {
9827 180 : t = mark_rvalue_use (t);
9828 180 : if (!processing_template_decl)
9829 : {
9830 177 : t = maybe_constant_value (t);
9831 177 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9832 : }
9833 180 : OMP_CLAUSE_FILTER_EXPR (c) = t;
9834 : }
9835 : break;
9836 :
9837 433 : case OMP_CLAUSE_IS_DEVICE_PTR:
9838 433 : case OMP_CLAUSE_USE_DEVICE_PTR:
9839 433 : field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
9840 433 : t = OMP_CLAUSE_DECL (c);
9841 433 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
9842 329 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
9843 433 : if (!type_dependent_expression_p (t))
9844 : {
9845 431 : tree type = TREE_TYPE (t);
9846 431 : if (!TYPE_PTR_P (type)
9847 431 : && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
9848 : {
9849 57 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
9850 57 : && ort == C_ORT_OMP)
9851 : {
9852 3 : error_at (OMP_CLAUSE_LOCATION (c),
9853 : "%qs variable is neither a pointer "
9854 : "nor reference to pointer",
9855 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9856 3 : remove = true;
9857 : }
9858 54 : else if (TREE_CODE (type) != ARRAY_TYPE
9859 54 : && (!TYPE_REF_P (type)
9860 2 : || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
9861 : {
9862 12 : error_at (OMP_CLAUSE_LOCATION (c),
9863 : "%qs variable is neither a pointer, nor an "
9864 : "array nor reference to pointer or array",
9865 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9866 12 : remove = true;
9867 : }
9868 : }
9869 : }
9870 433 : goto check_dup_generic;
9871 :
9872 267 : case OMP_CLAUSE_HAS_DEVICE_ADDR:
9873 267 : t = OMP_CLAUSE_DECL (c);
9874 267 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9875 : {
9876 28 : if (handle_omp_array_sections (c, ort))
9877 : remove = true;
9878 : else
9879 : {
9880 28 : t = OMP_CLAUSE_DECL (c);
9881 30 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
9882 2 : t = TREE_OPERAND (t, 0);
9883 64 : while (INDIRECT_REF_P (t)
9884 64 : || TREE_CODE (t) == ARRAY_REF)
9885 36 : t = TREE_OPERAND (t, 0);
9886 : }
9887 : }
9888 267 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
9889 : {
9890 267 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
9891 267 : if (!processing_template_decl
9892 267 : && !cxx_mark_addressable (t))
9893 : remove = true;
9894 : }
9895 267 : goto check_dup_generic_t;
9896 :
9897 76 : case OMP_CLAUSE_USE_DEVICE_ADDR:
9898 76 : field_ok = true;
9899 76 : t = OMP_CLAUSE_DECL (c);
9900 76 : if (!processing_template_decl
9901 74 : && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
9902 74 : && !TYPE_REF_P (TREE_TYPE (t))
9903 143 : && !cxx_mark_addressable (t))
9904 : remove = true;
9905 76 : goto check_dup_generic;
9906 :
9907 : case OMP_CLAUSE_NOWAIT:
9908 : case OMP_CLAUSE_DEFAULT:
9909 : case OMP_CLAUSE_UNTIED:
9910 : case OMP_CLAUSE_COLLAPSE:
9911 : case OMP_CLAUSE_PARALLEL:
9912 : case OMP_CLAUSE_FOR:
9913 : case OMP_CLAUSE_SECTIONS:
9914 : case OMP_CLAUSE_TASKGROUP:
9915 : case OMP_CLAUSE_PROC_BIND:
9916 : case OMP_CLAUSE_DEVICE_TYPE:
9917 : case OMP_CLAUSE_NOGROUP:
9918 : case OMP_CLAUSE_THREADS:
9919 : case OMP_CLAUSE_SIMD:
9920 : case OMP_CLAUSE_DEFAULTMAP:
9921 : case OMP_CLAUSE_BIND:
9922 : case OMP_CLAUSE_AUTO:
9923 : case OMP_CLAUSE_INDEPENDENT:
9924 : case OMP_CLAUSE_SEQ:
9925 : case OMP_CLAUSE_IF_PRESENT:
9926 : case OMP_CLAUSE_FINALIZE:
9927 : case OMP_CLAUSE_NOHOST:
9928 : case OMP_CLAUSE_INDIRECT:
9929 : break;
9930 :
9931 231 : case OMP_CLAUSE_MERGEABLE:
9932 231 : mergeable_seen = true;
9933 231 : break;
9934 :
9935 322 : case OMP_CLAUSE_TILE:
9936 754 : for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
9937 432 : list = TREE_CHAIN (list))
9938 : {
9939 432 : t = TREE_VALUE (list);
9940 :
9941 432 : if (t == error_mark_node)
9942 : remove = true;
9943 403 : else if (!type_dependent_expression_p (t)
9944 403 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9945 : {
9946 3 : error_at (OMP_CLAUSE_LOCATION (c),
9947 : "%<tile%> argument needs integral type");
9948 3 : remove = true;
9949 : }
9950 : else
9951 : {
9952 400 : t = mark_rvalue_use (t);
9953 400 : if (!processing_template_decl)
9954 : {
9955 : /* Zero is used to indicate '*', we permit you
9956 : to get there via an ICE of value zero. */
9957 385 : t = maybe_constant_value (t);
9958 385 : if (!tree_fits_shwi_p (t)
9959 369 : || tree_to_shwi (t) < 0)
9960 : {
9961 40 : error_at (OMP_CLAUSE_LOCATION (c),
9962 : "%<tile%> argument needs positive "
9963 : "integral constant");
9964 40 : remove = true;
9965 : }
9966 : }
9967 : }
9968 :
9969 : /* Update list item. */
9970 432 : TREE_VALUE (list) = t;
9971 : }
9972 : break;
9973 :
9974 1027 : case OMP_CLAUSE_SIZES:
9975 1027 : for (tree list = OMP_CLAUSE_SIZES_LIST (c);
9976 2688 : !remove && list; list = TREE_CHAIN (list))
9977 : {
9978 1661 : t = TREE_VALUE (list);
9979 :
9980 1661 : if (t == error_mark_node)
9981 0 : t = integer_one_node;
9982 1661 : else if (!type_dependent_expression_p (t)
9983 1661 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9984 : {
9985 8 : error_at (OMP_CLAUSE_LOCATION (c),
9986 : "%<sizes%> argument needs positive integral "
9987 : "constant");
9988 8 : t = integer_one_node;
9989 : }
9990 : else
9991 : {
9992 1653 : t = mark_rvalue_use (t);
9993 1653 : if (!processing_template_decl)
9994 : {
9995 1636 : t = maybe_constant_value (t);
9996 1636 : HOST_WIDE_INT n;
9997 1636 : if (!tree_fits_shwi_p (t)
9998 1632 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
9999 1632 : || (n = tree_to_shwi (t)) <= 0
10000 3240 : || (int)n != n)
10001 : {
10002 32 : error_at (OMP_CLAUSE_LOCATION (c),
10003 : "%<sizes%> argument needs positive "
10004 : "integral constant");
10005 32 : t = integer_one_node;
10006 : }
10007 : }
10008 : }
10009 :
10010 : /* Update list item. */
10011 1661 : TREE_VALUE (list) = t;
10012 : }
10013 : break;
10014 :
10015 630 : case OMP_CLAUSE_ORDERED:
10016 630 : ordered_seen = true;
10017 630 : break;
10018 :
10019 1549 : case OMP_CLAUSE_ORDER:
10020 1549 : if (order_seen)
10021 : remove = true;
10022 : else
10023 : order_seen = true;
10024 : break;
10025 :
10026 638 : case OMP_CLAUSE_INBRANCH:
10027 638 : case OMP_CLAUSE_NOTINBRANCH:
10028 638 : if (branch_seen)
10029 : {
10030 3 : error_at (OMP_CLAUSE_LOCATION (c),
10031 : "%<inbranch%> clause is incompatible with "
10032 : "%<notinbranch%>");
10033 3 : remove = true;
10034 : }
10035 : branch_seen = true;
10036 : break;
10037 :
10038 297 : case OMP_CLAUSE_INCLUSIVE:
10039 297 : case OMP_CLAUSE_EXCLUSIVE:
10040 297 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10041 297 : if (!t)
10042 297 : t = OMP_CLAUSE_DECL (c);
10043 297 : if (t == current_class_ptr)
10044 : {
10045 0 : error_at (OMP_CLAUSE_LOCATION (c),
10046 : "%<this%> allowed in OpenMP only in %<declare simd%>"
10047 : " clauses");
10048 0 : remove = true;
10049 0 : break;
10050 : }
10051 297 : if (!VAR_P (t)
10052 : && TREE_CODE (t) != PARM_DECL
10053 : && TREE_CODE (t) != FIELD_DECL)
10054 : {
10055 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
10056 : break;
10057 0 : if (DECL_P (t))
10058 0 : error_at (OMP_CLAUSE_LOCATION (c),
10059 : "%qD is not a variable in clause %qs", t,
10060 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10061 : else
10062 0 : error_at (OMP_CLAUSE_LOCATION (c),
10063 : "%qE is not a variable in clause %qs", t,
10064 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10065 : remove = true;
10066 : }
10067 : break;
10068 :
10069 : case OMP_CLAUSE_FULL:
10070 : break;
10071 :
10072 470 : case OMP_CLAUSE_PARTIAL:
10073 470 : partial_seen = true;
10074 470 : t = OMP_CLAUSE_PARTIAL_EXPR (c);
10075 470 : if (!t)
10076 : break;
10077 :
10078 313 : if (t == error_mark_node)
10079 : t = NULL_TREE;
10080 313 : else if (!type_dependent_expression_p (t)
10081 313 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10082 : {
10083 3 : error_at (OMP_CLAUSE_LOCATION (c),
10084 : "%<partial%> argument needs positive constant "
10085 : "integer expression");
10086 3 : t = NULL_TREE;
10087 : }
10088 : else
10089 : {
10090 310 : t = mark_rvalue_use (t);
10091 310 : if (!processing_template_decl)
10092 : {
10093 292 : t = maybe_constant_value (t);
10094 :
10095 292 : HOST_WIDE_INT n;
10096 584 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
10097 292 : || !tree_fits_shwi_p (t)
10098 286 : || (n = tree_to_shwi (t)) <= 0
10099 560 : || (int)n != n)
10100 : {
10101 24 : error_at (OMP_CLAUSE_LOCATION (c),
10102 : "%<partial%> argument needs positive "
10103 : "constant integer expression");
10104 24 : t = NULL_TREE;
10105 : }
10106 : }
10107 : }
10108 :
10109 313 : OMP_CLAUSE_PARTIAL_EXPR (c) = t;
10110 313 : break;
10111 549 : case OMP_CLAUSE_INIT:
10112 549 : init_seen = true;
10113 549 : OMP_CLAUSE_INIT_PREFER_TYPE (c)
10114 549 : = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c));
10115 549 : if (!OMP_CLAUSE_INIT_TARGETSYNC (c))
10116 271 : init_no_targetsync_clause = c;
10117 : /* FALLTHRU */
10118 844 : case OMP_CLAUSE_DESTROY:
10119 844 : case OMP_CLAUSE_USE:
10120 844 : init_use_destroy_seen = true;
10121 844 : t = OMP_CLAUSE_DECL (c);
10122 844 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
10123 : {
10124 9 : error_at (OMP_CLAUSE_LOCATION (c),
10125 : "%qD appears more than once in action clauses", t);
10126 9 : remove = true;
10127 9 : break;
10128 : }
10129 835 : bitmap_set_bit (&generic_head, DECL_UID (t));
10130 : /* FALLTHRU */
10131 1099 : case OMP_CLAUSE_INTEROP:
10132 1099 : if (!processing_template_decl)
10133 : {
10134 1003 : if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
10135 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) && */
10136 1003 : !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
10137 : {
10138 126 : error_at (OMP_CLAUSE_LOCATION (c),
10139 : "%qD must be of %<omp_interop_t%>",
10140 63 : OMP_CLAUSE_DECL (c));
10141 63 : remove = true;
10142 : }
10143 940 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
10144 481 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
10145 1058 : && TREE_READONLY (OMP_CLAUSE_DECL (c)))
10146 : {
10147 36 : error_at (OMP_CLAUSE_LOCATION (c),
10148 18 : "%qD shall not be const", OMP_CLAUSE_DECL (c));
10149 18 : remove = true;
10150 : }
10151 : }
10152 1099 : pc = &OMP_CLAUSE_CHAIN (c);
10153 1099 : break;
10154 0 : default:
10155 0 : gcc_unreachable ();
10156 54 : }
10157 :
10158 97104 : if (remove)
10159 : {
10160 2601 : if (grp_start_p)
10161 : {
10162 : /* If we found a clause to remove, we want to remove the whole
10163 : expanded group, otherwise gimplify
10164 : (omp_resolve_clause_dependencies) can get confused. */
10165 820 : *grp_start_p = grp_sentinel;
10166 820 : pc = grp_start_p;
10167 820 : grp_start_p = NULL;
10168 : }
10169 : else
10170 1781 : *pc = OMP_CLAUSE_CHAIN (c);
10171 : }
10172 : else
10173 94503 : pc = &OMP_CLAUSE_CHAIN (c);
10174 : }
10175 :
10176 62520 : if (grp_start_p
10177 62520 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
10178 140 : for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc))
10179 86 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
10180 :
10181 62520 : if (reduction_seen < 0 && (ordered_seen || schedule_seen))
10182 62520 : reduction_seen = -2;
10183 :
10184 157980 : for (pc = &clauses, c = clauses; c ; c = *pc)
10185 : {
10186 95460 : enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
10187 95460 : bool remove = false;
10188 95460 : bool need_complete_type = false;
10189 95460 : bool need_default_ctor = false;
10190 95460 : bool need_copy_ctor = false;
10191 95460 : bool need_copy_assignment = false;
10192 95460 : bool need_implicitly_determined = false;
10193 95460 : bool need_dtor = false;
10194 95460 : tree type, inner_type;
10195 :
10196 95460 : switch (c_kind)
10197 : {
10198 : case OMP_CLAUSE_SHARED:
10199 : need_implicitly_determined = true;
10200 : break;
10201 2540 : case OMP_CLAUSE_PRIVATE:
10202 2540 : need_complete_type = true;
10203 2540 : need_default_ctor = true;
10204 2540 : need_dtor = true;
10205 2540 : need_implicitly_determined = true;
10206 2540 : break;
10207 3156 : case OMP_CLAUSE_FIRSTPRIVATE:
10208 3156 : need_complete_type = true;
10209 3156 : need_copy_ctor = true;
10210 3156 : need_dtor = true;
10211 3156 : need_implicitly_determined = true;
10212 3156 : break;
10213 2763 : case OMP_CLAUSE_LASTPRIVATE:
10214 2763 : need_complete_type = true;
10215 2763 : need_copy_assignment = true;
10216 2763 : need_implicitly_determined = true;
10217 2763 : break;
10218 7286 : case OMP_CLAUSE_REDUCTION:
10219 7286 : if (reduction_seen == -2)
10220 27 : OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
10221 7286 : if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10222 421 : need_copy_assignment = true;
10223 : need_implicitly_determined = true;
10224 : break;
10225 : case OMP_CLAUSE_IN_REDUCTION:
10226 : case OMP_CLAUSE_TASK_REDUCTION:
10227 : case OMP_CLAUSE_INCLUSIVE:
10228 : case OMP_CLAUSE_EXCLUSIVE:
10229 : need_implicitly_determined = true;
10230 : break;
10231 1550 : case OMP_CLAUSE_LINEAR:
10232 1550 : if (ort != C_ORT_OMP_DECLARE_SIMD)
10233 : need_implicitly_determined = true;
10234 679 : else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
10235 721 : && !bitmap_bit_p (&map_head,
10236 42 : DECL_UID (OMP_CLAUSE_LINEAR_STEP (c))))
10237 : {
10238 6 : error_at (OMP_CLAUSE_LOCATION (c),
10239 : "%<linear%> clause step is a parameter %qD not "
10240 : "specified in %<uniform%> clause",
10241 6 : OMP_CLAUSE_LINEAR_STEP (c));
10242 6 : *pc = OMP_CLAUSE_CHAIN (c);
10243 73934 : continue;
10244 : }
10245 : break;
10246 : case OMP_CLAUSE_COPYPRIVATE:
10247 366 : need_copy_assignment = true;
10248 : break;
10249 : case OMP_CLAUSE_COPYIN:
10250 366 : need_copy_assignment = true;
10251 : break;
10252 798 : case OMP_CLAUSE_SIMDLEN:
10253 798 : if (safelen
10254 345 : && !processing_template_decl
10255 1143 : && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
10256 345 : OMP_CLAUSE_SIMDLEN_EXPR (c)))
10257 : {
10258 0 : error_at (OMP_CLAUSE_LOCATION (c),
10259 : "%<simdlen%> clause value is bigger than "
10260 : "%<safelen%> clause value");
10261 0 : OMP_CLAUSE_SIMDLEN_EXPR (c)
10262 0 : = OMP_CLAUSE_SAFELEN_EXPR (safelen);
10263 : }
10264 798 : pc = &OMP_CLAUSE_CHAIN (c);
10265 798 : continue;
10266 3853 : case OMP_CLAUSE_SCHEDULE:
10267 3853 : if (ordered_seen
10268 3853 : && (OMP_CLAUSE_SCHEDULE_KIND (c)
10269 : & OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
10270 : {
10271 21 : error_at (OMP_CLAUSE_LOCATION (c),
10272 : "%<nonmonotonic%> schedule modifier specified "
10273 : "together with %<ordered%> clause");
10274 42 : OMP_CLAUSE_SCHEDULE_KIND (c)
10275 21 : = (enum omp_clause_schedule_kind)
10276 21 : (OMP_CLAUSE_SCHEDULE_KIND (c)
10277 : & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
10278 : }
10279 3853 : if (reduction_seen == -2)
10280 9 : error_at (OMP_CLAUSE_LOCATION (c),
10281 : "%qs clause specified together with %<inscan%> "
10282 : "%<reduction%> clause", "schedule");
10283 3853 : pc = &OMP_CLAUSE_CHAIN (c);
10284 3853 : continue;
10285 51 : case OMP_CLAUSE_NOGROUP:
10286 51 : if (reduction_seen)
10287 : {
10288 3 : error_at (OMP_CLAUSE_LOCATION (c),
10289 : "%<nogroup%> clause must not be used together with "
10290 : "%<reduction%> clause");
10291 3 : *pc = OMP_CLAUSE_CHAIN (c);
10292 3 : continue;
10293 : }
10294 48 : pc = &OMP_CLAUSE_CHAIN (c);
10295 48 : continue;
10296 165 : case OMP_CLAUSE_GRAINSIZE:
10297 165 : if (num_tasks_seen)
10298 : {
10299 6 : error_at (OMP_CLAUSE_LOCATION (c),
10300 : "%<grainsize%> clause must not be used together with "
10301 : "%<num_tasks%> clause");
10302 6 : *pc = OMP_CLAUSE_CHAIN (c);
10303 6 : continue;
10304 : }
10305 159 : pc = &OMP_CLAUSE_CHAIN (c);
10306 159 : continue;
10307 630 : case OMP_CLAUSE_ORDERED:
10308 630 : if (reduction_seen == -2)
10309 6 : error_at (OMP_CLAUSE_LOCATION (c),
10310 : "%qs clause specified together with %<inscan%> "
10311 : "%<reduction%> clause", "ordered");
10312 630 : pc = &OMP_CLAUSE_CHAIN (c);
10313 630 : continue;
10314 1525 : case OMP_CLAUSE_ORDER:
10315 1525 : if (ordered_seen)
10316 : {
10317 12 : error_at (OMP_CLAUSE_LOCATION (c),
10318 : "%<order%> clause must not be used together "
10319 : "with %<ordered%> clause");
10320 12 : *pc = OMP_CLAUSE_CHAIN (c);
10321 12 : continue;
10322 : }
10323 1513 : pc = &OMP_CLAUSE_CHAIN (c);
10324 1513 : continue;
10325 57 : case OMP_CLAUSE_DETACH:
10326 57 : if (mergeable_seen)
10327 : {
10328 6 : error_at (OMP_CLAUSE_LOCATION (c),
10329 : "%<detach%> clause must not be used together with "
10330 : "%<mergeable%> clause");
10331 6 : *pc = OMP_CLAUSE_CHAIN (c);
10332 6 : continue;
10333 : }
10334 51 : pc = &OMP_CLAUSE_CHAIN (c);
10335 51 : continue;
10336 15650 : case OMP_CLAUSE_MAP:
10337 15650 : if (target_in_reduction_seen && !processing_template_decl)
10338 : {
10339 684 : t = OMP_CLAUSE_DECL (c);
10340 684 : while (handled_component_p (t)
10341 : || INDIRECT_REF_P (t)
10342 : || TREE_CODE (t) == ADDR_EXPR
10343 : || TREE_CODE (t) == MEM_REF
10344 804 : || TREE_CODE (t) == NON_LVALUE_EXPR)
10345 120 : t = TREE_OPERAND (t, 0);
10346 684 : if (DECL_P (t)
10347 684 : && bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
10348 342 : OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10349 : }
10350 15650 : pc = &OMP_CLAUSE_CHAIN (c);
10351 15650 : continue;
10352 225 : case OMP_CLAUSE_FULL:
10353 225 : if (partial_seen)
10354 : {
10355 12 : error_at (OMP_CLAUSE_LOCATION (c),
10356 : "%<full%> clause must not be used together "
10357 : "with %<partial%> clause");
10358 12 : *pc = OMP_CLAUSE_CHAIN (c);
10359 12 : continue;
10360 : }
10361 213 : pc = &OMP_CLAUSE_CHAIN (c);
10362 213 : continue;
10363 6894 : case OMP_CLAUSE_NOWAIT:
10364 6894 : if (copyprivate_seen)
10365 : {
10366 6 : error_at (OMP_CLAUSE_LOCATION (c),
10367 : "%<nowait%> clause must not be used together "
10368 : "with %<copyprivate%> clause");
10369 6 : *pc = OMP_CLAUSE_CHAIN (c);
10370 6 : continue;
10371 : }
10372 : /* FALLTHRU */
10373 50330 : default:
10374 50330 : pc = &OMP_CLAUSE_CHAIN (c);
10375 50330 : continue;
10376 : }
10377 :
10378 22164 : t = OMP_CLAUSE_DECL (c);
10379 22164 : switch (c_kind)
10380 : {
10381 2763 : case OMP_CLAUSE_LASTPRIVATE:
10382 2763 : if (DECL_P (t)
10383 2763 : && !bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
10384 : {
10385 2666 : need_default_ctor = true;
10386 2666 : need_dtor = true;
10387 : }
10388 : break;
10389 :
10390 9425 : case OMP_CLAUSE_REDUCTION:
10391 9425 : case OMP_CLAUSE_IN_REDUCTION:
10392 9425 : case OMP_CLAUSE_TASK_REDUCTION:
10393 9425 : if (allocate_seen)
10394 : {
10395 1561 : if (TREE_CODE (t) == MEM_REF)
10396 : {
10397 162 : t = TREE_OPERAND (t, 0);
10398 162 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
10399 0 : t = TREE_OPERAND (t, 0);
10400 162 : if (TREE_CODE (t) == ADDR_EXPR
10401 120 : || INDIRECT_REF_P (t))
10402 80 : t = TREE_OPERAND (t, 0);
10403 162 : if (DECL_P (t))
10404 162 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10405 : }
10406 1399 : else if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10407 : {
10408 192 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10409 96 : t = TREE_OPERAND (t, 0);
10410 96 : if (DECL_P (t))
10411 96 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10412 96 : t = OMP_CLAUSE_DECL (c);
10413 : }
10414 1303 : else if (DECL_P (t))
10415 1303 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10416 1561 : t = OMP_CLAUSE_DECL (c);
10417 : }
10418 9425 : if (processing_template_decl
10419 863 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10420 : break;
10421 8855 : if (finish_omp_reduction_clause (c, &need_default_ctor,
10422 : &need_dtor))
10423 : remove = true;
10424 : else
10425 8771 : t = OMP_CLAUSE_DECL (c);
10426 : break;
10427 :
10428 274 : case OMP_CLAUSE_COPYIN:
10429 274 : if (processing_template_decl
10430 0 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10431 : break;
10432 274 : if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t))
10433 : {
10434 15 : error_at (OMP_CLAUSE_LOCATION (c),
10435 : "%qE must be %<threadprivate%> for %<copyin%>", t);
10436 15 : remove = true;
10437 : }
10438 : break;
10439 :
10440 : default:
10441 : break;
10442 : }
10443 :
10444 22164 : if (processing_template_decl
10445 1544 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10446 : {
10447 632 : pc = &OMP_CLAUSE_CHAIN (c);
10448 632 : continue;
10449 : }
10450 :
10451 21532 : if (need_complete_type || need_copy_assignment)
10452 : {
10453 9190 : t = require_complete_type (t);
10454 9190 : if (t == error_mark_node)
10455 : remove = true;
10456 9166 : else if (!processing_template_decl
10457 8783 : && TYPE_REF_P (TREE_TYPE (t))
10458 9722 : && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
10459 : remove = true;
10460 : }
10461 21532 : if (need_implicitly_determined)
10462 : {
10463 20494 : const char *share_name = NULL;
10464 :
10465 20494 : if (allocate_seen
10466 4993 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10467 24608 : && DECL_P (t))
10468 3904 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10469 :
10470 20494 : if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
10471 : share_name = "threadprivate";
10472 20452 : else switch (cxx_omp_predetermined_sharing_1 (t))
10473 : {
10474 : case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
10475 : break;
10476 47 : case OMP_CLAUSE_DEFAULT_SHARED:
10477 47 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10478 30 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10479 64 : && c_omp_predefined_variable (t))
10480 : /* The __func__ variable and similar function-local predefined
10481 : variables may be listed in a shared or firstprivate
10482 : clause. */
10483 : break;
10484 31 : if (VAR_P (t)
10485 31 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10486 9 : && TREE_STATIC (t)
10487 40 : && cxx_omp_const_qual_no_mutable (t))
10488 : {
10489 6 : tree ctx = CP_DECL_CONTEXT (t);
10490 : /* const qualified static data members without mutable
10491 : member may be specified in firstprivate clause. */
10492 6 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
10493 : break;
10494 : }
10495 : share_name = "shared";
10496 : break;
10497 : case OMP_CLAUSE_DEFAULT_PRIVATE:
10498 : share_name = "private";
10499 : break;
10500 0 : default:
10501 0 : gcc_unreachable ();
10502 : }
10503 : if (share_name)
10504 : {
10505 67 : error_at (OMP_CLAUSE_LOCATION (c),
10506 : "%qE is predetermined %qs for %qs",
10507 : omp_clause_printable_decl (t), share_name,
10508 67 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10509 67 : remove = true;
10510 : }
10511 20427 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10512 18368 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
10513 35668 : && cxx_omp_const_qual_no_mutable (t))
10514 : {
10515 126 : error_at (OMP_CLAUSE_LOCATION (c),
10516 : "%<const%> qualified %qE without %<mutable%> member "
10517 : "may appear only in %<shared%> or %<firstprivate%> "
10518 : "clauses", omp_clause_printable_decl (t));
10519 63 : remove = true;
10520 : }
10521 : }
10522 :
10523 21532 : if (detach_seen
10524 16 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10525 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
10526 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10527 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10528 21548 : && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen))
10529 : {
10530 6 : error_at (OMP_CLAUSE_LOCATION (c),
10531 : "the event handle of a %<detach%> clause "
10532 : "should not be in a data-sharing clause");
10533 6 : remove = true;
10534 : }
10535 :
10536 : /* We're interested in the base element, not arrays. */
10537 21532 : inner_type = type = TREE_TYPE (t);
10538 21532 : if ((need_complete_type
10539 : || need_copy_assignment
10540 12342 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10541 5708 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10542 4235 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10543 29966 : && TYPE_REF_P (inner_type))
10544 878 : inner_type = TREE_TYPE (inner_type);
10545 24113 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
10546 2581 : inner_type = TREE_TYPE (inner_type);
10547 :
10548 : /* Check for special function availability by building a call to one.
10549 : Save the results, because later we won't be in the right context
10550 : for making these queries. */
10551 2387 : if (CLASS_TYPE_P (inner_type)
10552 2387 : && COMPLETE_TYPE_P (inner_type)
10553 2318 : && (need_default_ctor || need_copy_ctor
10554 1081 : || need_copy_assignment || need_dtor)
10555 1994 : && !type_dependent_expression_p (t)
10556 23526 : && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
10557 : need_copy_ctor, need_copy_assignment,
10558 : need_dtor))
10559 : remove = true;
10560 :
10561 21532 : if (!remove
10562 21532 : && c_kind == OMP_CLAUSE_SHARED
10563 2056 : && processing_template_decl)
10564 : {
10565 125 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10566 125 : if (t)
10567 5 : OMP_CLAUSE_DECL (c) = t;
10568 : }
10569 :
10570 21532 : if (remove)
10571 292 : *pc = OMP_CLAUSE_CHAIN (c);
10572 : else
10573 21240 : pc = &OMP_CLAUSE_CHAIN (c);
10574 : }
10575 :
10576 62520 : if (allocate_seen)
10577 16828 : for (pc = &clauses, c = clauses; c ; c = *pc)
10578 : {
10579 14544 : bool remove = false;
10580 14544 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
10581 2540 : && !OMP_CLAUSE_ALLOCATE_COMBINED (c)
10582 2143 : && DECL_P (OMP_CLAUSE_DECL (c))
10583 16687 : && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c))))
10584 : {
10585 15 : error_at (OMP_CLAUSE_LOCATION (c),
10586 : "%qD specified in %<allocate%> clause but not in "
10587 15 : "an explicit privatization clause", OMP_CLAUSE_DECL (c));
10588 15 : remove = true;
10589 : }
10590 14544 : if (remove)
10591 15 : *pc = OMP_CLAUSE_CHAIN (c);
10592 : else
10593 14529 : pc = &OMP_CLAUSE_CHAIN (c);
10594 : }
10595 :
10596 62520 : if (ort == C_ORT_OMP_INTEROP
10597 62520 : && depend_clause
10598 60 : && (!init_use_destroy_seen
10599 57 : || (init_seen && init_no_targetsync_clause)))
10600 : {
10601 9 : error_at (OMP_CLAUSE_LOCATION (depend_clause),
10602 : "%<depend%> clause requires action clauses with "
10603 : "%<targetsync%> interop-type");
10604 9 : if (init_no_targetsync_clause)
10605 6 : inform (OMP_CLAUSE_LOCATION (init_no_targetsync_clause),
10606 : "%<init%> clause lacks the %<targetsync%> modifier");
10607 : }
10608 :
10609 62520 : bitmap_obstack_release (NULL);
10610 62520 : return clauses;
10611 : }
10612 :
10613 : /* Start processing OpenMP clauses that can include any
10614 : privatization clauses for non-static data members. */
10615 :
10616 : tree
10617 48381 : push_omp_privatization_clauses (bool ignore_next)
10618 : {
10619 48381 : if (omp_private_member_ignore_next)
10620 : {
10621 656 : omp_private_member_ignore_next = ignore_next;
10622 656 : return NULL_TREE;
10623 : }
10624 47725 : omp_private_member_ignore_next = ignore_next;
10625 47725 : if (omp_private_member_map)
10626 24 : omp_private_member_vec.safe_push (error_mark_node);
10627 47725 : return push_stmt_list ();
10628 : }
10629 :
10630 : /* Revert remapping of any non-static data members since
10631 : the last push_omp_privatization_clauses () call. */
10632 :
10633 : void
10634 48375 : pop_omp_privatization_clauses (tree stmt)
10635 : {
10636 48375 : if (stmt == NULL_TREE)
10637 : return;
10638 47719 : stmt = pop_stmt_list (stmt);
10639 47719 : if (omp_private_member_map)
10640 : {
10641 1280 : while (!omp_private_member_vec.is_empty ())
10642 : {
10643 850 : tree t = omp_private_member_vec.pop ();
10644 850 : if (t == error_mark_node)
10645 : {
10646 24 : add_stmt (stmt);
10647 24 : return;
10648 : }
10649 826 : bool no_decl_expr = t == integer_zero_node;
10650 826 : if (no_decl_expr)
10651 136 : t = omp_private_member_vec.pop ();
10652 826 : tree *v = omp_private_member_map->get (t);
10653 826 : gcc_assert (v);
10654 826 : if (!no_decl_expr)
10655 690 : add_decl_expr (*v);
10656 826 : omp_private_member_map->remove (t);
10657 : }
10658 860 : delete omp_private_member_map;
10659 430 : omp_private_member_map = NULL;
10660 : }
10661 47695 : add_stmt (stmt);
10662 : }
10663 :
10664 : /* Remember OpenMP privatization clauses mapping and clear it.
10665 : Used for lambdas. */
10666 :
10667 : void
10668 20148842 : save_omp_privatization_clauses (vec<tree> &save)
10669 : {
10670 20148842 : save = vNULL;
10671 20148842 : if (omp_private_member_ignore_next)
10672 2 : save.safe_push (integer_one_node);
10673 20148842 : omp_private_member_ignore_next = false;
10674 20148842 : if (!omp_private_member_map)
10675 : return;
10676 :
10677 0 : while (!omp_private_member_vec.is_empty ())
10678 : {
10679 0 : tree t = omp_private_member_vec.pop ();
10680 0 : if (t == error_mark_node)
10681 : {
10682 0 : save.safe_push (t);
10683 0 : continue;
10684 : }
10685 0 : tree n = t;
10686 0 : if (t == integer_zero_node)
10687 0 : t = omp_private_member_vec.pop ();
10688 0 : tree *v = omp_private_member_map->get (t);
10689 0 : gcc_assert (v);
10690 0 : save.safe_push (*v);
10691 0 : save.safe_push (t);
10692 0 : if (n != t)
10693 0 : save.safe_push (n);
10694 : }
10695 0 : delete omp_private_member_map;
10696 0 : omp_private_member_map = NULL;
10697 : }
10698 :
10699 : /* Restore OpenMP privatization clauses mapping saved by the
10700 : above function. */
10701 :
10702 : void
10703 20148842 : restore_omp_privatization_clauses (vec<tree> &save)
10704 : {
10705 20148842 : gcc_assert (omp_private_member_vec.is_empty ());
10706 20148842 : omp_private_member_ignore_next = false;
10707 20148842 : if (save.is_empty ())
10708 : return;
10709 4 : if (save.length () == 1 && save[0] == integer_one_node)
10710 : {
10711 2 : omp_private_member_ignore_next = true;
10712 2 : save.release ();
10713 2 : return;
10714 : }
10715 :
10716 0 : omp_private_member_map = new hash_map <tree, tree>;
10717 0 : while (!save.is_empty ())
10718 : {
10719 0 : tree t = save.pop ();
10720 0 : tree n = t;
10721 0 : if (t != error_mark_node)
10722 : {
10723 0 : if (t == integer_one_node)
10724 : {
10725 0 : omp_private_member_ignore_next = true;
10726 0 : gcc_assert (save.is_empty ());
10727 0 : break;
10728 : }
10729 0 : if (t == integer_zero_node)
10730 0 : t = save.pop ();
10731 0 : tree &v = omp_private_member_map->get_or_insert (t);
10732 0 : v = save.pop ();
10733 : }
10734 0 : omp_private_member_vec.safe_push (t);
10735 0 : if (n != t)
10736 0 : omp_private_member_vec.safe_push (n);
10737 : }
10738 0 : save.release ();
10739 : }
10740 :
10741 : /* For all variables in the tree_list VARS, mark them as thread local. */
10742 :
10743 : void
10744 238 : finish_omp_threadprivate (tree vars)
10745 : {
10746 238 : tree t;
10747 :
10748 : /* Mark every variable in VARS to be assigned thread local storage. */
10749 509 : for (t = vars; t; t = TREE_CHAIN (t))
10750 : {
10751 271 : tree v = TREE_PURPOSE (t);
10752 271 : location_t loc = EXPR_LOCATION (TREE_VALUE (t));
10753 :
10754 271 : if (error_operand_p (v))
10755 : ;
10756 271 : else if (!VAR_P (v))
10757 6 : error_at (loc, "%<threadprivate%> %qD is not file, namespace "
10758 : "or block scope variable", v);
10759 : /* If V had already been marked threadprivate, it doesn't matter
10760 : whether it had been used prior to this point. */
10761 265 : else if (TREE_USED (v)
10762 265 : && (DECL_LANG_SPECIFIC (v) == NULL
10763 3 : || !CP_DECL_THREADPRIVATE_P (v)))
10764 6 : error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10765 259 : else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10766 6 : error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10767 253 : else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v))))
10768 3 : error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10769 201 : else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))
10770 273 : && CP_DECL_CONTEXT (v) != current_class_type)
10771 6 : error_at (loc, "%<threadprivate%> %qE directive not "
10772 6 : "in %qT definition", v, CP_DECL_CONTEXT (v));
10773 : else
10774 : {
10775 : /* Allocate a LANG_SPECIFIC structure for V, if needed. */
10776 244 : if (DECL_LANG_SPECIFIC (v) == NULL)
10777 200 : retrofit_lang_decl (v);
10778 :
10779 244 : if (! CP_DECL_THREAD_LOCAL_P (v))
10780 : {
10781 244 : CP_DECL_THREAD_LOCAL_P (v) = true;
10782 244 : set_decl_tls_model (v, decl_default_tls_model (v));
10783 : /* If rtl has been already set for this var, call
10784 : make_decl_rtl once again, so that encode_section_info
10785 : has a chance to look at the new decl flags. */
10786 244 : if (DECL_RTL_SET_P (v))
10787 0 : make_decl_rtl (v);
10788 : }
10789 244 : CP_DECL_THREADPRIVATE_P (v) = 1;
10790 : }
10791 : }
10792 238 : }
10793 :
10794 : /* Build an OpenMP structured block. */
10795 :
10796 : tree
10797 63943 : begin_omp_structured_block (void)
10798 : {
10799 63943 : return do_pushlevel (sk_omp);
10800 : }
10801 :
10802 : tree
10803 63922 : finish_omp_structured_block (tree block)
10804 : {
10805 63922 : return do_poplevel (block);
10806 : }
10807 :
10808 : /* Similarly, except force the retention of the BLOCK. */
10809 :
10810 : tree
10811 14797 : begin_omp_parallel (void)
10812 : {
10813 14797 : keep_next_level (true);
10814 14797 : return begin_omp_structured_block ();
10815 : }
10816 :
10817 : /* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
10818 : statement. */
10819 :
10820 : tree
10821 768 : finish_oacc_data (tree clauses, tree block)
10822 : {
10823 768 : tree stmt;
10824 :
10825 768 : block = finish_omp_structured_block (block);
10826 :
10827 768 : stmt = make_node (OACC_DATA);
10828 768 : TREE_TYPE (stmt) = void_type_node;
10829 768 : OACC_DATA_CLAUSES (stmt) = clauses;
10830 768 : OACC_DATA_BODY (stmt) = block;
10831 :
10832 768 : return add_stmt (stmt);
10833 : }
10834 :
10835 : /* Generate OACC_HOST_DATA, with CLAUSES and BLOCK as its compound
10836 : statement. */
10837 :
10838 : tree
10839 55 : finish_oacc_host_data (tree clauses, tree block)
10840 : {
10841 55 : tree stmt;
10842 :
10843 55 : block = finish_omp_structured_block (block);
10844 :
10845 55 : stmt = make_node (OACC_HOST_DATA);
10846 55 : TREE_TYPE (stmt) = void_type_node;
10847 55 : OACC_HOST_DATA_CLAUSES (stmt) = clauses;
10848 55 : OACC_HOST_DATA_BODY (stmt) = block;
10849 :
10850 55 : return add_stmt (stmt);
10851 : }
10852 :
10853 : /* Generate OMP construct CODE, with BODY and CLAUSES as its compound
10854 : statement. */
10855 :
10856 : tree
10857 4653 : finish_omp_construct (enum tree_code code, tree body, tree clauses)
10858 : {
10859 4653 : body = finish_omp_structured_block (body);
10860 :
10861 4653 : tree stmt = make_node (code);
10862 4653 : TREE_TYPE (stmt) = void_type_node;
10863 4653 : OMP_BODY (stmt) = body;
10864 4653 : OMP_CLAUSES (stmt) = clauses;
10865 :
10866 4653 : return add_stmt (stmt);
10867 : }
10868 :
10869 : /* Used to walk OpenMP target directive body. */
10870 :
10871 : struct omp_target_walk_data
10872 : {
10873 : /* Holds the 'this' expression found in current function. */
10874 : tree current_object;
10875 :
10876 : /* True if the 'this' expression was accessed in the target body. */
10877 : bool this_expr_accessed;
10878 :
10879 : /* For non-static functions, record which pointer-typed members were
10880 : accessed, and the whole expression. */
10881 : hash_map<tree, tree> ptr_members_accessed;
10882 :
10883 : /* Record which lambda objects were accessed in target body. */
10884 : hash_set<tree> lambda_objects_accessed;
10885 :
10886 : /* For lambda functions, the __closure object expression of the current
10887 : function, and the set of captured variables accessed in target body. */
10888 : tree current_closure;
10889 : hash_set<tree> closure_vars_accessed;
10890 :
10891 : /* Local variables declared inside a BIND_EXPR, used to filter out such
10892 : variables when recording lambda_objects_accessed. */
10893 : hash_set<tree> local_decls;
10894 :
10895 : omp_mapper_list<tree> *mappers;
10896 : };
10897 :
10898 : /* Helper function of finish_omp_target_clauses, called via
10899 : cp_walk_tree_without_duplicates. Traverse body of OpenMP target
10900 : directive *TP, and fill out omp_target_walk_data passed in *PTR. */
10901 :
10902 : static tree
10903 226322 : finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr)
10904 : {
10905 226322 : tree t = *tp;
10906 226322 : struct omp_target_walk_data *data = (struct omp_target_walk_data *) ptr;
10907 226322 : tree current_object = data->current_object;
10908 226322 : tree current_closure = data->current_closure;
10909 226322 : omp_mapper_list<tree> *mlist = data->mappers;
10910 :
10911 : /* References inside of these expression codes shouldn't incur any
10912 : form of mapping, so return early. */
10913 226322 : if (TREE_CODE (t) == SIZEOF_EXPR
10914 226314 : || TREE_CODE (t) == ALIGNOF_EXPR)
10915 : {
10916 8 : *walk_subtrees = 0;
10917 8 : return NULL_TREE;
10918 : }
10919 :
10920 226314 : if (TREE_CODE (t) == OMP_CLAUSE)
10921 : return NULL_TREE;
10922 :
10923 213729 : if (!processing_template_decl)
10924 : {
10925 213729 : tree aggr_type = NULL_TREE;
10926 :
10927 213729 : if (TREE_CODE (t) == COMPONENT_REF
10928 213729 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
10929 2233 : aggr_type = TREE_TYPE (TREE_OPERAND (t, 0));
10930 211496 : else if ((TREE_CODE (t) == VAR_DECL
10931 : || TREE_CODE (t) == PARM_DECL
10932 : || TREE_CODE (t) == RESULT_DECL)
10933 16821 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
10934 1214 : aggr_type = TREE_TYPE (t);
10935 :
10936 3447 : if (aggr_type)
10937 : {
10938 3447 : tree mapper_fn = cxx_omp_mapper_lookup (NULL_TREE, aggr_type);
10939 3447 : if (mapper_fn)
10940 173 : mlist->add_mapper (NULL_TREE, aggr_type, mapper_fn);
10941 : }
10942 : }
10943 :
10944 213729 : if (current_object)
10945 : {
10946 2564 : tree this_expr = TREE_OPERAND (current_object, 0);
10947 :
10948 2564 : if (operand_equal_p (t, this_expr))
10949 : {
10950 35 : data->this_expr_accessed = true;
10951 35 : *walk_subtrees = 0;
10952 35 : return NULL_TREE;
10953 : }
10954 :
10955 2529 : if (TREE_CODE (t) == COMPONENT_REF
10956 115 : && POINTER_TYPE_P (TREE_TYPE (t))
10957 36 : && operand_equal_p (TREE_OPERAND (t, 0), current_object)
10958 2563 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL)
10959 : {
10960 34 : data->this_expr_accessed = true;
10961 34 : tree fld = TREE_OPERAND (t, 1);
10962 34 : if (data->ptr_members_accessed.get (fld) == NULL)
10963 : {
10964 14 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
10965 4 : t = convert_from_reference (t);
10966 14 : data->ptr_members_accessed.put (fld, t);
10967 : }
10968 34 : *walk_subtrees = 0;
10969 34 : return NULL_TREE;
10970 : }
10971 : }
10972 :
10973 : /* When the current_function_decl is a lambda function, the closure object
10974 : argument's type seems to not yet have fields layed out, so a recording
10975 : of DECL_VALUE_EXPRs during the target body walk seems the only way to
10976 : find them. */
10977 213660 : if (current_closure
10978 300 : && (VAR_P (t)
10979 : || TREE_CODE (t) == PARM_DECL
10980 : || TREE_CODE (t) == RESULT_DECL)
10981 24 : && DECL_HAS_VALUE_EXPR_P (t)
10982 10 : && TREE_CODE (DECL_VALUE_EXPR (t)) == COMPONENT_REF
10983 213670 : && operand_equal_p (current_closure,
10984 10 : TREE_OPERAND (DECL_VALUE_EXPR (t), 0)))
10985 : {
10986 9 : if (!data->closure_vars_accessed.contains (t))
10987 9 : data->closure_vars_accessed.add (t);
10988 9 : *walk_subtrees = 0;
10989 9 : return NULL_TREE;
10990 : }
10991 :
10992 213651 : if (TREE_CODE (t) == BIND_EXPR)
10993 : {
10994 19908 : if (tree block = BIND_EXPR_BLOCK (t))
10995 22301 : for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
10996 2397 : if (!data->local_decls.contains (var))
10997 2397 : data->local_decls.add (var);
10998 19908 : return NULL_TREE;
10999 : }
11000 :
11001 198324 : if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
11002 : {
11003 39 : tree lt = TREE_TYPE (t);
11004 39 : gcc_assert (CLASS_TYPE_P (lt));
11005 :
11006 39 : if (!data->lambda_objects_accessed.contains (t)
11007 : /* Do not prepare to create target maps for locally declared
11008 : lambdas or anonymous ones. */
11009 39 : && !data->local_decls.contains (t)
11010 72 : && TREE_CODE (t) != TARGET_EXPR)
11011 13 : data->lambda_objects_accessed.add (t);
11012 39 : *walk_subtrees = 0;
11013 39 : return NULL_TREE;
11014 : }
11015 :
11016 : return NULL_TREE;
11017 : }
11018 :
11019 : /* Helper function for finish_omp_target, and also from tsubst_expr.
11020 : Create additional clauses for mapping of non-static members, lambda objects,
11021 : etc. */
11022 :
11023 : void
11024 6938 : finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr)
11025 : {
11026 6938 : omp_target_walk_data data;
11027 6938 : data.this_expr_accessed = false;
11028 6938 : data.current_object = NULL_TREE;
11029 :
11030 6938 : if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr)
11031 96 : if (tree ct = current_nonlambda_class_type ())
11032 : {
11033 95 : tree object = maybe_dummy_object (ct, NULL);
11034 95 : object = maybe_resolve_dummy (object, true);
11035 95 : data.current_object = object;
11036 : }
11037 :
11038 6938 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11039 : {
11040 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11041 8 : data.current_closure = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11042 : }
11043 : else
11044 6930 : data.current_closure = NULL_TREE;
11045 :
11046 6938 : auto_vec<tree, 16> new_clauses;
11047 :
11048 6938 : if (!processing_template_decl)
11049 : {
11050 6938 : hash_set<omp_name_type<tree> > seen_types;
11051 6938 : auto_vec<tree> mapper_fns;
11052 6938 : omp_mapper_list<tree> mlist (&seen_types, &mapper_fns);
11053 6938 : data.mappers = &mlist;
11054 :
11055 6938 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11056 : &data);
11057 :
11058 6938 : unsigned int i;
11059 6938 : tree mapper_fn;
11060 13965 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11061 89 : c_omp_find_nested_mappers (&mlist, mapper_fn);
11062 :
11063 7093 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11064 : {
11065 89 : tree mapper = cxx_omp_extract_mapper_directive (mapper_fn);
11066 89 : if (mapper == error_mark_node)
11067 0 : continue;
11068 89 : tree mapper_name = OMP_DECLARE_MAPPER_ID (mapper);
11069 89 : tree decl = OMP_DECLARE_MAPPER_DECL (mapper);
11070 89 : if (BASELINK_P (mapper_fn))
11071 0 : mapper_fn = BASELINK_FUNCTIONS (mapper_fn);
11072 :
11073 89 : tree c = build_omp_clause (loc, OMP_CLAUSE__MAPPER_BINDING_);
11074 89 : OMP_CLAUSE__MAPPER_BINDING__ID (c) = mapper_name;
11075 89 : OMP_CLAUSE__MAPPER_BINDING__DECL (c) = decl;
11076 89 : OMP_CLAUSE__MAPPER_BINDING__MAPPER (c) = mapper_fn;
11077 :
11078 89 : new_clauses.safe_push (c);
11079 : }
11080 6938 : }
11081 : else
11082 : {
11083 0 : data.mappers = NULL;
11084 0 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11085 : &data);
11086 : }
11087 :
11088 6938 : tree omp_target_this_expr = NULL_TREE;
11089 6938 : tree *explicit_this_deref_map = NULL;
11090 6938 : if (data.this_expr_accessed)
11091 : {
11092 31 : omp_target_this_expr = TREE_OPERAND (data.current_object, 0);
11093 :
11094 : /* See if explicit user-specified map(this[:]) clause already exists.
11095 : If not, we create an implicit map(tofrom:this[:1]) clause. */
11096 80 : for (tree *cp = clauses_ptr; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
11097 50 : if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
11098 47 : && (TREE_CODE (OMP_CLAUSE_DECL (*cp)) == INDIRECT_REF
11099 40 : || TREE_CODE (OMP_CLAUSE_DECL (*cp)) == MEM_REF)
11100 57 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*cp), 0),
11101 : omp_target_this_expr))
11102 : {
11103 : explicit_this_deref_map = cp;
11104 : break;
11105 : }
11106 : }
11107 :
11108 6938 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11109 6938 : && (data.this_expr_accessed
11110 1 : || !data.closure_vars_accessed.is_empty ()))
11111 : {
11112 : /* For lambda functions, we need to first create a copy of the
11113 : __closure object. */
11114 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11115 8 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11116 8 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11117 8 : OMP_CLAUSE_DECL (c)
11118 8 : = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11119 8 : OMP_CLAUSE_SIZE (c)
11120 8 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure)));
11121 8 : new_clauses.safe_push (c);
11122 :
11123 8 : tree closure_obj = OMP_CLAUSE_DECL (c);
11124 8 : tree closure_type = TREE_TYPE (closure_obj);
11125 :
11126 16 : gcc_assert (LAMBDA_TYPE_P (closure_type)
11127 : && CLASS_TYPE_P (closure_type));
11128 :
11129 8 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11130 8 : OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
11131 8 : OMP_CLAUSE_DECL (c2) = closure;
11132 8 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11133 8 : new_clauses.safe_push (c2);
11134 : }
11135 :
11136 6938 : if (data.this_expr_accessed)
11137 : {
11138 : /* If the this-expr was accessed, create a map(*this) clause. */
11139 31 : enum gomp_map_kind kind = GOMP_MAP_TOFROM;
11140 31 : if (explicit_this_deref_map)
11141 : {
11142 1 : tree this_map = *explicit_this_deref_map;
11143 1 : tree nc = OMP_CLAUSE_CHAIN (this_map);
11144 2 : gcc_assert (nc != NULL_TREE
11145 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11146 : && (OMP_CLAUSE_MAP_KIND (nc)
11147 : == GOMP_MAP_FIRSTPRIVATE_POINTER));
11148 1 : kind = OMP_CLAUSE_MAP_KIND (this_map);
11149 : /* Remove the original 'map(*this) map(firstprivate_ptr:this)'
11150 : two-map sequence away from the chain. */
11151 1 : *explicit_this_deref_map = OMP_CLAUSE_CHAIN (nc);
11152 : }
11153 31 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11154 31 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11155 31 : OMP_CLAUSE_DECL (c)
11156 31 : = build_indirect_ref (loc, omp_target_this_expr, RO_UNARY_STAR);
11157 31 : OMP_CLAUSE_SIZE (c)
11158 31 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (omp_target_this_expr)));
11159 31 : new_clauses.safe_push (c);
11160 :
11161 : /* If we're in a lambda function, the this-pointer will actually be
11162 : '__closure->this', a mapped member of __closure, hence always_pointer.
11163 : Otherwise it's a firstprivate pointer. */
11164 31 : enum gomp_map_kind ptr_kind
11165 31 : = (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11166 31 : ? GOMP_MAP_ALWAYS_POINTER
11167 24 : : GOMP_MAP_FIRSTPRIVATE_POINTER);
11168 31 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11169 31 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11170 31 : OMP_CLAUSE_DECL (c) = omp_target_this_expr;
11171 31 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11172 31 : new_clauses.safe_push (c);
11173 : }
11174 :
11175 6938 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11176 : {
11177 8 : if (omp_target_this_expr)
11178 : {
11179 7 : STRIP_NOPS (omp_target_this_expr);
11180 7 : gcc_assert (DECL_HAS_VALUE_EXPR_P (omp_target_this_expr));
11181 7 : omp_target_this_expr = DECL_VALUE_EXPR (omp_target_this_expr);
11182 : }
11183 :
11184 17 : for (hash_set<tree>::iterator i = data.closure_vars_accessed.begin ();
11185 34 : i != data.closure_vars_accessed.end (); ++i)
11186 : {
11187 9 : tree orig_decl = *i;
11188 9 : tree closure_expr = DECL_VALUE_EXPR (orig_decl);
11189 :
11190 9 : if (TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE
11191 9 : || TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE)
11192 : {
11193 : /* this-pointer is processed above, outside this loop. */
11194 3 : if (omp_target_this_expr
11195 3 : && operand_equal_p (closure_expr, omp_target_this_expr))
11196 0 : continue;
11197 :
11198 3 : bool ptr_p = TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE;
11199 3 : enum gomp_map_kind kind, ptr_kind, nc_kind;
11200 3 : tree size;
11201 :
11202 3 : if (ptr_p)
11203 : {
11204 : /* For pointers, default mapped as zero-length array
11205 : section. */
11206 2 : kind = GOMP_MAP_ALLOC;
11207 2 : nc_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
11208 2 : ptr_kind = GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
11209 2 : size = size_zero_node;
11210 : }
11211 : else
11212 : {
11213 : /* For references, default mapped as appearing on map
11214 : clause. */
11215 1 : kind = GOMP_MAP_TOFROM;
11216 1 : nc_kind = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
11217 1 : ptr_kind = GOMP_MAP_ALWAYS_POINTER;
11218 1 : size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure_expr)));
11219 : }
11220 :
11221 6 : for (tree *p = clauses_ptr; *p; p = &OMP_CLAUSE_CHAIN (*p))
11222 3 : if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_MAP
11223 1 : && (TREE_CODE (OMP_CLAUSE_DECL (*p)) == INDIRECT_REF
11224 1 : || TREE_CODE (OMP_CLAUSE_DECL (*p)) == MEM_REF)
11225 3 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*p), 0),
11226 : orig_decl))
11227 : {
11228 : /* If this was already specified by user as a map,
11229 : save the user specified map kind, delete the
11230 : "map(*ptr/ref), map(firstprivate ptr/ref)" sequence,
11231 : and insert our own sequence:
11232 : "map(*__closure->ptr/ref), map(<ptr_kind>:__closure->ref"
11233 : */
11234 0 : tree nc = OMP_CLAUSE_CHAIN (*p);
11235 0 : gcc_assert (nc != NULL_TREE
11236 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11237 : && OMP_CLAUSE_MAP_KIND (nc) == nc_kind);
11238 : /* Update with user specified kind and size. */
11239 0 : kind = OMP_CLAUSE_MAP_KIND (*p);
11240 0 : size = OMP_CLAUSE_SIZE (*p);
11241 0 : *p = OMP_CLAUSE_CHAIN (nc);
11242 0 : break;
11243 : }
11244 :
11245 3 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11246 3 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11247 3 : OMP_CLAUSE_DECL (c)
11248 3 : = build_indirect_ref (loc, closure_expr, RO_UNARY_STAR);
11249 3 : OMP_CLAUSE_SIZE (c) = size;
11250 3 : if (ptr_p)
11251 2 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11252 3 : new_clauses.safe_push (c);
11253 :
11254 3 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11255 3 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11256 3 : OMP_CLAUSE_DECL (c) = closure_expr;
11257 3 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11258 3 : new_clauses.safe_push (c);
11259 : }
11260 : }
11261 : }
11262 :
11263 6938 : if (!data.ptr_members_accessed.is_empty ())
11264 14 : for (hash_map<tree, tree>::iterator i = data.ptr_members_accessed.begin ();
11265 56 : i != data.ptr_members_accessed.end (); ++i)
11266 : {
11267 : /* For each referenced member that is of pointer or reference-to-pointer
11268 : type, create the equivalent of map(alloc:this->ptr[:0]). */
11269 14 : tree field_decl = (*i).first;
11270 14 : tree ptr_member = (*i).second;
11271 :
11272 26 : for (tree c = *clauses_ptr; c; c = OMP_CLAUSE_CHAIN (c))
11273 : {
11274 16 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
11275 2 : continue;
11276 : /* If map(this->ptr[:N]) already exists, avoid creating another
11277 : such map. */
11278 14 : tree decl = OMP_CLAUSE_DECL (c);
11279 14 : if ((TREE_CODE (decl) == INDIRECT_REF
11280 10 : || TREE_CODE (decl) == MEM_REF)
11281 14 : && operand_equal_p (TREE_OPERAND (decl, 0), ptr_member))
11282 4 : goto next_ptr_member;
11283 : }
11284 :
11285 10 : if (!cxx_mark_addressable (ptr_member))
11286 0 : gcc_unreachable ();
11287 :
11288 10 : if (TREE_CODE (TREE_TYPE (field_decl)) == REFERENCE_TYPE)
11289 : {
11290 : /* For reference to pointers, we need to map the referenced
11291 : pointer first for things to be correct. */
11292 4 : tree ptr_member_type = TREE_TYPE (ptr_member);
11293 :
11294 : /* Map pointer target as zero-length array section. */
11295 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11296 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11297 4 : OMP_CLAUSE_DECL (c)
11298 4 : = build1 (INDIRECT_REF, TREE_TYPE (ptr_member_type), ptr_member);
11299 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11300 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11301 :
11302 : /* Map pointer to zero-length array section. */
11303 4 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11304 4 : OMP_CLAUSE_SET_MAP_KIND
11305 : (c2, GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION);
11306 4 : OMP_CLAUSE_DECL (c2) = ptr_member;
11307 4 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11308 :
11309 : /* Attach reference-to-pointer field to pointer. */
11310 4 : tree c3 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11311 4 : OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH);
11312 4 : OMP_CLAUSE_DECL (c3) = TREE_OPERAND (ptr_member, 0);
11313 4 : OMP_CLAUSE_SIZE (c3) = size_zero_node;
11314 :
11315 4 : new_clauses.safe_push (c);
11316 4 : new_clauses.safe_push (c2);
11317 4 : new_clauses.safe_push (c3);
11318 : }
11319 6 : else if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
11320 : {
11321 : /* Map pointer target as zero-length array section. */
11322 6 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11323 6 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11324 6 : OMP_CLAUSE_DECL (c) = build_indirect_ref (loc, ptr_member,
11325 : RO_UNARY_STAR);
11326 6 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11327 6 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11328 :
11329 : /* Attach zero-length array section to pointer. */
11330 6 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11331 6 : OMP_CLAUSE_SET_MAP_KIND
11332 : (c2, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11333 6 : OMP_CLAUSE_DECL (c2) = ptr_member;
11334 6 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11335 :
11336 6 : new_clauses.safe_push (c);
11337 6 : new_clauses.safe_push (c2);
11338 : }
11339 : else
11340 0 : gcc_unreachable ();
11341 :
11342 14 : next_ptr_member:
11343 14 : ;
11344 : }
11345 :
11346 6951 : for (hash_set<tree>::iterator i = data.lambda_objects_accessed.begin ();
11347 6964 : i != data.lambda_objects_accessed.end (); ++i)
11348 : {
11349 13 : tree lobj = *i;
11350 13 : if (TREE_CODE (lobj) == TARGET_EXPR)
11351 0 : lobj = TARGET_EXPR_SLOT (lobj);
11352 :
11353 13 : tree lt = TREE_TYPE (lobj);
11354 26 : gcc_assert (LAMBDA_TYPE_P (lt) && CLASS_TYPE_P (lt));
11355 :
11356 13 : tree lc = build_omp_clause (loc, OMP_CLAUSE_MAP);
11357 13 : OMP_CLAUSE_SET_MAP_KIND (lc, GOMP_MAP_TO);
11358 13 : OMP_CLAUSE_DECL (lc) = lobj;
11359 13 : OMP_CLAUSE_SIZE (lc) = TYPE_SIZE_UNIT (lt);
11360 13 : new_clauses.safe_push (lc);
11361 :
11362 180 : for (tree fld = TYPE_FIELDS (lt); fld; fld = DECL_CHAIN (fld))
11363 : {
11364 167 : if (TREE_CODE (TREE_TYPE (fld)) == POINTER_TYPE)
11365 : {
11366 4 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11367 : lobj, fld, NULL_TREE);
11368 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11369 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11370 4 : OMP_CLAUSE_DECL (c)
11371 4 : = build_indirect_ref (loc, exp, RO_UNARY_STAR);
11372 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11373 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11374 4 : new_clauses.safe_push (c);
11375 :
11376 4 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11377 4 : OMP_CLAUSE_SET_MAP_KIND
11378 : (c, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11379 4 : OMP_CLAUSE_DECL (c) = exp;
11380 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11381 4 : new_clauses.safe_push (c);
11382 : }
11383 163 : else if (TREE_CODE (TREE_TYPE (fld)) == REFERENCE_TYPE)
11384 : {
11385 0 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11386 : lobj, fld, NULL_TREE);
11387 0 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11388 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11389 0 : OMP_CLAUSE_DECL (c)
11390 0 : = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
11391 0 : OMP_CLAUSE_SIZE (c)
11392 0 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (exp)));
11393 0 : new_clauses.safe_push (c);
11394 :
11395 0 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11396 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
11397 0 : OMP_CLAUSE_DECL (c) = exp;
11398 0 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11399 0 : new_clauses.safe_push (c);
11400 : }
11401 : }
11402 : }
11403 :
11404 6938 : tree c = *clauses_ptr;
11405 14094 : for (int i = new_clauses.length () - 1; i >= 0; i--)
11406 : {
11407 218 : OMP_CLAUSE_CHAIN (new_clauses[i]) = c;
11408 218 : c = new_clauses[i];
11409 : }
11410 6938 : *clauses_ptr = c;
11411 6938 : }
11412 :
11413 : /* Called from cp_parser_omp_target. Create additional implicit clauses for
11414 : OpenMP target directives, and do sanity checks. */
11415 :
11416 : tree
11417 6926 : finish_omp_target (location_t loc, tree clauses, tree body, bool combined_p)
11418 : {
11419 6926 : if (!processing_template_decl)
11420 6113 : finish_omp_target_clauses (loc, body, &clauses);
11421 :
11422 6926 : tree stmt = make_node (OMP_TARGET);
11423 6926 : TREE_TYPE (stmt) = void_type_node;
11424 6926 : OMP_TARGET_CLAUSES (stmt) = clauses;
11425 6926 : OMP_TARGET_BODY (stmt) = body;
11426 6926 : OMP_TARGET_COMBINED (stmt) = combined_p;
11427 6926 : SET_EXPR_LOCATION (stmt, loc);
11428 :
11429 6926 : tree c = clauses;
11430 16530 : while (c)
11431 : {
11432 9604 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11433 5534 : switch (OMP_CLAUSE_MAP_KIND (c))
11434 : {
11435 : case GOMP_MAP_TO:
11436 : case GOMP_MAP_ALWAYS_TO:
11437 : case GOMP_MAP_PRESENT_TO:
11438 : case GOMP_MAP_ALWAYS_PRESENT_TO:
11439 : case GOMP_MAP_FROM:
11440 : case GOMP_MAP_ALWAYS_FROM:
11441 : case GOMP_MAP_PRESENT_FROM:
11442 : case GOMP_MAP_ALWAYS_PRESENT_FROM:
11443 : case GOMP_MAP_TOFROM:
11444 : case GOMP_MAP_ALWAYS_TOFROM:
11445 : case GOMP_MAP_PRESENT_TOFROM:
11446 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
11447 : case GOMP_MAP_ALLOC:
11448 : case GOMP_MAP_PRESENT_ALLOC:
11449 : case GOMP_MAP_FIRSTPRIVATE_POINTER:
11450 : case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
11451 : case GOMP_MAP_ALWAYS_POINTER:
11452 : case GOMP_MAP_ATTACH_DETACH:
11453 : case GOMP_MAP_ATTACH:
11454 : case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
11455 : case GOMP_MAP_POINTER:
11456 : case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
11457 : break;
11458 3 : default:
11459 3 : error_at (OMP_CLAUSE_LOCATION (c),
11460 : "%<#pragma omp target%> with map-type other "
11461 : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
11462 : "on %<map%> clause");
11463 3 : break;
11464 : }
11465 9604 : c = OMP_CLAUSE_CHAIN (c);
11466 : }
11467 6926 : return add_stmt (stmt);
11468 : }
11469 :
11470 : tree
11471 9321 : finish_omp_parallel (tree clauses, tree body)
11472 : {
11473 9321 : tree stmt;
11474 :
11475 9321 : body = finish_omp_structured_block (body);
11476 :
11477 9321 : stmt = make_node (OMP_PARALLEL);
11478 9321 : TREE_TYPE (stmt) = void_type_node;
11479 9321 : OMP_PARALLEL_CLAUSES (stmt) = clauses;
11480 9321 : OMP_PARALLEL_BODY (stmt) = body;
11481 :
11482 9321 : return add_stmt (stmt);
11483 : }
11484 :
11485 : tree
11486 2161 : begin_omp_task (void)
11487 : {
11488 2161 : keep_next_level (true);
11489 2161 : return begin_omp_structured_block ();
11490 : }
11491 :
11492 : tree
11493 2161 : finish_omp_task (tree clauses, tree body)
11494 : {
11495 2161 : tree stmt;
11496 :
11497 2161 : body = finish_omp_structured_block (body);
11498 :
11499 2161 : stmt = make_node (OMP_TASK);
11500 2161 : TREE_TYPE (stmt) = void_type_node;
11501 2161 : OMP_TASK_CLAUSES (stmt) = clauses;
11502 2161 : OMP_TASK_BODY (stmt) = body;
11503 :
11504 2161 : return add_stmt (stmt);
11505 : }
11506 :
11507 : /* Helper function for finish_omp_for. Convert Ith random access iterator
11508 : into integral iterator. Return FALSE if successful. */
11509 :
11510 : static bool
11511 813 : handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
11512 : tree declv, tree orig_declv, tree initv,
11513 : tree condv, tree incrv, tree *body,
11514 : tree *pre_body, tree &clauses,
11515 : int collapse, int ordered)
11516 : {
11517 813 : tree diff, iter_init, iter_incr = NULL, last;
11518 813 : tree incr_var = NULL, orig_pre_body, orig_body, c;
11519 813 : tree decl = TREE_VEC_ELT (declv, i);
11520 813 : tree init = TREE_VEC_ELT (initv, i);
11521 813 : tree cond = TREE_VEC_ELT (condv, i);
11522 813 : tree incr = TREE_VEC_ELT (incrv, i);
11523 813 : tree iter = decl;
11524 813 : location_t elocus = locus;
11525 :
11526 813 : if (init && EXPR_HAS_LOCATION (init))
11527 12 : elocus = EXPR_LOCATION (init);
11528 :
11529 813 : switch (TREE_CODE (cond))
11530 : {
11531 810 : case GT_EXPR:
11532 810 : case GE_EXPR:
11533 810 : case LT_EXPR:
11534 810 : case LE_EXPR:
11535 810 : case NE_EXPR:
11536 810 : if (TREE_OPERAND (cond, 1) == iter)
11537 42 : cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
11538 42 : TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
11539 810 : if (TREE_OPERAND (cond, 0) != iter)
11540 0 : cond = error_mark_node;
11541 : else
11542 : {
11543 810 : tree tem = build_x_binary_op (EXPR_LOCATION (cond),
11544 810 : TREE_CODE (cond),
11545 : iter, ERROR_MARK,
11546 810 : TREE_OPERAND (cond, 1), ERROR_MARK,
11547 : NULL_TREE, NULL, tf_warning_or_error);
11548 810 : if (error_operand_p (tem))
11549 : return true;
11550 : }
11551 : break;
11552 3 : default:
11553 3 : cond = error_mark_node;
11554 3 : break;
11555 : }
11556 810 : if (cond == error_mark_node)
11557 : {
11558 3 : error_at (elocus, "invalid controlling predicate");
11559 3 : return true;
11560 : }
11561 807 : diff = build_x_binary_op (elocus, MINUS_EXPR,
11562 807 : TREE_OPERAND (cond, 1), ERROR_MARK,
11563 : iter, ERROR_MARK,
11564 : NULL_TREE, NULL, tf_warning_or_error);
11565 807 : diff = cp_fully_fold (diff);
11566 807 : if (error_operand_p (diff))
11567 : return true;
11568 807 : if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
11569 : {
11570 0 : error_at (elocus, "difference between %qE and %qD does not have integer type",
11571 0 : TREE_OPERAND (cond, 1), iter);
11572 0 : return true;
11573 : }
11574 807 : if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
11575 807 : TREE_VEC_ELT (declv, i), NULL_TREE,
11576 : cond, cp_walk_subtrees))
11577 : return true;
11578 :
11579 762 : switch (TREE_CODE (incr))
11580 : {
11581 370 : case PREINCREMENT_EXPR:
11582 370 : case PREDECREMENT_EXPR:
11583 370 : case POSTINCREMENT_EXPR:
11584 370 : case POSTDECREMENT_EXPR:
11585 370 : if (TREE_OPERAND (incr, 0) != iter)
11586 : {
11587 0 : incr = error_mark_node;
11588 0 : break;
11589 : }
11590 370 : iter_incr = build_x_unary_op (EXPR_LOCATION (incr),
11591 370 : TREE_CODE (incr), iter,
11592 : NULL_TREE, tf_warning_or_error);
11593 370 : if (error_operand_p (iter_incr))
11594 : return true;
11595 370 : else if (TREE_CODE (incr) == PREINCREMENT_EXPR
11596 219 : || TREE_CODE (incr) == POSTINCREMENT_EXPR)
11597 299 : incr = integer_one_node;
11598 : else
11599 71 : incr = integer_minus_one_node;
11600 : break;
11601 392 : case MODIFY_EXPR:
11602 392 : if (TREE_OPERAND (incr, 0) != iter)
11603 0 : incr = error_mark_node;
11604 392 : else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
11605 392 : || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
11606 : {
11607 392 : tree rhs = TREE_OPERAND (incr, 1);
11608 392 : if (TREE_OPERAND (rhs, 0) == iter)
11609 : {
11610 299 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
11611 : != INTEGER_TYPE)
11612 0 : incr = error_mark_node;
11613 : else
11614 : {
11615 299 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11616 299 : iter, TREE_CODE (rhs),
11617 299 : TREE_OPERAND (rhs, 1),
11618 : NULL_TREE,
11619 : tf_warning_or_error);
11620 299 : if (error_operand_p (iter_incr))
11621 : return true;
11622 299 : incr = TREE_OPERAND (rhs, 1);
11623 299 : incr = cp_convert (TREE_TYPE (diff), incr,
11624 : tf_warning_or_error);
11625 299 : if (TREE_CODE (rhs) == MINUS_EXPR)
11626 : {
11627 16 : incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
11628 16 : incr = fold_simple (incr);
11629 : }
11630 299 : if (TREE_CODE (incr) != INTEGER_CST
11631 299 : && (TREE_CODE (incr) != NOP_EXPR
11632 66 : || (TREE_CODE (TREE_OPERAND (incr, 0))
11633 : != INTEGER_CST)))
11634 : iter_incr = NULL;
11635 : }
11636 : }
11637 93 : else if (TREE_OPERAND (rhs, 1) == iter)
11638 : {
11639 93 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
11640 93 : || TREE_CODE (rhs) != PLUS_EXPR)
11641 0 : incr = error_mark_node;
11642 : else
11643 : {
11644 93 : iter_incr = build_x_binary_op (EXPR_LOCATION (rhs),
11645 : PLUS_EXPR,
11646 93 : TREE_OPERAND (rhs, 0),
11647 : ERROR_MARK, iter,
11648 : ERROR_MARK, NULL_TREE, NULL,
11649 : tf_warning_or_error);
11650 93 : if (error_operand_p (iter_incr))
11651 : return true;
11652 93 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11653 : iter, NOP_EXPR,
11654 : iter_incr, NULL_TREE,
11655 : tf_warning_or_error);
11656 93 : if (error_operand_p (iter_incr))
11657 : return true;
11658 93 : incr = TREE_OPERAND (rhs, 0);
11659 93 : iter_incr = NULL;
11660 : }
11661 : }
11662 : else
11663 0 : incr = error_mark_node;
11664 : }
11665 : else
11666 0 : incr = error_mark_node;
11667 : break;
11668 0 : default:
11669 0 : incr = error_mark_node;
11670 0 : break;
11671 : }
11672 :
11673 762 : if (incr == error_mark_node)
11674 : {
11675 0 : error_at (elocus, "invalid increment expression");
11676 0 : return true;
11677 : }
11678 :
11679 762 : incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
11680 762 : incr = cp_fully_fold (incr);
11681 762 : tree loop_iv_seen = NULL_TREE;
11682 1735 : for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11683 1093 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11684 1093 : && OMP_CLAUSE_DECL (c) == iter)
11685 : {
11686 120 : if (code == OMP_TASKLOOP || code == OMP_LOOP)
11687 : {
11688 60 : loop_iv_seen = c;
11689 60 : OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
11690 : }
11691 : break;
11692 : }
11693 973 : else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
11694 113 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
11695 1007 : && OMP_CLAUSE_DECL (c) == iter)
11696 : {
11697 30 : loop_iv_seen = c;
11698 30 : if (code == OMP_TASKLOOP)
11699 25 : OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
11700 : }
11701 :
11702 762 : decl = create_temporary_var (TREE_TYPE (diff));
11703 762 : pushdecl (decl);
11704 762 : add_decl_expr (decl);
11705 762 : last = create_temporary_var (TREE_TYPE (diff));
11706 762 : pushdecl (last);
11707 762 : add_decl_expr (last);
11708 762 : if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST
11709 10 : && (!ordered || (i < collapse && collapse > 1)))
11710 : {
11711 10 : incr_var = create_temporary_var (TREE_TYPE (diff));
11712 10 : pushdecl (incr_var);
11713 10 : add_decl_expr (incr_var);
11714 : }
11715 762 : gcc_assert (stmts_are_full_exprs_p ());
11716 762 : tree diffvar = NULL_TREE;
11717 762 : if (code == OMP_TASKLOOP)
11718 : {
11719 101 : if (!loop_iv_seen)
11720 : {
11721 38 : tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11722 38 : OMP_CLAUSE_DECL (ivc) = iter;
11723 38 : cxx_omp_finish_clause (ivc, NULL, false);
11724 38 : OMP_CLAUSE_CHAIN (ivc) = clauses;
11725 38 : clauses = ivc;
11726 : }
11727 101 : tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11728 101 : OMP_CLAUSE_DECL (lvc) = last;
11729 101 : OMP_CLAUSE_CHAIN (lvc) = clauses;
11730 101 : clauses = lvc;
11731 101 : diffvar = create_temporary_var (TREE_TYPE (diff));
11732 101 : pushdecl (diffvar);
11733 101 : add_decl_expr (diffvar);
11734 : }
11735 661 : else if (code == OMP_LOOP)
11736 : {
11737 43 : if (!loop_iv_seen)
11738 : {
11739 : /* While iterators on the loop construct are predetermined
11740 : lastprivate, if the decl is not declared inside of the
11741 : loop, OMP_CLAUSE_LASTPRIVATE should have been added
11742 : already. */
11743 16 : loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11744 16 : OMP_CLAUSE_DECL (loop_iv_seen) = iter;
11745 16 : OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
11746 16 : clauses = loop_iv_seen;
11747 : }
11748 27 : else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
11749 : {
11750 5 : OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
11751 5 : OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
11752 5 : OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
11753 : }
11754 43 : if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
11755 21 : cxx_omp_finish_clause (loop_iv_seen, NULL, false);
11756 : }
11757 :
11758 762 : orig_pre_body = *pre_body;
11759 762 : *pre_body = push_stmt_list ();
11760 762 : if (orig_pre_body)
11761 610 : add_stmt (orig_pre_body);
11762 762 : if (init != NULL)
11763 61 : finish_expr_stmt (build_x_modify_expr (elocus,
11764 : iter, NOP_EXPR, init,
11765 : NULL_TREE, tf_warning_or_error));
11766 762 : init = build_int_cst (TREE_TYPE (diff), 0);
11767 762 : if (c && iter_incr == NULL
11768 28 : && (!ordered || (i < collapse && collapse > 1)))
11769 : {
11770 28 : if (incr_var)
11771 : {
11772 10 : finish_expr_stmt (build_x_modify_expr (elocus,
11773 : incr_var, NOP_EXPR,
11774 : incr, NULL_TREE,
11775 : tf_warning_or_error));
11776 10 : incr = incr_var;
11777 : }
11778 28 : iter_incr = build_x_modify_expr (elocus,
11779 : iter, PLUS_EXPR, incr,
11780 : NULL_TREE, tf_warning_or_error);
11781 : }
11782 762 : if (c && ordered && i < collapse && collapse > 1)
11783 762 : iter_incr = incr;
11784 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11785 : last, NOP_EXPR, init,
11786 : NULL_TREE, tf_warning_or_error));
11787 762 : if (diffvar)
11788 : {
11789 101 : finish_expr_stmt (build_x_modify_expr (elocus,
11790 : diffvar, NOP_EXPR,
11791 : diff, NULL_TREE, tf_warning_or_error));
11792 101 : diff = diffvar;
11793 : }
11794 762 : *pre_body = pop_stmt_list (*pre_body);
11795 :
11796 1524 : cond = cp_build_binary_op (elocus,
11797 762 : TREE_CODE (cond), decl, diff,
11798 : tf_warning_or_error);
11799 762 : incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
11800 : elocus, incr, NULL_TREE);
11801 :
11802 762 : orig_body = *body;
11803 762 : *body = push_stmt_list ();
11804 762 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
11805 762 : iter_init = build_x_modify_expr (elocus,
11806 : iter, PLUS_EXPR, iter_init,
11807 : NULL_TREE, tf_warning_or_error);
11808 762 : if (iter_init != error_mark_node)
11809 759 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11810 762 : finish_expr_stmt (iter_init);
11811 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11812 : last, NOP_EXPR, decl,
11813 : NULL_TREE, tf_warning_or_error));
11814 762 : add_stmt (orig_body);
11815 762 : *body = pop_stmt_list (*body);
11816 :
11817 762 : if (c)
11818 : {
11819 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list ();
11820 120 : if (!ordered)
11821 114 : finish_expr_stmt (iter_incr);
11822 : else
11823 : {
11824 6 : iter_init = decl;
11825 6 : if (i < collapse && collapse > 1 && !error_operand_p (iter_incr))
11826 2 : iter_init = build2 (PLUS_EXPR, TREE_TYPE (diff),
11827 : iter_init, iter_incr);
11828 6 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), iter_init, last);
11829 6 : iter_init = build_x_modify_expr (elocus,
11830 : iter, PLUS_EXPR, iter_init,
11831 : NULL_TREE, tf_warning_or_error);
11832 6 : if (iter_init != error_mark_node)
11833 6 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11834 6 : finish_expr_stmt (iter_init);
11835 : }
11836 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c)
11837 240 : = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c));
11838 : }
11839 :
11840 762 : if (TREE_CODE (TREE_VEC_ELT (orig_declv, i)) == TREE_LIST)
11841 : {
11842 116 : tree t = TREE_VEC_ELT (orig_declv, i);
11843 116 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
11844 : && TREE_VALUE (t) == NULL_TREE
11845 : && TREE_CODE (TREE_CHAIN (t)) == TREE_VEC);
11846 116 : TREE_PURPOSE (t) = TREE_VEC_ELT (declv, i);
11847 116 : TREE_VALUE (t) = last;
11848 : }
11849 : else
11850 646 : TREE_VEC_ELT (orig_declv, i)
11851 1292 : = tree_cons (TREE_VEC_ELT (declv, i), last, NULL_TREE);
11852 762 : TREE_VEC_ELT (declv, i) = decl;
11853 762 : TREE_VEC_ELT (initv, i) = init;
11854 762 : TREE_VEC_ELT (condv, i) = cond;
11855 762 : TREE_VEC_ELT (incrv, i) = incr;
11856 :
11857 762 : return false;
11858 : }
11859 :
11860 : /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
11861 : are directly for their associated operands in the statement. DECL
11862 : and INIT are a combo; if DECL is NULL then INIT ought to be a
11863 : MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
11864 : optional statements that need to go before the loop into its
11865 : sk_omp scope. */
11866 :
11867 : tree
11868 21128 : finish_omp_for (location_t locus, enum tree_code code, tree declv,
11869 : tree orig_declv, tree initv, tree condv, tree incrv,
11870 : tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
11871 : {
11872 21128 : tree omp_for = NULL, orig_incr = NULL;
11873 21128 : tree decl = NULL, init, cond, incr;
11874 21128 : location_t elocus;
11875 21128 : int i;
11876 21128 : int collapse = 1;
11877 21128 : int ordered = 0;
11878 21128 : auto_vec<location_t> init_locv;
11879 :
11880 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
11881 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
11882 21128 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
11883 21128 : if (TREE_VEC_LENGTH (declv) > 1)
11884 : {
11885 4054 : if (tree ti = omp_find_clause (clauses, OMP_CLAUSE_TILE))
11886 83 : collapse = list_length (OMP_CLAUSE_TILE_LIST (ti));
11887 : else
11888 : {
11889 3971 : if (tree co = omp_find_clause (clauses, OMP_CLAUSE_COLLAPSE))
11890 3501 : collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
11891 470 : else if (tree si = omp_find_clause (clauses, OMP_CLAUSE_SIZES))
11892 394 : collapse = list_length (OMP_CLAUSE_SIZES_LIST (si));
11893 3971 : if (collapse != TREE_VEC_LENGTH (declv))
11894 100 : ordered = TREE_VEC_LENGTH (declv);
11895 : }
11896 : }
11897 48601 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
11898 : {
11899 27509 : decl = TREE_VEC_ELT (declv, i);
11900 27509 : init = TREE_VEC_ELT (initv, i);
11901 27509 : cond = TREE_VEC_ELT (condv, i);
11902 27509 : incr = TREE_VEC_ELT (incrv, i);
11903 27509 : elocus = locus;
11904 :
11905 27509 : if (decl == global_namespace)
11906 : {
11907 1101 : gcc_assert (init == NULL_TREE && cond == NULL_TREE && incr == NULL_TREE);
11908 1101 : TREE_VEC_ELT (declv, i) = NULL_TREE;
11909 1101 : init_locv.safe_push (UNKNOWN_LOCATION);
11910 1101 : continue;
11911 : }
11912 : /* We are going to throw out the init's original MODIFY_EXPR or
11913 : MODOP_EXPR below. Save its location so we can use it when
11914 : reconstructing the expression farther down. Alternatively, if the
11915 : initializer is a binding of the iteration variable, save
11916 : that location. Any of these locations in the initialization clause
11917 : for the current nested loop are better than using the argument locus,
11918 : that points to the "for" of the outermost loop in the nest. */
11919 26408 : if (init && EXPR_HAS_LOCATION (init))
11920 17875 : elocus = EXPR_LOCATION (init);
11921 8533 : else if (decl && INDIRECT_REF_P (decl) && EXPR_HAS_LOCATION (decl))
11922 : /* This can happen for class iterators. */
11923 0 : elocus = EXPR_LOCATION (decl);
11924 8533 : else if (decl && DECL_P (decl))
11925 : {
11926 8506 : if (DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
11927 8506 : elocus = DECL_SOURCE_LOCATION (decl);
11928 0 : else if (DECL_INITIAL (decl)
11929 0 : && EXPR_HAS_LOCATION (DECL_INITIAL (decl)))
11930 0 : elocus = EXPR_LOCATION (DECL_INITIAL (decl));
11931 : }
11932 26408 : init_locv.safe_push (elocus);
11933 :
11934 26408 : if (decl == NULL)
11935 : {
11936 16564 : if (init != NULL)
11937 16561 : switch (TREE_CODE (init))
11938 : {
11939 16176 : case MODIFY_EXPR:
11940 16176 : decl = TREE_OPERAND (init, 0);
11941 16176 : init = TREE_OPERAND (init, 1);
11942 16176 : break;
11943 367 : case MODOP_EXPR:
11944 367 : if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
11945 : {
11946 367 : decl = TREE_OPERAND (init, 0);
11947 367 : init = TREE_OPERAND (init, 2);
11948 : }
11949 : break;
11950 : default:
11951 : break;
11952 : }
11953 :
11954 16564 : if (decl == NULL)
11955 : {
11956 21 : error_at (locus,
11957 : "expected iteration declaration or initialization");
11958 21 : return NULL;
11959 : }
11960 : }
11961 :
11962 26387 : if (cond == global_namespace)
11963 170 : continue;
11964 :
11965 26217 : if (cond == NULL)
11966 : {
11967 9 : error_at (elocus, "missing controlling predicate");
11968 9 : return NULL;
11969 : }
11970 :
11971 26208 : if (incr == NULL)
11972 : {
11973 6 : error_at (elocus, "missing increment expression");
11974 6 : return NULL;
11975 : }
11976 :
11977 26202 : TREE_VEC_ELT (declv, i) = decl;
11978 26202 : TREE_VEC_ELT (initv, i) = init;
11979 : }
11980 :
11981 21092 : if (orig_inits)
11982 : {
11983 : bool fail = false;
11984 : tree orig_init;
11985 21214 : FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
11986 1181 : if (orig_init
11987 3396 : && !c_omp_check_loop_iv_exprs (locus, code,
11988 : orig_declv ? orig_declv : declv, i,
11989 1164 : TREE_VEC_ELT (declv, i), orig_init,
11990 : NULL_TREE, cp_walk_subtrees))
11991 : fail = true;
11992 20033 : if (fail)
11993 887 : return NULL;
11994 : }
11995 :
11996 21035 : if (dependent_omp_for_p (declv, initv, condv, incrv, body))
11997 : {
11998 453 : tree stmt;
11999 :
12000 453 : stmt = make_node (code);
12001 :
12002 1499 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12003 : {
12004 593 : if (TREE_VEC_ELT (declv, i) == NULL_TREE)
12005 9 : continue;
12006 : /* This is really just a place-holder. We'll be decomposing this
12007 : again and going through the cp_build_modify_expr path below when
12008 : we instantiate the thing. */
12009 584 : TREE_VEC_ELT (initv, i)
12010 1168 : = build2_loc (init_locv[i], MODIFY_EXPR, void_type_node,
12011 584 : TREE_VEC_ELT (declv, i), TREE_VEC_ELT (initv, i));
12012 : }
12013 :
12014 453 : TREE_TYPE (stmt) = void_type_node;
12015 453 : OMP_FOR_INIT (stmt) = initv;
12016 453 : OMP_FOR_COND (stmt) = condv;
12017 453 : OMP_FOR_INCR (stmt) = incrv;
12018 453 : OMP_FOR_BODY (stmt) = body;
12019 453 : OMP_FOR_PRE_BODY (stmt) = pre_body;
12020 453 : OMP_FOR_CLAUSES (stmt) = clauses;
12021 :
12022 453 : SET_EXPR_LOCATION (stmt, locus);
12023 453 : return add_stmt (stmt);
12024 : }
12025 :
12026 20582 : if (!orig_declv)
12027 19795 : orig_declv = copy_node (declv);
12028 :
12029 20582 : if (processing_template_decl)
12030 612 : orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv));
12031 :
12032 48030 : for (i = 0; i < TREE_VEC_LENGTH (declv); )
12033 : {
12034 27540 : decl = TREE_VEC_ELT (declv, i);
12035 27540 : init = TREE_VEC_ELT (initv, i);
12036 27540 : cond = TREE_VEC_ELT (condv, i);
12037 27540 : incr = TREE_VEC_ELT (incrv, i);
12038 27540 : if (orig_incr)
12039 844 : TREE_VEC_ELT (orig_incr, i) = incr;
12040 27540 : elocus = init_locv[i];
12041 :
12042 27540 : if (decl == NULL_TREE)
12043 : {
12044 1092 : i++;
12045 1092 : continue;
12046 : }
12047 :
12048 26448 : if (!DECL_P (decl))
12049 : {
12050 6 : error_at (elocus, "expected iteration declaration or initialization");
12051 6 : return NULL;
12052 : }
12053 :
12054 26442 : if (incr && TREE_CODE (incr) == MODOP_EXPR)
12055 : {
12056 1 : if (orig_incr)
12057 1 : TREE_VEC_ELT (orig_incr, i) = incr;
12058 1 : incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
12059 1 : TREE_CODE (TREE_OPERAND (incr, 1)),
12060 1 : TREE_OPERAND (incr, 2),
12061 : tf_warning_or_error);
12062 : }
12063 :
12064 26442 : if (CLASS_TYPE_P (TREE_TYPE (decl)))
12065 : {
12066 825 : if (code == OMP_SIMD)
12067 : {
12068 12 : error_at (elocus, "%<#pragma omp simd%> used with class "
12069 : "iteration variable %qE", decl);
12070 12 : return NULL;
12071 : }
12072 813 : if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
12073 : initv, condv, incrv, &body,
12074 : &pre_body, clauses,
12075 : collapse, ordered))
12076 : return NULL;
12077 762 : continue;
12078 : }
12079 :
12080 51234 : if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
12081 27203 : && !TYPE_PTR_P (TREE_TYPE (decl)))
12082 : {
12083 14 : error_at (elocus, "invalid type for iteration variable %qE", decl);
12084 14 : return NULL;
12085 : }
12086 :
12087 25603 : if (!processing_template_decl && TREE_CODE (init) != TREE_VEC)
12088 24842 : init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
12089 : tf_warning_or_error);
12090 : else
12091 761 : init = build2_loc (elocus, MODIFY_EXPR, void_type_node, decl, init);
12092 25603 : if (decl == error_mark_node || init == error_mark_node)
12093 : return NULL;
12094 :
12095 25594 : TREE_VEC_ELT (declv, i) = decl;
12096 25594 : TREE_VEC_ELT (initv, i) = init;
12097 25594 : TREE_VEC_ELT (condv, i) = cond;
12098 25594 : TREE_VEC_ELT (incrv, i) = incr;
12099 25594 : i++;
12100 : }
12101 :
12102 20490 : if (pre_body && IS_EMPTY_STMT (pre_body))
12103 0 : pre_body = NULL;
12104 :
12105 40980 : omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
12106 : incrv, body, pre_body,
12107 20490 : !processing_template_decl);
12108 :
12109 : /* Check for iterators appearing in lb, b or incr expressions. */
12110 20490 : if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees))
12111 : omp_for = NULL_TREE;
12112 :
12113 20004 : if (omp_for == NULL)
12114 702 : return NULL;
12115 :
12116 19788 : add_stmt (omp_for);
12117 :
12118 45448 : for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
12119 : {
12120 25660 : init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i);
12121 25660 : if (init == NULL_TREE)
12122 1032 : continue;
12123 24628 : decl = TREE_OPERAND (init, 0);
12124 24628 : cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i);
12125 24628 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
12126 :
12127 24628 : if (!processing_template_decl)
12128 : {
12129 24107 : if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC)
12130 : {
12131 106 : tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1);
12132 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 1)
12133 106 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12134 106 : t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2);
12135 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 2)
12136 212 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12137 : }
12138 : else
12139 : {
12140 24001 : tree t = TREE_OPERAND (init, 1);
12141 24001 : TREE_OPERAND (init, 1)
12142 48002 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12143 : }
12144 24107 : if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC)
12145 : {
12146 121 : tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1);
12147 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1)
12148 121 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12149 121 : t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2);
12150 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2)
12151 242 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12152 : }
12153 : else
12154 : {
12155 23986 : tree t = TREE_OPERAND (cond, 1);
12156 23986 : TREE_OPERAND (cond, 1)
12157 47972 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12158 : }
12159 : }
12160 :
12161 24628 : if (TREE_CODE (incr) != MODIFY_EXPR)
12162 18426 : continue;
12163 :
12164 6202 : if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
12165 70 : && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
12166 6272 : && !processing_template_decl)
12167 : {
12168 64 : tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
12169 64 : if (TREE_SIDE_EFFECTS (t)
12170 8 : && t != decl
12171 70 : && (TREE_CODE (t) != NOP_EXPR
12172 0 : || TREE_OPERAND (t, 0) != decl))
12173 6 : TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
12174 12 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12175 :
12176 64 : t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
12177 64 : if (TREE_SIDE_EFFECTS (t)
12178 56 : && t != decl
12179 120 : && (TREE_CODE (t) != NOP_EXPR
12180 5 : || TREE_OPERAND (t, 0) != decl))
12181 56 : TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
12182 112 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12183 : }
12184 :
12185 6202 : if (orig_incr)
12186 177 : TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
12187 : }
12188 19788 : OMP_FOR_CLAUSES (omp_for) = clauses;
12189 :
12190 : /* For simd loops with non-static data member iterators, we could have added
12191 : OMP_CLAUSE_LINEAR clauses without OMP_CLAUSE_LINEAR_STEP. As we know the
12192 : step at this point, fill it in. */
12193 4735 : if (code == OMP_SIMD && !processing_template_decl
12194 24479 : && TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)) == 1)
12195 4619 : for (tree c = omp_find_clause (clauses, OMP_CLAUSE_LINEAR); c;
12196 561 : c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_LINEAR))
12197 561 : if (OMP_CLAUSE_LINEAR_STEP (c) == NULL_TREE)
12198 : {
12199 4 : decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0), 0);
12200 4 : gcc_assert (decl == OMP_CLAUSE_DECL (c));
12201 4 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
12202 4 : tree step, stept;
12203 4 : switch (TREE_CODE (incr))
12204 : {
12205 0 : case PREINCREMENT_EXPR:
12206 0 : case POSTINCREMENT_EXPR:
12207 : /* c_omp_for_incr_canonicalize_ptr() should have been
12208 : called to massage things appropriately. */
12209 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12210 0 : OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1);
12211 0 : break;
12212 0 : case PREDECREMENT_EXPR:
12213 0 : case POSTDECREMENT_EXPR:
12214 : /* c_omp_for_incr_canonicalize_ptr() should have been
12215 : called to massage things appropriately. */
12216 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12217 0 : OMP_CLAUSE_LINEAR_STEP (c)
12218 0 : = build_int_cst (TREE_TYPE (decl), -1);
12219 0 : break;
12220 4 : case MODIFY_EXPR:
12221 4 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12222 4 : incr = TREE_OPERAND (incr, 1);
12223 4 : switch (TREE_CODE (incr))
12224 : {
12225 4 : case PLUS_EXPR:
12226 4 : if (TREE_OPERAND (incr, 1) == decl)
12227 0 : step = TREE_OPERAND (incr, 0);
12228 : else
12229 4 : step = TREE_OPERAND (incr, 1);
12230 : break;
12231 0 : case MINUS_EXPR:
12232 0 : case POINTER_PLUS_EXPR:
12233 0 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12234 0 : step = TREE_OPERAND (incr, 1);
12235 0 : break;
12236 0 : default:
12237 0 : gcc_unreachable ();
12238 : }
12239 4 : stept = TREE_TYPE (decl);
12240 4 : if (INDIRECT_TYPE_P (stept))
12241 0 : stept = sizetype;
12242 4 : step = fold_convert (stept, step);
12243 4 : if (TREE_CODE (incr) == MINUS_EXPR)
12244 0 : step = fold_build1 (NEGATE_EXPR, stept, step);
12245 4 : OMP_CLAUSE_LINEAR_STEP (c) = step;
12246 4 : break;
12247 0 : default:
12248 0 : gcc_unreachable ();
12249 : }
12250 : }
12251 : /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
12252 : clauses, we need copy ctor for those rather than default ctor,
12253 : plus as for other lastprivates assignment op and dtor. */
12254 19788 : if (code == OMP_LOOP && !processing_template_decl)
12255 1993 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
12256 1285 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12257 204 : && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
12258 1307 : && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
12259 : false, true, true, true))
12260 0 : CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
12261 :
12262 : return omp_for;
12263 21128 : }
12264 :
12265 : /* Code walker for finish_omp_for_block: extract binding of DP->var
12266 : from its current block and move it to a new BIND_EXPR DP->b
12267 : surrounding the body of DP->omp_for. */
12268 :
12269 : struct fofb_data {
12270 : tree var;
12271 : tree b;
12272 : tree omp_for;
12273 : };
12274 :
12275 : static tree
12276 389 : finish_omp_for_block_walker (tree *tp, int *walk_subtrees, void *dp)
12277 : {
12278 389 : struct fofb_data *fofb = (struct fofb_data *)dp;
12279 389 : if (TREE_CODE (*tp) == BIND_EXPR)
12280 578 : for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
12281 : {
12282 576 : if (*p == fofb->var)
12283 : {
12284 363 : *p = DECL_CHAIN (*p);
12285 363 : if (fofb->b == NULL_TREE)
12286 : {
12287 214 : fofb->b = make_node (BLOCK);
12288 214 : fofb->b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12289 214 : OMP_FOR_BODY (fofb->omp_for), fofb->b);
12290 214 : TREE_SIDE_EFFECTS (fofb->b) = 1;
12291 214 : OMP_FOR_BODY (fofb->omp_for) = fofb->b;
12292 : }
12293 363 : DECL_CHAIN (fofb->var) = BIND_EXPR_VARS (fofb->b);
12294 363 : BIND_EXPR_VARS (fofb->b) = fofb->var;
12295 363 : BLOCK_VARS (BIND_EXPR_BLOCK (fofb->b)) = fofb->var;
12296 363 : BLOCK_VARS (BIND_EXPR_BLOCK (*tp)) = BIND_EXPR_VARS (*tp);
12297 363 : return *tp;
12298 : }
12299 : }
12300 26 : if (TREE_CODE (*tp) != BIND_EXPR && TREE_CODE (*tp) != STATEMENT_LIST)
12301 22 : *walk_subtrees = false;
12302 : return NULL_TREE;
12303 : }
12304 :
12305 : /* Fix up range for decls. Those decls were pushed into BIND's
12306 : BIND_EXPR_VARS, or that of a nested BIND_EXPR inside its body,
12307 : and need to be moved into a new BIND_EXPR surrounding OMP_FOR's body
12308 : so that processing of combined loop directives can find them. */
12309 : tree
12310 14525 : finish_omp_for_block (tree bind, tree omp_for)
12311 : {
12312 14525 : if (omp_for == NULL_TREE
12313 14478 : || !OMP_FOR_ORIG_DECLS (omp_for)
12314 28435 : || bind == NULL_TREE)
12315 615 : return bind;
12316 13910 : struct fofb_data fofb;
12317 13910 : fofb.b = NULL_TREE;
12318 13910 : fofb.omp_for = omp_for;
12319 33347 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (omp_for)); i++)
12320 19437 : if (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i)
12321 19215 : && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i))
12322 : == TREE_LIST)
12323 20268 : && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)))
12324 : {
12325 237 : tree v = TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i));
12326 602 : for (int j = 2; j < TREE_VEC_LENGTH (v); j++)
12327 : {
12328 365 : fofb.var = TREE_VEC_ELT (v, j);
12329 365 : cp_walk_tree (&bind, finish_omp_for_block_walker,
12330 : (void *)&fofb, NULL);
12331 : }
12332 : }
12333 13910 : return bind;
12334 : }
12335 :
12336 : void
12337 3342 : finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
12338 : tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
12339 : tree clauses, enum omp_memory_order mo, bool weak)
12340 : {
12341 3342 : tree orig_lhs;
12342 3342 : tree orig_rhs;
12343 3342 : tree orig_v;
12344 3342 : tree orig_lhs1;
12345 3342 : tree orig_rhs1;
12346 3342 : tree orig_r;
12347 3342 : bool dependent_p;
12348 3342 : tree stmt;
12349 :
12350 3342 : orig_lhs = lhs;
12351 3342 : orig_rhs = rhs;
12352 3342 : orig_v = v;
12353 3342 : orig_lhs1 = lhs1;
12354 3342 : orig_rhs1 = rhs1;
12355 3342 : orig_r = r;
12356 3342 : dependent_p = false;
12357 3342 : stmt = NULL_TREE;
12358 :
12359 : /* Even in a template, we can detect invalid uses of the atomic
12360 : pragma if neither LHS nor RHS is type-dependent. */
12361 3342 : if (processing_template_decl)
12362 : {
12363 600 : dependent_p = (type_dependent_expression_p (lhs)
12364 237 : || (rhs && type_dependent_expression_p (rhs))
12365 234 : || (v && type_dependent_expression_p (v))
12366 234 : || (lhs1 && type_dependent_expression_p (lhs1))
12367 234 : || (rhs1 && type_dependent_expression_p (rhs1))
12368 834 : || (r
12369 25 : && r != void_list_node
12370 16 : && type_dependent_expression_p (r)));
12371 600 : if (clauses)
12372 : {
12373 30 : gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE
12374 : && OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT
12375 : && OMP_CLAUSE_CHAIN (clauses) == NULL_TREE);
12376 30 : if (type_dependent_expression_p (OMP_CLAUSE_HINT_EXPR (clauses))
12377 30 : || TREE_CODE (OMP_CLAUSE_HINT_EXPR (clauses)) != INTEGER_CST)
12378 : dependent_p = true;
12379 : }
12380 : }
12381 576 : if (!dependent_p)
12382 : {
12383 2958 : bool swapped = false;
12384 2958 : if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs))
12385 : {
12386 143 : std::swap (rhs, rhs1);
12387 143 : swapped = !commutative_tree_code (opcode);
12388 : }
12389 2958 : if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1))
12390 : {
12391 0 : if (code == OMP_ATOMIC)
12392 0 : error ("%<#pragma omp atomic update%> uses two different "
12393 : "expressions for memory");
12394 : else
12395 0 : error ("%<#pragma omp atomic capture%> uses two different "
12396 : "expressions for memory");
12397 0 : return;
12398 : }
12399 2958 : if (lhs1 && !cp_tree_equal (lhs, lhs1))
12400 : {
12401 0 : if (code == OMP_ATOMIC)
12402 0 : error ("%<#pragma omp atomic update%> uses two different "
12403 : "expressions for memory");
12404 : else
12405 0 : error ("%<#pragma omp atomic capture%> uses two different "
12406 : "expressions for memory");
12407 0 : return;
12408 : }
12409 5916 : stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs,
12410 : v, lhs1, rhs1, r, swapped, mo, weak,
12411 2958 : processing_template_decl != 0);
12412 2958 : if (stmt == error_mark_node)
12413 : return;
12414 : }
12415 3312 : if (processing_template_decl)
12416 : {
12417 591 : if (code == OMP_ATOMIC_READ)
12418 : {
12419 167 : stmt = build_min_nt_loc (loc, OMP_ATOMIC_READ, orig_lhs);
12420 167 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12421 167 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12422 : }
12423 : else
12424 : {
12425 424 : if (opcode == NOP_EXPR)
12426 35 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
12427 389 : else if (opcode == COND_EXPR)
12428 : {
12429 124 : stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs);
12430 124 : if (orig_r)
12431 50 : stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r,
12432 : stmt);
12433 124 : stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1,
12434 : orig_lhs);
12435 124 : orig_rhs1 = NULL_TREE;
12436 : }
12437 : else
12438 265 : stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
12439 424 : if (orig_rhs1)
12440 182 : stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
12441 : COMPOUND_EXPR, orig_rhs1, stmt);
12442 424 : if (code != OMP_ATOMIC)
12443 : {
12444 233 : stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt);
12445 233 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12446 233 : OMP_ATOMIC_WEAK (stmt) = weak;
12447 233 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12448 : }
12449 : }
12450 591 : stmt = build2 (OMP_ATOMIC, void_type_node,
12451 : clauses ? clauses : integer_zero_node, stmt);
12452 591 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12453 591 : OMP_ATOMIC_WEAK (stmt) = weak;
12454 591 : SET_EXPR_LOCATION (stmt, loc);
12455 : }
12456 :
12457 : /* Avoid -Wunused-value warnings here, the whole construct has side-effects
12458 : and even if it might be wrapped from fold-const.cc or c-omp.cc wrapped
12459 : in some tree that appears to be unused, the value is not unused. */
12460 3312 : warning_sentinel w (warn_unused_value);
12461 3312 : finish_expr_stmt (stmt);
12462 3312 : }
12463 :
12464 : void
12465 359 : finish_omp_barrier (void)
12466 : {
12467 359 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
12468 359 : releasing_vec vec;
12469 359 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12470 359 : finish_expr_stmt (stmt);
12471 359 : }
12472 :
12473 : void
12474 397 : finish_omp_depobj (location_t loc, tree depobj,
12475 : enum omp_clause_depend_kind kind, tree clause)
12476 : {
12477 397 : if (!error_operand_p (depobj) && !type_dependent_expression_p (depobj))
12478 : {
12479 343 : if (!lvalue_p (depobj))
12480 : {
12481 6 : error_at (EXPR_LOC_OR_LOC (depobj, loc),
12482 : "%<depobj%> expression is not lvalue expression");
12483 6 : depobj = error_mark_node;
12484 : }
12485 : }
12486 :
12487 397 : if (processing_template_decl)
12488 : {
12489 114 : if (clause == NULL_TREE)
12490 47 : clause = build_int_cst (integer_type_node, kind);
12491 114 : add_stmt (build_min_nt_loc (loc, OMP_DEPOBJ, depobj, clause));
12492 114 : return;
12493 : }
12494 :
12495 283 : if (!error_operand_p (depobj))
12496 : {
12497 274 : tree addr = cp_build_addr_expr (depobj, tf_warning_or_error);
12498 274 : if (addr == error_mark_node)
12499 : depobj = error_mark_node;
12500 : else
12501 274 : depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR,
12502 : tf_warning_or_error);
12503 : }
12504 :
12505 283 : c_finish_omp_depobj (loc, depobj, kind, clause);
12506 : }
12507 :
12508 : void
12509 162 : finish_omp_flush (int mo)
12510 : {
12511 162 : tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
12512 162 : releasing_vec vec;
12513 162 : if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST)
12514 : {
12515 54 : fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
12516 54 : vec->quick_push (build_int_cst (integer_type_node, mo));
12517 : }
12518 162 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12519 162 : finish_expr_stmt (stmt);
12520 162 : }
12521 :
12522 : void
12523 111 : finish_omp_taskwait (void)
12524 : {
12525 111 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
12526 111 : releasing_vec vec;
12527 111 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12528 111 : finish_expr_stmt (stmt);
12529 111 : }
12530 :
12531 : void
12532 16 : finish_omp_taskyield (void)
12533 : {
12534 16 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
12535 16 : releasing_vec vec;
12536 16 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12537 16 : finish_expr_stmt (stmt);
12538 16 : }
12539 :
12540 : void
12541 596 : finish_omp_cancel (tree clauses)
12542 : {
12543 596 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
12544 596 : int mask = 0;
12545 596 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12546 : mask = 1;
12547 414 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12548 : mask = 2;
12549 285 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12550 : mask = 4;
12551 164 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12552 : mask = 8;
12553 : else
12554 : {
12555 0 : error ("%<#pragma omp cancel%> must specify one of "
12556 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12557 0 : return;
12558 : }
12559 596 : releasing_vec vec;
12560 596 : tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
12561 596 : if (ifc != NULL_TREE)
12562 : {
12563 70 : if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
12564 70 : && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
12565 6 : error_at (OMP_CLAUSE_LOCATION (ifc),
12566 : "expected %<cancel%> %<if%> clause modifier");
12567 : else
12568 : {
12569 64 : tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
12570 64 : if (ifc2 != NULL_TREE)
12571 : {
12572 3 : gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
12573 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
12574 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
12575 3 : error_at (OMP_CLAUSE_LOCATION (ifc2),
12576 : "expected %<cancel%> %<if%> clause modifier");
12577 : }
12578 : }
12579 :
12580 70 : if (!processing_template_decl)
12581 61 : ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc));
12582 : else
12583 9 : ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
12584 9 : OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK,
12585 : integer_zero_node, ERROR_MARK,
12586 : NULL_TREE, NULL, tf_warning_or_error);
12587 : }
12588 : else
12589 526 : ifc = boolean_true_node;
12590 596 : vec->quick_push (build_int_cst (integer_type_node, mask));
12591 596 : vec->quick_push (ifc);
12592 596 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12593 596 : finish_expr_stmt (stmt);
12594 596 : }
12595 :
12596 : void
12597 494 : finish_omp_cancellation_point (tree clauses)
12598 : {
12599 494 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
12600 494 : int mask = 0;
12601 494 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12602 : mask = 1;
12603 366 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12604 : mask = 2;
12605 261 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12606 : mask = 4;
12607 156 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12608 : mask = 8;
12609 : else
12610 : {
12611 3 : error ("%<#pragma omp cancellation point%> must specify one of "
12612 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12613 3 : return;
12614 : }
12615 491 : releasing_vec vec
12616 491 : = make_tree_vector_single (build_int_cst (integer_type_node, mask));
12617 491 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12618 491 : finish_expr_stmt (stmt);
12619 491 : }
12620 :
12621 : /* Begin a __transaction_atomic or __transaction_relaxed statement.
12622 : If PCOMPOUND is non-null, this is for a function-transaction-block, and we
12623 : should create an extra compound stmt. */
12624 :
12625 : tree
12626 303 : begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
12627 : {
12628 303 : tree r;
12629 :
12630 303 : if (pcompound)
12631 21 : *pcompound = begin_compound_stmt (0);
12632 :
12633 303 : r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
12634 :
12635 : /* Only add the statement to the function if support enabled. */
12636 303 : if (flag_tm)
12637 297 : add_stmt (r);
12638 : else
12639 12 : error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
12640 : ? G_("%<__transaction_relaxed%> without "
12641 : "transactional memory support enabled")
12642 : : G_("%<__transaction_atomic%> without "
12643 : "transactional memory support enabled")));
12644 :
12645 303 : TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
12646 303 : TREE_SIDE_EFFECTS (r) = 1;
12647 303 : return r;
12648 : }
12649 :
12650 : /* End a __transaction_atomic or __transaction_relaxed statement.
12651 : If COMPOUND_STMT is non-null, this is for a function-transaction-block,
12652 : and we should end the compound. If NOEX is non-NULL, we wrap the body in
12653 : a MUST_NOT_THROW_EXPR with NOEX as condition. */
12654 :
12655 : void
12656 303 : finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
12657 : {
12658 303 : TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
12659 303 : TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
12660 303 : TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
12661 303 : TRANSACTION_EXPR_IS_STMT (stmt) = 1;
12662 :
12663 : /* noexcept specifications are not allowed for function transactions. */
12664 303 : gcc_assert (!(noex && compound_stmt));
12665 303 : if (noex)
12666 : {
12667 51 : tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
12668 : noex);
12669 51 : protected_set_expr_location
12670 51 : (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
12671 51 : TREE_SIDE_EFFECTS (body) = 1;
12672 51 : TRANSACTION_EXPR_BODY (stmt) = body;
12673 : }
12674 :
12675 303 : if (compound_stmt)
12676 21 : finish_compound_stmt (compound_stmt);
12677 303 : }
12678 :
12679 : /* Build a __transaction_atomic or __transaction_relaxed expression. If
12680 : NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
12681 : condition. */
12682 :
12683 : tree
12684 116 : build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
12685 : {
12686 116 : tree ret;
12687 116 : if (noex)
12688 : {
12689 57 : expr = build_must_not_throw_expr (expr, noex);
12690 57 : protected_set_expr_location (expr, loc);
12691 57 : TREE_SIDE_EFFECTS (expr) = 1;
12692 : }
12693 116 : ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
12694 116 : if (flags & TM_STMT_ATTR_RELAXED)
12695 4 : TRANSACTION_EXPR_RELAXED (ret) = 1;
12696 116 : TREE_SIDE_EFFECTS (ret) = 1;
12697 116 : SET_EXPR_LOCATION (ret, loc);
12698 116 : return ret;
12699 : }
12700 :
12701 : void
12702 98033 : init_cp_semantics (void)
12703 : {
12704 98033 : }
12705 :
12706 :
12707 : /* Get constant string at LOCATION. Returns true if successful,
12708 : otherwise false. */
12709 :
12710 : bool
12711 10766544 : cexpr_str::type_check (location_t location, bool allow_char8_t /*=false*/)
12712 : {
12713 10766544 : tsubst_flags_t complain = tf_warning_or_error;
12714 :
12715 10766544 : if (message == NULL_TREE
12716 10766544 : || message == error_mark_node
12717 21533085 : || check_for_bare_parameter_packs (message))
12718 3 : return false;
12719 :
12720 10766541 : if (TREE_CODE (message) != STRING_CST
12721 10766541 : && !type_dependent_expression_p (message))
12722 : {
12723 974 : message_sz
12724 974 : = finish_class_member_access_expr (message,
12725 : get_identifier ("size"),
12726 : false, complain);
12727 974 : if (message_sz != error_mark_node)
12728 887 : message_data
12729 887 : = finish_class_member_access_expr (message,
12730 : get_identifier ("data"),
12731 : false, complain);
12732 974 : if (message_sz == error_mark_node || message_data == error_mark_node)
12733 : {
12734 121 : error_at (location, "constexpr string must be a string "
12735 : "literal or object with %<size%> and "
12736 : "%<data%> members");
12737 292 : return false;
12738 : }
12739 853 : releasing_vec size_args, data_args;
12740 853 : message_sz = finish_call_expr (message_sz, &size_args, false, false,
12741 : complain);
12742 853 : message_data = finish_call_expr (message_data, &data_args, false, false,
12743 : complain);
12744 853 : if (message_sz == error_mark_node || message_data == error_mark_node)
12745 : return false;
12746 739 : message_sz = build_converted_constant_expr (size_type_node, message_sz,
12747 : complain);
12748 739 : if (message_sz == error_mark_node)
12749 : {
12750 15 : error_at (location, "constexpr string %<size()%> "
12751 : "must be implicitly convertible to "
12752 : "%<std::size_t%>");
12753 15 : return false;
12754 : }
12755 :
12756 724 : if (allow_char8_t
12757 35 : && POINTER_TYPE_P (TREE_TYPE (message_data))
12758 35 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
12759 35 : == char8_type_node)
12760 734 : && (TYPE_QUALS (TREE_TYPE (TREE_TYPE (message_data)))
12761 : == TYPE_QUAL_CONST))
12762 : return true;
12763 :
12764 714 : message_data = build_converted_constant_expr (const_string_type_node,
12765 : message_data, complain);
12766 714 : if (message_data == error_mark_node)
12767 : {
12768 32 : error_at (location, "constexpr string %<data()%> "
12769 : "must be implicitly convertible to "
12770 : "%<const char*%>");
12771 32 : return false;
12772 : }
12773 853 : }
12774 : return true;
12775 : }
12776 :
12777 : /* Extract constant string at LOCATON into output string STR.
12778 : Returns true if successful, otherwise false. */
12779 :
12780 : bool
12781 405 : cexpr_str::extract (location_t location, tree &str)
12782 : {
12783 405 : const char *msg;
12784 405 : int len;
12785 405 : if (!extract (location, msg, len))
12786 : return false;
12787 343 : str = build_string (len, msg);
12788 343 : return true;
12789 : }
12790 :
12791 : /* Extract constant string at LOCATION into output string MSG with LEN.
12792 : Returns true if successful, otherwise false. */
12793 :
12794 : bool
12795 2147 : cexpr_str::extract (location_t location, const char * &msg, int &len,
12796 : const constexpr_ctx *ctx /* = NULL */,
12797 : bool *non_constant_p /* = NULL */,
12798 : bool *overflow_p /* = NULL */,
12799 : tree *jump_target /* = NULL */)
12800 : {
12801 2147 : tsubst_flags_t complain = tf_warning_or_error;
12802 :
12803 2147 : msg = NULL;
12804 2147 : if (message_sz && message_data)
12805 : {
12806 618 : tree msz;
12807 618 : if (ctx)
12808 : {
12809 53 : msz = cxx_eval_constant_expression (ctx, message_sz, vc_prvalue,
12810 : non_constant_p, overflow_p,
12811 : jump_target);
12812 53 : if (*jump_target || *non_constant_p)
12813 : return false;
12814 : }
12815 : else
12816 565 : msz = cxx_constant_value (message_sz, NULL_TREE, complain);
12817 614 : if (!tree_fits_uhwi_p (msz))
12818 : {
12819 35 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12820 35 : error_at (location,
12821 : "constexpr string %<size()%> "
12822 : "must be a constant expression");
12823 35 : return false;
12824 : }
12825 579 : else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
12826 : != tree_to_uhwi (msz))
12827 : {
12828 0 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12829 0 : error_at (location,
12830 : "constexpr string message %<size()%> "
12831 : "%qE too large", msz);
12832 0 : return false;
12833 : }
12834 579 : len = tree_to_uhwi (msz);
12835 579 : tree data;
12836 579 : if (ctx)
12837 : {
12838 49 : data = cxx_eval_constant_expression (ctx, message_data, vc_prvalue,
12839 : non_constant_p, overflow_p,
12840 : jump_target);
12841 49 : if (*jump_target || *non_constant_p)
12842 : return false;
12843 45 : STRIP_NOPS (data);
12844 45 : if (TREE_CODE (data) != ADDR_EXPR)
12845 : {
12846 0 : unhandled:
12847 0 : if (!cxx_constexpr_quiet_p (ctx))
12848 0 : error_at (location, "unhandled return from %<data()%>");
12849 0 : return false;
12850 : }
12851 45 : tree str = TREE_OPERAND (data, 0);
12852 45 : unsigned HOST_WIDE_INT off = 0;
12853 45 : if (TREE_CODE (str) == ARRAY_REF
12854 45 : && tree_fits_uhwi_p (TREE_OPERAND (str, 1)))
12855 : {
12856 6 : off = tree_to_uhwi (TREE_OPERAND (str, 1));
12857 6 : str = TREE_OPERAND (str, 0);
12858 : }
12859 45 : str = cxx_eval_constant_expression (ctx, str, vc_prvalue,
12860 : non_constant_p, overflow_p,
12861 : jump_target);
12862 45 : if (*jump_target || *non_constant_p)
12863 : return false;
12864 45 : if (TREE_CODE (str) == STRING_CST)
12865 : {
12866 42 : if (TREE_STRING_LENGTH (str) < len
12867 42 : || (unsigned) TREE_STRING_LENGTH (str) < off
12868 84 : || (unsigned) TREE_STRING_LENGTH (str) < off + len)
12869 0 : goto unhandled;
12870 42 : msg = TREE_STRING_POINTER (str) + off;
12871 42 : goto translate;
12872 : }
12873 3 : if (TREE_CODE (str) != CONSTRUCTOR
12874 3 : || TREE_CODE (TREE_TYPE (str)) != ARRAY_TYPE)
12875 0 : goto unhandled;
12876 3 : char *b;
12877 3 : if (len < 64)
12878 3 : b = XALLOCAVEC (char, len + 1);
12879 : else
12880 : {
12881 0 : buf = XNEWVEC (char, len + 1);
12882 0 : b = buf;
12883 : }
12884 3 : msg = b;
12885 3 : memset (b, 0, len + 1);
12886 3 : tree field, value;
12887 3 : unsigned k;
12888 3 : unsigned HOST_WIDE_INT l = 0;
12889 33 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (str), k, field, value)
12890 33 : if (!tree_fits_shwi_p (value))
12891 0 : goto unhandled;
12892 33 : else if (field == NULL_TREE)
12893 : {
12894 0 : if (integer_zerop (value))
12895 : break;
12896 0 : if (l >= off && l < off + len)
12897 0 : b[l - off] = tree_to_shwi (value);
12898 0 : ++l;
12899 : }
12900 33 : else if (TREE_CODE (field) == RANGE_EXPR)
12901 : {
12902 0 : tree lo = TREE_OPERAND (field, 0);
12903 0 : tree hi = TREE_OPERAND (field, 1);
12904 0 : if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
12905 0 : goto unhandled;
12906 0 : if (integer_zerop (value))
12907 : break;
12908 0 : unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
12909 0 : for (l = tree_to_uhwi (lo); l <= m; ++l)
12910 0 : if (l >= off && l < off + len)
12911 0 : b[l - off] = tree_to_shwi (value);
12912 : }
12913 33 : else if (tree_fits_uhwi_p (field))
12914 : {
12915 33 : l = tree_to_uhwi (field);
12916 33 : if (integer_zerop (value))
12917 : break;
12918 30 : if (l >= off && l < off + len)
12919 30 : b[l - off] = tree_to_shwi (value);
12920 30 : l++;
12921 : }
12922 3 : b[len] = '\0';
12923 : }
12924 : else
12925 : {
12926 530 : data = maybe_constant_value (message_data, NULL_TREE, mce_true);
12927 530 : if (!reduced_constant_expression_p (data))
12928 96 : data = NULL_TREE;
12929 530 : if (len)
12930 : {
12931 453 : if (data)
12932 379 : msg = c_getstr (data);
12933 453 : if (msg == NULL)
12934 119 : buf = XNEWVEC (char, len);
12935 1452 : for (int i = 0; i < len; ++i)
12936 : {
12937 1029 : tree t = message_data;
12938 1029 : if (i)
12939 1152 : t = build2 (POINTER_PLUS_EXPR,
12940 576 : TREE_TYPE (message_data), message_data,
12941 576 : size_int (i));
12942 1029 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
12943 1029 : tree t2 = cxx_constant_value (t, NULL_TREE, complain);
12944 1029 : if (!tree_fits_shwi_p (t2))
12945 : {
12946 30 : error_at (location,
12947 : "constexpr string %<data()[%d]%> "
12948 : "must be a constant expression", i);
12949 30 : return false;
12950 : }
12951 999 : if (msg == NULL)
12952 362 : buf[i] = tree_to_shwi (t2);
12953 : /* If c_getstr worked, just verify the first and
12954 : last characters using constant evaluation. */
12955 637 : else if (len > 2 && i == 0)
12956 266 : i = len - 2;
12957 : }
12958 423 : if (msg == NULL)
12959 104 : msg = buf;
12960 : }
12961 77 : else if (!data)
12962 : {
12963 : /* We don't have any function to test whether some
12964 : expression is a core constant expression. So, instead
12965 : test whether (message.data (), 0) is a constant
12966 : expression. */
12967 22 : data = build2 (COMPOUND_EXPR, integer_type_node,
12968 : message_data, integer_zero_node);
12969 22 : tree t = cxx_constant_value (data, NULL_TREE, complain);
12970 22 : if (!integer_zerop (t))
12971 : {
12972 22 : error_at (location,
12973 : "constexpr string %<data()%> "
12974 : "must be a core constant expression");
12975 22 : return false;
12976 : }
12977 : }
12978 : }
12979 : }
12980 : else
12981 : {
12982 1529 : tree eltype = TREE_TYPE (TREE_TYPE (message));
12983 1529 : int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
12984 1529 : msg = TREE_STRING_POINTER (message);
12985 1529 : len = TREE_STRING_LENGTH (message) / sz - 1;
12986 : }
12987 2052 : translate:
12988 2052 : if ((message_sz && message_data) || ctx)
12989 : {
12990 : /* Convert the string from execution charset to SOURCE_CHARSET. */
12991 614 : cpp_string istr, ostr;
12992 614 : istr.len = len;
12993 614 : istr.text = (const unsigned char *) msg;
12994 614 : enum cpp_ttype type = CPP_STRING;
12995 614 : if (message_sz && message_data)
12996 : {
12997 523 : if (POINTER_TYPE_P (TREE_TYPE (message_data))
12998 523 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
12999 523 : == char8_type_node))
13000 : type = CPP_UTF8STRING;
13001 : }
13002 91 : else if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message)))
13003 91 : == char8_type_node)
13004 614 : type = CPP_UTF8STRING;
13005 614 : if (len == 0)
13006 : ;
13007 528 : else if (!cpp_translate_string (parse_in, &istr, &ostr, type,
13008 : true))
13009 : {
13010 0 : if (type == CPP_UTF8STRING)
13011 0 : error_at (location, "could not convert constexpr string from "
13012 : "UTF-8 encoding to source character "
13013 : "set");
13014 : else
13015 0 : error_at (location, "could not convert constexpr string from "
13016 : "ordinary literal encoding to source character "
13017 : "set");
13018 0 : return false;
13019 : }
13020 : else
13021 : {
13022 528 : if (buf)
13023 104 : XDELETEVEC (buf);
13024 528 : msg = buf = const_cast <char *> ((const char *) ostr.text);
13025 528 : len = ostr.len;
13026 : }
13027 : }
13028 :
13029 : return true;
13030 : }
13031 :
13032 : /* Build a STATIC_ASSERT for a static assertion with the condition
13033 : CONDITION and the message text MESSAGE. LOCATION is the location
13034 : of the static assertion in the source code. When MEMBER_P, this
13035 : static assertion is a member of a class. If SHOW_EXPR_P is true,
13036 : print the condition (because it was instantiation-dependent).
13037 : If CONSTEVAL_BLOCK_P is true, this static assertion represents
13038 : a consteval block. */
13039 :
13040 : void
13041 10765971 : finish_static_assert (tree condition, tree message, location_t location,
13042 : bool member_p, bool show_expr_p,
13043 : bool consteval_block_p/*=false*/)
13044 : {
13045 10765971 : tsubst_flags_t complain = tf_warning_or_error;
13046 :
13047 10765971 : if (condition == NULL_TREE
13048 10765971 : || condition == error_mark_node)
13049 4387551 : return;
13050 :
13051 10765807 : if (check_for_bare_parameter_packs (condition))
13052 : return;
13053 :
13054 10765804 : cexpr_str cstr(message);
13055 10765804 : if (!cstr.type_check (location))
13056 : return;
13057 :
13058 : /* Save the condition in case it was a concept check. */
13059 10765710 : tree orig_condition = condition;
13060 :
13061 10765710 : if (instantiation_dependent_expression_p (condition)
13062 10765710 : || instantiation_dependent_expression_p (message))
13063 : {
13064 : /* We're in a template; build a STATIC_ASSERT and put it in
13065 : the right place. */
13066 4387051 : defer:
13067 4387051 : tree assertion = make_node (STATIC_ASSERT);
13068 4387051 : STATIC_ASSERT_CONDITION (assertion) = orig_condition;
13069 4387051 : STATIC_ASSERT_MESSAGE (assertion) = cstr.message;
13070 4387051 : STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
13071 4387051 : CONSTEVAL_BLOCK_P (assertion) = consteval_block_p;
13072 :
13073 4387051 : if (member_p)
13074 2276683 : maybe_add_class_template_decl_list (current_class_type,
13075 : assertion,
13076 : /*friend_p=*/0);
13077 : else
13078 2110368 : add_stmt (assertion);
13079 :
13080 4387051 : return;
13081 : }
13082 :
13083 : /* Evaluate the consteval { }. This must be done only once. */
13084 6381940 : if (consteval_block_p)
13085 : {
13086 214 : cxx_constant_value (condition);
13087 214 : return;
13088 : }
13089 :
13090 : /* Fold the expression and convert it to a boolean value. */
13091 6381726 : condition = contextual_conv_bool (condition, complain);
13092 6381726 : condition = fold_non_dependent_expr (condition, complain,
13093 : /*manifestly_const_eval=*/true);
13094 :
13095 6381725 : if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
13096 : /* Do nothing; the condition is satisfied. */
13097 : ;
13098 : else
13099 : {
13100 5371 : iloc_sentinel ils (location);
13101 :
13102 5371 : if (integer_zerop (condition))
13103 : {
13104 : /* CWG2518: static_assert failure in a template is not IFNDR. */
13105 4879 : if (processing_template_decl)
13106 3281 : goto defer;
13107 :
13108 1598 : int len;
13109 1598 : const char *msg = NULL;
13110 1598 : if (!cstr.extract (location, msg, len))
13111 25 : return;
13112 :
13113 : /* See if we can find which clause was failing (for logical AND). */
13114 1573 : tree bad = find_failing_clause (NULL, orig_condition);
13115 : /* If not, or its location is unusable, fall back to the previous
13116 : location. */
13117 1573 : location_t cloc = cp_expr_loc_or_loc (bad, location);
13118 :
13119 1573 : auto_diagnostic_group d;
13120 :
13121 : /* Report the error. */
13122 1573 : if (len == 0)
13123 977 : error_at (cloc, "static assertion failed");
13124 : else
13125 596 : error_at (cloc, "static assertion failed: %.*s", len, msg);
13126 :
13127 1573 : diagnose_failing_condition (bad, cloc, show_expr_p);
13128 :
13129 : /* Suppress -Wreturn-type for functions with failed static_asserts.
13130 : Otherwise templates like:
13131 : if constexpr (whatever)
13132 : return something (args);
13133 : else
13134 : static_assert (false, "explanation");
13135 : get a useless extra -Wreturn-type warning. */
13136 1573 : if (current_function_decl)
13137 576 : suppress_warning (current_function_decl, OPT_Wreturn_type);
13138 1573 : }
13139 492 : else if (condition && condition != error_mark_node)
13140 : {
13141 489 : error ("non-constant condition for static assertion");
13142 489 : if (require_rvalue_constant_expression (condition))
13143 433 : cxx_constant_value (condition);
13144 : }
13145 5371 : }
13146 10765803 : }
13147 :
13148 : /* Implements the C++0x decltype keyword. Returns the type of EXPR,
13149 : suitable for use as a type-specifier.
13150 :
13151 : ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
13152 : id-expression or a class member access, FALSE when it was parsed as
13153 : a full expression. */
13154 :
13155 : tree
13156 60620111 : finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
13157 : tsubst_flags_t complain)
13158 : {
13159 60620111 : tree type = NULL_TREE;
13160 :
13161 60620111 : if (!expr || error_operand_p (expr))
13162 208398 : return error_mark_node;
13163 :
13164 60411713 : if (TYPE_P (expr)
13165 60411713 : || TREE_CODE (expr) == TYPE_DECL
13166 120823407 : || (TREE_CODE (expr) == BIT_NOT_EXPR
13167 13005 : && TYPE_P (TREE_OPERAND (expr, 0))))
13168 : {
13169 28 : if (complain & tf_error)
13170 28 : error ("argument to %<decltype%> must be an expression");
13171 28 : return error_mark_node;
13172 : }
13173 :
13174 : /* decltype is an unevaluated context. */
13175 60411685 : cp_unevaluated u;
13176 :
13177 60411685 : processing_template_decl_sentinel ptds (/*reset=*/false);
13178 :
13179 : /* Depending on the resolution of DR 1172, we may later need to distinguish
13180 : instantiation-dependent but not type-dependent expressions so that, say,
13181 : A<decltype(sizeof(T))>::U doesn't require 'typename'. */
13182 60411685 : if (instantiation_dependent_uneval_expression_p (expr))
13183 : {
13184 6804706 : dependent:
13185 6805090 : type = cxx_make_type (DECLTYPE_TYPE);
13186 6805090 : DECLTYPE_TYPE_EXPR (type) = expr;
13187 13610180 : DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
13188 6805090 : = id_expression_or_member_access_p;
13189 6805090 : SET_TYPE_STRUCTURAL_EQUALITY (type);
13190 :
13191 6805090 : return type;
13192 : }
13193 53606979 : else if (processing_template_decl)
13194 : {
13195 4628 : expr = instantiate_non_dependent_expr (expr, complain|tf_decltype);
13196 4628 : if (expr == error_mark_node)
13197 : return error_mark_node;
13198 : /* Keep processing_template_decl cleared for the rest of the function
13199 : (for sake of the call to lvalue_kind below, which handles templated
13200 : and non-templated COND_EXPR differently). */
13201 4591 : processing_template_decl = 0;
13202 : }
13203 :
13204 : /* The type denoted by decltype(e) is defined as follows: */
13205 :
13206 53606942 : expr = resolve_nondeduced_context (expr, complain);
13207 53606942 : if (!mark_single_function (expr, complain))
13208 0 : return error_mark_node;
13209 :
13210 53606942 : if (invalid_nonstatic_memfn_p (input_location, expr, complain))
13211 18 : return error_mark_node;
13212 :
13213 53606924 : if (type_unknown_p (expr))
13214 : {
13215 18 : if (complain & tf_error)
13216 6 : error ("%<decltype%> cannot resolve address of overloaded function");
13217 18 : return error_mark_node;
13218 : }
13219 :
13220 53606906 : if (id_expression_or_member_access_p)
13221 : {
13222 : /* If e is an id-expression or a class member access (5.2.5
13223 : [expr.ref]), decltype(e) is defined as the type of the entity
13224 : named by e. If there is no such entity, or e names a set of
13225 : overloaded functions, the program is ill-formed. */
13226 2814907 : if (identifier_p (expr))
13227 0 : expr = lookup_name (expr);
13228 :
13229 : /* If e is a constified expression inside a contract assertion,
13230 : strip the const wrapper. Per P2900R14, "For a function f with the
13231 : return type T , the result name is an lvalue of type const T , decltype(r)
13232 : is T , and decltype((r)) is const T&." */
13233 2814907 : expr = strip_contract_const_wrapper (expr);
13234 :
13235 2814907 : if (INDIRECT_REF_P (expr)
13236 2814907 : || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
13237 : /* This can happen when the expression is, e.g., "a.b". Just
13238 : look at the underlying operand. */
13239 2593591 : expr = TREE_OPERAND (expr, 0);
13240 :
13241 2814907 : if (TREE_CODE (expr) == OFFSET_REF
13242 2814907 : || TREE_CODE (expr) == MEMBER_REF
13243 2814907 : || TREE_CODE (expr) == SCOPE_REF)
13244 : /* We're only interested in the field itself. If it is a
13245 : BASELINK, we will need to see through it in the next
13246 : step. */
13247 0 : expr = TREE_OPERAND (expr, 1);
13248 :
13249 2814907 : if (BASELINK_P (expr))
13250 : /* See through BASELINK nodes to the underlying function. */
13251 5 : expr = BASELINK_FUNCTIONS (expr);
13252 :
13253 : /* decltype of a decomposition name drops references in the tuple case
13254 : (unlike decltype of a normal variable) and keeps cv-qualifiers from
13255 : the containing object in the other cases (unlike decltype of a member
13256 : access expression). */
13257 2814907 : if (DECL_DECOMPOSITION_P (expr))
13258 : {
13259 1412 : if (ptds.saved)
13260 : {
13261 275 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr)
13262 : || (DECL_CONTEXT (expr)
13263 : != current_function_decl));
13264 : /* DECL_HAS_VALUE_EXPR_P is always set if
13265 : processing_template_decl at least for structured bindings
13266 : within the template. If lookup_decomp_type
13267 : returns non-NULL, it is the tuple case. */
13268 275 : if (tree ret = lookup_decomp_type (expr))
13269 : return ret;
13270 191 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
13271 : }
13272 1328 : if (DECL_HAS_VALUE_EXPR_P (expr))
13273 : /* Expr is an array or struct subobject proxy, handle
13274 : bit-fields properly. */
13275 1016 : return unlowered_expr_type (expr);
13276 : else
13277 : /* Expr is a reference variable for the tuple case. */
13278 312 : return lookup_decomp_type (expr);
13279 : }
13280 :
13281 2813495 : switch (TREE_CODE (expr))
13282 : {
13283 222 : case FIELD_DECL:
13284 222 : if (DECL_BIT_FIELD_TYPE (expr))
13285 : {
13286 : type = DECL_BIT_FIELD_TYPE (expr);
13287 : break;
13288 : }
13289 : /* Fall through for fields that aren't bitfields. */
13290 197066 : gcc_fallthrough ();
13291 :
13292 197066 : case VAR_DECL:
13293 197066 : if (is_capture_proxy (expr))
13294 : {
13295 85 : if (is_normal_capture_proxy (expr))
13296 : {
13297 21 : expr = DECL_CAPTURED_VARIABLE (expr);
13298 21 : type = TREE_TYPE (expr);
13299 : }
13300 : else
13301 : {
13302 64 : expr = DECL_VALUE_EXPR (expr);
13303 64 : gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
13304 64 : expr = TREE_OPERAND (expr, 1);
13305 64 : type = TREE_TYPE (expr);
13306 : }
13307 : break;
13308 : }
13309 : /* Fall through for variables that aren't capture proxies. */
13310 2809287 : gcc_fallthrough ();
13311 :
13312 2809287 : case FUNCTION_DECL:
13313 2809287 : case CONST_DECL:
13314 2809287 : case PARM_DECL:
13315 2809287 : case RESULT_DECL:
13316 2809287 : case TEMPLATE_PARM_INDEX:
13317 2809287 : expr = mark_type_use (expr);
13318 2809287 : type = TREE_TYPE (expr);
13319 2809287 : if (VAR_P (expr) && DECL_NTTP_OBJECT_P (expr))
13320 : {
13321 : /* decltype of an NTTP object is the type of the template
13322 : parameter, which is the object type modulo cv-quals. */
13323 1238 : int quals = cp_type_quals (type);
13324 1238 : gcc_checking_assert (quals & TYPE_QUAL_CONST);
13325 1238 : type = cv_unqualified (type);
13326 : }
13327 : break;
13328 :
13329 0 : case ERROR_MARK:
13330 0 : type = error_mark_node;
13331 0 : break;
13332 :
13333 3069 : case COMPONENT_REF:
13334 3069 : case COMPOUND_EXPR:
13335 3069 : mark_type_use (expr);
13336 3069 : type = is_bitfield_expr_with_lowered_type (expr);
13337 3069 : if (!type)
13338 3034 : type = TREE_TYPE (TREE_OPERAND (expr, 1));
13339 : break;
13340 :
13341 0 : case BIT_FIELD_REF:
13342 0 : gcc_unreachable ();
13343 :
13344 412 : case INTEGER_CST:
13345 412 : case PTRMEM_CST:
13346 : /* We can get here when the id-expression refers to an
13347 : enumerator or non-type template parameter. */
13348 412 : type = TREE_TYPE (expr);
13349 412 : break;
13350 :
13351 642 : default:
13352 : /* Handle instantiated template non-type arguments. */
13353 642 : type = TREE_TYPE (expr);
13354 642 : break;
13355 : }
13356 : }
13357 : else
13358 : {
13359 50791999 : tree decl = STRIP_REFERENCE_REF (expr);
13360 50791999 : tree lam = current_lambda_expr ();
13361 50791999 : if (lam && outer_automatic_var_p (decl))
13362 : {
13363 : /* [expr.prim.id.unqual]/3: If naming the entity from outside of an
13364 : unevaluated operand within S would refer to an entity captured by
13365 : copy in some intervening lambda-expression, then let E be the
13366 : innermost such lambda-expression.
13367 :
13368 : If there is such a lambda-expression and if P is in E's function
13369 : parameter scope but not its parameter-declaration-clause, then the
13370 : type of the expression is the type of a class member access
13371 : expression naming the non-static data member that would be declared
13372 : for such a capture in the object parameter of the function call
13373 : operator of E." */
13374 : /* FIXME: This transformation needs to happen for all uses of an outer
13375 : local variable inside decltype, not just decltype((x)) (PR83167).
13376 : And we don't handle nested lambdas properly, where we need to
13377 : consider the outer lambdas as well (PR112926). */
13378 940 : tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK,
13379 : LOOK_want::HIDDEN_LAMBDA);
13380 :
13381 940 : if (cap && is_capture_proxy (cap))
13382 319 : type = TREE_TYPE (cap);
13383 621 : else if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_COPY)
13384 : {
13385 500 : type = TREE_TYPE (decl);
13386 500 : if (TYPE_REF_P (type)
13387 500 : && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
13388 25 : type = TREE_TYPE (type);
13389 : }
13390 :
13391 819 : if (type && !TYPE_REF_P (type))
13392 : {
13393 761 : int quals;
13394 761 : if (current_function_decl
13395 1428 : && LAMBDA_FUNCTION_P (current_function_decl)
13396 1428 : && DECL_XOBJ_MEMBER_FUNCTION_P (current_function_decl))
13397 : {
13398 600 : tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl));
13399 600 : if (WILDCARD_TYPE_P (non_reference (obtype)))
13400 : /* We don't know what the eventual obtype quals will be. */
13401 384 : goto dependent;
13402 432 : auto direct_type = [](tree t){
13403 216 : if (INDIRECT_TYPE_P (t))
13404 108 : return TREE_TYPE (t);
13405 : return t;
13406 : };
13407 432 : quals = (cp_type_quals (type)
13408 216 : | cp_type_quals (direct_type (obtype)));
13409 : }
13410 : else
13411 : /* We are in the parameter clause, trailing return type, or
13412 : the requires clause and have no relevant c_f_decl yet. */
13413 251 : quals = (LAMBDA_EXPR_CONST_QUAL_P (lam)
13414 161 : ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
13415 377 : type = cp_build_qualified_type (type, quals);
13416 377 : type = build_reference_type (type);
13417 : }
13418 : }
13419 50791059 : else if (error_operand_p (expr))
13420 0 : type = error_mark_node;
13421 50791059 : else if (expr == current_class_ptr)
13422 : /* If the expression is just "this", we want the
13423 : cv-unqualified pointer for the "this" type. */
13424 0 : type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
13425 :
13426 377 : if (!type)
13427 : {
13428 : /* Otherwise, where T is the type of e, if e is an lvalue,
13429 : decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
13430 50791180 : cp_lvalue_kind clk = lvalue_kind (expr);
13431 50791180 : type = unlowered_expr_type (expr);
13432 50791180 : gcc_assert (!TYPE_REF_P (type));
13433 :
13434 : /* For vector types, pick a non-opaque variant. */
13435 50791180 : if (VECTOR_TYPE_P (type))
13436 2079 : type = strip_typedefs (type);
13437 :
13438 50791180 : if (clk != clk_none && !(clk & clk_class))
13439 10243476 : type = cp_build_reference_type (type, (clk & clk_rvalueref));
13440 : }
13441 : }
13442 :
13443 : return type;
13444 60411685 : }
13445 :
13446 : /* Called from trait_expr_value to evaluate either __has_nothrow_assign or
13447 : __has_nothrow_copy, depending on assign_p. Returns true iff all
13448 : the copy {ctor,assign} fns are nothrow. */
13449 :
13450 : static bool
13451 279 : classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
13452 : {
13453 279 : tree fns = NULL_TREE;
13454 :
13455 279 : if (assign_p || TYPE_HAS_COPY_CTOR (type))
13456 276 : fns = get_class_binding (type, assign_p ? assign_op_identifier
13457 : : ctor_identifier);
13458 :
13459 279 : bool saw_copy = false;
13460 696 : for (ovl_iterator iter (fns); iter; ++iter)
13461 : {
13462 441 : tree fn = *iter;
13463 :
13464 441 : if (copy_fn_p (fn) > 0)
13465 : {
13466 423 : saw_copy = true;
13467 423 : if (!maybe_instantiate_noexcept (fn)
13468 423 : || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
13469 192 : return false;
13470 : }
13471 : }
13472 :
13473 87 : return saw_copy;
13474 : }
13475 :
13476 : /* Return true if BASE is a pointer-interconvertible base of DERIVED. */
13477 :
13478 : bool
13479 157 : pointer_interconvertible_base_of_p (tree base, tree derived,
13480 : bool explain/*=false*/)
13481 : {
13482 157 : if (base == error_mark_node || derived == error_mark_node)
13483 : return false;
13484 :
13485 157 : base = TYPE_MAIN_VARIANT (base);
13486 157 : derived = TYPE_MAIN_VARIANT (derived);
13487 157 : if (!NON_UNION_CLASS_TYPE_P (base))
13488 : {
13489 15 : if (explain)
13490 3 : inform (location_of (base),
13491 : "%qT is not a non-union class type", base);
13492 15 : return false;
13493 : }
13494 142 : if (!NON_UNION_CLASS_TYPE_P (derived))
13495 : {
13496 6 : if (explain)
13497 3 : inform (location_of (derived),
13498 : "%qT is not a non-union class type", derived);
13499 6 : return false;
13500 : }
13501 :
13502 136 : if (same_type_p (base, derived))
13503 : return true;
13504 :
13505 106 : if (!std_layout_type_p (derived))
13506 : {
13507 17 : if (explain)
13508 6 : inform (location_of (derived),
13509 : "%qT is not a standard-layout type", derived);
13510 17 : return false;
13511 : }
13512 :
13513 89 : if (!uniquely_derived_from_p (base, derived))
13514 : {
13515 16 : if (explain)
13516 : {
13517 : /* An ambiguous base should already be impossible due to
13518 : the std_layout_type_p check. */
13519 3 : gcc_checking_assert (!DERIVED_FROM_P (base, derived));
13520 3 : inform (location_of (derived),
13521 : "%qT is not a base of %qT", base, derived);
13522 : }
13523 16 : return false;
13524 : }
13525 :
13526 : return true;
13527 : }
13528 :
13529 : /* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
13530 : return true if MEMBERTYPE is the type of the first non-static data member
13531 : of TYPE or for unions of any members. */
13532 : static bool
13533 637 : first_nonstatic_data_member_p (tree type, tree membertype)
13534 : {
13535 1297 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13536 : {
13537 1222 : if (TREE_CODE (field) != FIELD_DECL)
13538 135 : continue;
13539 1087 : if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
13540 60 : continue;
13541 1027 : if (DECL_FIELD_IS_BASE (field))
13542 45 : return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
13543 982 : if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13544 : {
13545 216 : if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
13546 138 : || std_layout_type_p (TREE_TYPE (field)))
13547 294 : && first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
13548 : return true;
13549 : }
13550 766 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13551 : membertype))
13552 : return true;
13553 537 : if (TREE_CODE (type) != UNION_TYPE)
13554 : return false;
13555 : }
13556 : return false;
13557 : }
13558 :
13559 : /* Fold __builtin_is_pointer_interconvertible_with_class call. */
13560 :
13561 : tree
13562 536 : fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
13563 : tree *args)
13564 : {
13565 : /* Unless users call the builtin directly, the following 3 checks should be
13566 : ensured from std::is_pointer_interconvertible_with_class function
13567 : template. */
13568 536 : if (nargs != 1)
13569 : {
13570 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13571 : "needs a single argument");
13572 6 : return boolean_false_node;
13573 : }
13574 530 : tree arg = args[0];
13575 530 : if (error_operand_p (arg))
13576 0 : return boolean_false_node;
13577 530 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
13578 : {
13579 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13580 : "argument is not pointer to member");
13581 6 : return boolean_false_node;
13582 : }
13583 :
13584 524 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
13585 18 : return boolean_false_node;
13586 :
13587 506 : tree membertype = TREE_TYPE (TREE_TYPE (arg));
13588 506 : tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
13589 506 : if (!complete_type_or_else (basetype, NULL_TREE))
13590 3 : return boolean_false_node;
13591 :
13592 503 : if (TREE_CODE (basetype) != UNION_TYPE
13593 503 : && !std_layout_type_p (basetype))
13594 22 : return boolean_false_node;
13595 :
13596 481 : if (!first_nonstatic_data_member_p (basetype, membertype))
13597 132 : return boolean_false_node;
13598 :
13599 349 : if (TREE_CODE (arg) == PTRMEM_CST)
13600 68 : arg = cplus_expand_constant (arg);
13601 :
13602 349 : if (integer_nonzerop (arg))
13603 10 : return boolean_false_node;
13604 339 : if (integer_zerop (arg))
13605 71 : return boolean_true_node;
13606 :
13607 268 : return fold_build2 (EQ_EXPR, boolean_type_node, arg,
13608 : build_zero_cst (TREE_TYPE (arg)));
13609 : }
13610 :
13611 : /* Helper function for is_corresponding_member_aggr. Return true if
13612 : MEMBERTYPE pointer-to-data-member ARG can be found in anonymous
13613 : union or structure BASETYPE. */
13614 :
13615 : static bool
13616 90 : is_corresponding_member_union (tree basetype, tree membertype, tree arg)
13617 : {
13618 222 : for (tree field = TYPE_FIELDS (basetype); field; field = DECL_CHAIN (field))
13619 192 : if (TREE_CODE (field) != FIELD_DECL || DECL_BIT_FIELD_TYPE (field))
13620 36 : continue;
13621 156 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13622 : membertype))
13623 : {
13624 48 : if (TREE_CODE (arg) != INTEGER_CST
13625 48 : || tree_int_cst_equal (arg, byte_position (field)))
13626 48 : return true;
13627 : }
13628 108 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13629 : {
13630 18 : tree narg = arg;
13631 18 : if (TREE_CODE (basetype) != UNION_TYPE
13632 0 : && TREE_CODE (narg) == INTEGER_CST)
13633 0 : narg = size_binop (MINUS_EXPR, arg, byte_position (field));
13634 18 : if (is_corresponding_member_union (TREE_TYPE (field),
13635 : membertype, narg))
13636 : return true;
13637 : }
13638 : return false;
13639 : }
13640 :
13641 : /* Helper function for fold_builtin_is_corresponding_member call.
13642 : Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and
13643 : MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members,
13644 : boolean_true_node if they are corresponding members, or for
13645 : non-constant ARG2 the highest member offset for corresponding
13646 : members. */
13647 :
13648 : static tree
13649 550 : is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
13650 : tree arg1, tree basetype2, tree membertype2,
13651 : tree arg2)
13652 : {
13653 550 : tree field1 = TYPE_FIELDS (basetype1);
13654 550 : tree field2 = TYPE_FIELDS (basetype2);
13655 550 : tree ret = boolean_false_node;
13656 2376 : while (1)
13657 : {
13658 1463 : bool r = next_common_initial_sequence (field1, field2);
13659 1463 : if (field1 == NULL_TREE || field2 == NULL_TREE)
13660 : break;
13661 1331 : if (r
13662 1038 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field1),
13663 : membertype1)
13664 1841 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field2),
13665 : membertype2))
13666 : {
13667 504 : tree pos = byte_position (field1);
13668 504 : if (TREE_CODE (arg1) == INTEGER_CST
13669 504 : && tree_int_cst_equal (arg1, pos))
13670 : {
13671 92 : if (TREE_CODE (arg2) == INTEGER_CST)
13672 92 : return boolean_true_node;
13673 : return pos;
13674 : }
13675 412 : else if (TREE_CODE (arg1) != INTEGER_CST)
13676 1188 : ret = pos;
13677 : }
13678 1654 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field1))
13679 944 : && ANON_AGGR_TYPE_P (TREE_TYPE (field2)))
13680 : {
13681 117 : if ((!lookup_attribute ("no_unique_address",
13682 117 : DECL_ATTRIBUTES (field1)))
13683 117 : != !lookup_attribute ("no_unique_address",
13684 117 : DECL_ATTRIBUTES (field2)))
13685 : break;
13686 117 : if (!tree_int_cst_equal (bit_position (field1),
13687 117 : bit_position (field2)))
13688 : break;
13689 99 : bool overlap = true;
13690 99 : tree pos = byte_position (field1);
13691 99 : if (TREE_CODE (arg1) == INTEGER_CST)
13692 : {
13693 27 : tree off1 = fold_convert (sizetype, arg1);
13694 27 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (field1));
13695 27 : if (tree_int_cst_lt (off1, pos)
13696 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz1), off1))
13697 : overlap = false;
13698 : }
13699 99 : if (TREE_CODE (arg2) == INTEGER_CST)
13700 : {
13701 27 : tree off2 = fold_convert (sizetype, arg2);
13702 27 : tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (field2));
13703 27 : if (tree_int_cst_lt (off2, pos)
13704 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz2), off2))
13705 : overlap = false;
13706 : }
13707 87 : if (overlap
13708 87 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field1))
13709 126 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field2)))
13710 : {
13711 39 : tree narg1 = arg1;
13712 39 : if (TREE_CODE (arg1) == INTEGER_CST)
13713 9 : narg1 = size_binop (MINUS_EXPR,
13714 : fold_convert (sizetype, arg1), pos);
13715 39 : tree narg2 = arg2;
13716 39 : if (TREE_CODE (arg2) == INTEGER_CST)
13717 9 : narg2 = size_binop (MINUS_EXPR,
13718 : fold_convert (sizetype, arg2), pos);
13719 39 : tree t1 = TREE_TYPE (field1);
13720 39 : tree t2 = TREE_TYPE (field2);
13721 39 : tree nret = is_corresponding_member_aggr (loc, t1, membertype1,
13722 : narg1, t2, membertype2,
13723 : narg2);
13724 39 : if (nret != boolean_false_node)
13725 : {
13726 39 : if (nret == boolean_true_node)
13727 : return nret;
13728 30 : if (TREE_CODE (arg1) == INTEGER_CST)
13729 0 : return size_binop (PLUS_EXPR, nret, pos);
13730 30 : ret = size_binop (PLUS_EXPR, nret, pos);
13731 : }
13732 : }
13733 60 : else if (overlap
13734 48 : && TREE_CODE (TREE_TYPE (field1)) == UNION_TYPE
13735 108 : && TREE_CODE (TREE_TYPE (field2)) == UNION_TYPE)
13736 : {
13737 48 : tree narg1 = arg1;
13738 48 : if (TREE_CODE (arg1) == INTEGER_CST)
13739 6 : narg1 = size_binop (MINUS_EXPR,
13740 : fold_convert (sizetype, arg1), pos);
13741 48 : tree narg2 = arg2;
13742 48 : if (TREE_CODE (arg2) == INTEGER_CST)
13743 6 : narg2 = size_binop (MINUS_EXPR,
13744 : fold_convert (sizetype, arg2), pos);
13745 48 : if (is_corresponding_member_union (TREE_TYPE (field1),
13746 : membertype1, narg1)
13747 48 : && is_corresponding_member_union (TREE_TYPE (field2),
13748 : membertype2, narg2))
13749 : {
13750 24 : sorry_at (loc, "%<__builtin_is_corresponding_member%> "
13751 : "not well defined for anonymous unions");
13752 24 : return boolean_false_node;
13753 : }
13754 : }
13755 : }
13756 1188 : if (!r)
13757 : break;
13758 913 : field1 = DECL_CHAIN (field1);
13759 913 : field2 = DECL_CHAIN (field2);
13760 913 : }
13761 : return ret;
13762 : }
13763 :
13764 : /* Fold __builtin_is_corresponding_member call. */
13765 :
13766 : tree
13767 699 : fold_builtin_is_corresponding_member (location_t loc, int nargs,
13768 : tree *args)
13769 : {
13770 : /* Unless users call the builtin directly, the following 3 checks should be
13771 : ensured from std::is_corresponding_member function template. */
13772 699 : if (nargs != 2)
13773 : {
13774 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13775 : "needs two arguments");
13776 9 : return boolean_false_node;
13777 : }
13778 690 : tree arg1 = args[0];
13779 690 : tree arg2 = args[1];
13780 690 : if (error_operand_p (arg1) || error_operand_p (arg2))
13781 0 : return boolean_false_node;
13782 711 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg1))
13783 705 : || !TYPE_PTRMEM_P (TREE_TYPE (arg2)))
13784 : {
13785 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13786 : "argument is not pointer to member");
13787 9 : return boolean_false_node;
13788 : }
13789 :
13790 681 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg1))
13791 681 : || !TYPE_PTRDATAMEM_P (TREE_TYPE (arg2)))
13792 15 : return boolean_false_node;
13793 :
13794 666 : tree membertype1 = TREE_TYPE (TREE_TYPE (arg1));
13795 666 : tree basetype1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg1));
13796 666 : if (!complete_type_or_else (basetype1, NULL_TREE))
13797 12 : return boolean_false_node;
13798 :
13799 654 : tree membertype2 = TREE_TYPE (TREE_TYPE (arg2));
13800 654 : tree basetype2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg2));
13801 654 : if (!complete_type_or_else (basetype2, NULL_TREE))
13802 12 : return boolean_false_node;
13803 :
13804 627 : if (!NON_UNION_CLASS_TYPE_P (basetype1)
13805 627 : || !NON_UNION_CLASS_TYPE_P (basetype2)
13806 627 : || !std_layout_type_p (basetype1)
13807 1233 : || !std_layout_type_p (basetype2))
13808 51 : return boolean_false_node;
13809 :
13810 : /* If the member types aren't layout compatible, then they
13811 : can't be corresponding members. */
13812 591 : if (!layout_compatible_type_p (membertype1, membertype2))
13813 18 : return boolean_false_node;
13814 :
13815 573 : if (TREE_CODE (arg1) == PTRMEM_CST)
13816 176 : arg1 = cplus_expand_constant (arg1);
13817 573 : if (TREE_CODE (arg2) == PTRMEM_CST)
13818 182 : arg2 = cplus_expand_constant (arg2);
13819 :
13820 573 : if (null_member_pointer_value_p (arg1)
13821 573 : || null_member_pointer_value_p (arg2))
13822 9 : return boolean_false_node;
13823 :
13824 564 : if (TREE_CODE (arg1) == INTEGER_CST
13825 182 : && TREE_CODE (arg2) == INTEGER_CST
13826 746 : && !tree_int_cst_equal (arg1, arg2))
13827 53 : return boolean_false_node;
13828 :
13829 511 : if (TREE_CODE (arg2) == INTEGER_CST
13830 129 : && TREE_CODE (arg1) != INTEGER_CST)
13831 : {
13832 : std::swap (arg1, arg2);
13833 : std::swap (membertype1, membertype2);
13834 : std::swap (basetype1, basetype2);
13835 : }
13836 :
13837 511 : tree ret = is_corresponding_member_aggr (loc, basetype1, membertype1, arg1,
13838 : basetype2, membertype2, arg2);
13839 511 : if (TREE_TYPE (ret) == boolean_type_node)
13840 : return ret;
13841 : /* If both arg1 and arg2 are INTEGER_CSTs, is_corresponding_member_aggr
13842 : already returns boolean_{true,false}_node whether those particular
13843 : members are corresponding members or not. Otherwise, if only
13844 : one of them is INTEGER_CST (canonicalized to first being INTEGER_CST
13845 : above), it returns boolean_false_node if it is certainly not a
13846 : corresponding member and otherwise we need to do a runtime check that
13847 : those two OFFSET_TYPE offsets are equal.
13848 : If neither of the operands is INTEGER_CST, is_corresponding_member_aggr
13849 : returns the largest offset at which the members would be corresponding
13850 : members, so perform arg1 <= ret && arg1 == arg2 runtime check. */
13851 304 : gcc_assert (TREE_CODE (arg2) != INTEGER_CST);
13852 304 : if (TREE_CODE (arg1) == INTEGER_CST)
13853 0 : return fold_build2 (EQ_EXPR, boolean_type_node, arg1,
13854 : fold_convert (TREE_TYPE (arg1), arg2));
13855 304 : ret = fold_build2 (LE_EXPR, boolean_type_node,
13856 : fold_convert (pointer_sized_int_node, arg1),
13857 : fold_convert (pointer_sized_int_node, ret));
13858 304 : return fold_build2 (TRUTH_AND_EXPR, boolean_type_node, ret,
13859 : fold_build2 (EQ_EXPR, boolean_type_node, arg1,
13860 : fold_convert (TREE_TYPE (arg1), arg2)));
13861 : }
13862 :
13863 : /* Fold __builtin_is_string_literal call. */
13864 :
13865 : tree
13866 1778 : fold_builtin_is_string_literal (location_t loc, int nargs, tree *args)
13867 : {
13868 : /* Unless users call the builtin directly, the following 3 checks should be
13869 : ensured from std::is_string_literal overloads. */
13870 1778 : if (nargs != 1)
13871 : {
13872 0 : error_at (loc, "%<__builtin_is_string_literal%> needs a single "
13873 : "argument");
13874 0 : return boolean_false_node;
13875 : }
13876 1778 : tree arg = args[0];
13877 1778 : if (error_operand_p (arg))
13878 0 : return boolean_false_node;
13879 1778 : if (!TYPE_PTR_P (TREE_TYPE (arg))
13880 1778 : || !TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg)))
13881 3556 : || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (arg))))
13882 : {
13883 0 : arg_invalid:
13884 0 : error_at (loc, "%<__builtin_is_string_literal%> "
13885 : "argument is not %<const char*%>, %<const wchar_t*%>, "
13886 : "%<const char8_t*%>, %<const char16_t*%> or "
13887 : "%<const char32_t*%>");
13888 0 : return boolean_false_node;
13889 : }
13890 1778 : tree chart = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg)));
13891 1778 : if (chart != char_type_node
13892 1420 : && chart != wchar_type_node
13893 1065 : && chart != char8_type_node
13894 710 : && chart != char16_type_node
13895 355 : && chart != char32_type_node)
13896 0 : goto arg_invalid;
13897 :
13898 1778 : STRIP_NOPS (arg);
13899 3562 : while (TREE_CODE (arg) == POINTER_PLUS_EXPR)
13900 : {
13901 6 : arg = TREE_OPERAND (arg, 0);
13902 6 : STRIP_NOPS (arg);
13903 : }
13904 1778 : if (TREE_CODE (arg) != ADDR_EXPR)
13905 1750 : return boolean_false_node;
13906 28 : arg = TREE_OPERAND (arg, 0);
13907 28 : if (TREE_CODE (arg) == ARRAY_REF)
13908 12 : arg = TREE_OPERAND (arg, 0);
13909 28 : if (TREE_CODE (arg) != STRING_CST)
13910 8 : return boolean_false_node;
13911 20 : return boolean_true_node;
13912 : }
13913 :
13914 : /* [basic.types] 8. True iff TYPE is an object type. */
13915 :
13916 : static bool
13917 3314362 : object_type_p (const_tree type)
13918 : {
13919 3314362 : return (TREE_CODE (type) != FUNCTION_TYPE
13920 0 : && !TYPE_REF_P (type)
13921 3314362 : && !VOID_TYPE_P (type));
13922 : }
13923 :
13924 : /* [defns.referenceable] True iff TYPE is a referenceable type. */
13925 :
13926 : static bool
13927 4042403 : referenceable_type_p (const_tree type)
13928 : {
13929 4042403 : return (TYPE_REF_P (type)
13930 4042797 : || object_type_p (type)
13931 4042797 : || (FUNC_OR_METHOD_TYPE_P (type)
13932 332 : && type_memfn_quals (type) == TYPE_UNQUALIFIED
13933 272 : && type_memfn_rqual (type) == REF_QUAL_NONE));
13934 : }
13935 :
13936 : /* Actually evaluates the trait. */
13937 :
13938 : static bool
13939 21802117 : trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
13940 : {
13941 21802117 : enum tree_code type_code1;
13942 21802117 : tree t;
13943 :
13944 21802117 : type_code1 = TREE_CODE (type1);
13945 :
13946 21802117 : switch (kind)
13947 : {
13948 317 : case CPTK_HAS_NOTHROW_ASSIGN:
13949 317 : type1 = strip_array_types (type1);
13950 601 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
13951 601 : && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
13952 173 : || (CLASS_TYPE_P (type1)
13953 129 : && classtype_has_nothrow_assign_or_copy_p (type1,
13954 : true))));
13955 :
13956 215 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
13957 215 : type1 = strip_array_types (type1);
13958 215 : return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
13959 215 : || (CLASS_TYPE_P (type1)
13960 93 : && (t = locate_ctor (type1))
13961 60 : && maybe_instantiate_noexcept (t)
13962 58 : && TYPE_NOTHROW_P (TREE_TYPE (t))));
13963 :
13964 305 : case CPTK_HAS_NOTHROW_COPY:
13965 305 : type1 = strip_array_types (type1);
13966 305 : return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
13967 305 : || (CLASS_TYPE_P (type1)
13968 150 : && classtype_has_nothrow_assign_or_copy_p (type1, false)));
13969 :
13970 517 : case CPTK_HAS_TRIVIAL_ASSIGN:
13971 : /* ??? The standard seems to be missing the "or array of such a class
13972 : type" wording for this trait. */
13973 517 : type1 = strip_array_types (type1);
13974 1016 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
13975 1001 : && (trivial_type_p (type1)
13976 307 : || (CLASS_TYPE_P (type1)
13977 222 : && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
13978 :
13979 505 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
13980 505 : type1 = strip_array_types (type1);
13981 505 : return (trivial_type_p (type1)
13982 505 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
13983 :
13984 526 : case CPTK_HAS_TRIVIAL_COPY:
13985 : /* ??? The standard seems to be missing the "or array of such a class
13986 : type" wording for this trait. */
13987 526 : type1 = strip_array_types (type1);
13988 878 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
13989 863 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
13990 :
13991 761 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
13992 761 : type1 = strip_array_types (type1);
13993 761 : if (CLASS_TYPE_P (type1) && type_build_dtor_call (type1))
13994 : {
13995 123 : deferring_access_check_sentinel dacs (dk_no_check);
13996 123 : cp_unevaluated un;
13997 123 : tree fn = get_dtor (type1, tf_none);
13998 123 : if (!fn && !seen_error ())
13999 3 : warning (0, "checking %qs for type %qT with a destructor that "
14000 : "cannot be called", "__has_trivial_destructor", type1);
14001 123 : }
14002 1092 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14003 1089 : || (CLASS_TYPE_P (type1)
14004 284 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
14005 :
14006 57452 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14007 57452 : return type_has_unique_obj_representations (type1);
14008 :
14009 279 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14010 279 : return type_has_virtual_destructor (type1);
14011 :
14012 54122 : case CPTK_IS_ABSTRACT:
14013 54122 : return ABSTRACT_CLASS_TYPE_P (type1);
14014 :
14015 813 : case CPTK_IS_AGGREGATE:
14016 813 : return CP_AGGREGATE_TYPE_P (type1);
14017 :
14018 467906 : case CPTK_IS_ARRAY:
14019 467906 : return (type_code1 == ARRAY_TYPE
14020 : /* We don't want to report T[0] as being an array type.
14021 : This is for compatibility with an implementation of
14022 : std::is_array by template argument deduction, because
14023 : compute_array_index_type_loc rejects a zero-size array
14024 : in SFINAE context. */
14025 467906 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14026 :
14027 1108002 : case CPTK_IS_ASSIGNABLE:
14028 1108002 : return is_xible (MODIFY_EXPR, type1, type2);
14029 :
14030 563483 : case CPTK_IS_BASE_OF:
14031 563392 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14032 1108864 : && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
14033 520461 : || DERIVED_FROM_P (type1, type2)));
14034 :
14035 91397 : case CPTK_IS_BOUNDED_ARRAY:
14036 91397 : return (type_code1 == ARRAY_TYPE
14037 1230 : && TYPE_DOMAIN (type1)
14038 : /* We don't want to report T[0] as being a bounded array type.
14039 : This is for compatibility with an implementation of
14040 : std::is_bounded_array by template argument deduction, because
14041 : compute_array_index_type_loc rejects a zero-size array
14042 : in SFINAE context. */
14043 92511 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14044 :
14045 682418 : case CPTK_IS_CLASS:
14046 682418 : return NON_UNION_CLASS_TYPE_P (type1);
14047 :
14048 704635 : case CPTK_IS_CONST:
14049 704635 : return CP_TYPE_CONST_P (type1);
14050 :
14051 3013962 : case CPTK_IS_CONSTRUCTIBLE:
14052 3013962 : return is_xible (INIT_EXPR, type1, type2);
14053 :
14054 3697260 : case CPTK_IS_CONVERTIBLE:
14055 3697260 : return is_convertible (type1, type2);
14056 :
14057 1868 : case CPTK_IS_DESTRUCTIBLE:
14058 1868 : return is_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14059 :
14060 244581 : case CPTK_IS_EMPTY:
14061 244581 : return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
14062 :
14063 713959 : case CPTK_IS_ENUM:
14064 713959 : return type_code1 == ENUMERAL_TYPE;
14065 :
14066 447764 : case CPTK_IS_FINAL:
14067 447764 : return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
14068 :
14069 60901 : case CPTK_IS_FUNCTION:
14070 60901 : return type_code1 == FUNCTION_TYPE;
14071 :
14072 800 : case CPTK_IS_IMPLICIT_LIFETIME:
14073 800 : return implicit_lifetime_type_p (type1);
14074 :
14075 45794 : case CPTK_IS_INVOCABLE:
14076 45794 : return !error_operand_p (build_invoke (type1, type2, tf_none));
14077 :
14078 195 : case CPTK_IS_LAYOUT_COMPATIBLE:
14079 195 : return layout_compatible_type_p (type1, type2);
14080 :
14081 197 : case CPTK_IS_LITERAL_TYPE:
14082 197 : return literal_type_p (type1);
14083 :
14084 45978 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14085 45978 : return TYPE_PTRMEMFUNC_P (type1);
14086 :
14087 45947 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14088 45947 : return TYPE_PTRDATAMEM_P (type1);
14089 :
14090 10172 : case CPTK_IS_MEMBER_POINTER:
14091 10172 : return TYPE_PTRMEM_P (type1);
14092 :
14093 542863 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14094 542863 : return is_nothrow_xible (MODIFY_EXPR, type1, type2);
14095 :
14096 998315 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14097 998315 : return is_nothrow_xible (INIT_EXPR, type1, type2);
14098 :
14099 667 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14100 667 : return is_nothrow_convertible (type1, type2);
14101 :
14102 22992 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14103 22992 : return is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14104 :
14105 40148 : case CPTK_IS_NOTHROW_INVOCABLE:
14106 40148 : return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
14107 :
14108 1250149 : case CPTK_IS_OBJECT:
14109 1250149 : return object_type_p (type1);
14110 :
14111 142 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14112 142 : return pointer_interconvertible_base_of_p (type1, type2);
14113 :
14114 10938 : case CPTK_IS_POD:
14115 10938 : return pod_type_p (type1);
14116 :
14117 151803 : case CPTK_IS_POINTER:
14118 151803 : return TYPE_PTR_P (type1);
14119 :
14120 277 : case CPTK_IS_POLYMORPHIC:
14121 277 : return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
14122 :
14123 822527 : case CPTK_IS_REFERENCE:
14124 822527 : return type_code1 == REFERENCE_TYPE;
14125 :
14126 4217064 : case CPTK_IS_SAME:
14127 4217064 : return same_type_p (type1, type2);
14128 :
14129 373 : case CPTK_IS_SCOPED_ENUM:
14130 373 : return SCOPED_ENUM_P (type1);
14131 :
14132 57537 : case CPTK_IS_STD_LAYOUT:
14133 57537 : return std_layout_type_p (type1);
14134 :
14135 54295 : case CPTK_IS_TRIVIAL:
14136 54295 : return trivial_type_p (type1);
14137 :
14138 9935 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14139 9935 : return is_trivially_xible (MODIFY_EXPR, type1, type2);
14140 :
14141 66414 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14142 66414 : return is_trivially_xible (INIT_EXPR, type1, type2);
14143 :
14144 108300 : case CPTK_IS_TRIVIALLY_COPYABLE:
14145 108300 : return trivially_copyable_p (type1);
14146 :
14147 24297 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14148 24297 : return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14149 :
14150 90425 : case CPTK_IS_UNBOUNDED_ARRAY:
14151 90425 : return array_of_unknown_bound_p (type1);
14152 :
14153 265840 : case CPTK_IS_UNION:
14154 265840 : return type_code1 == UNION_TYPE;
14155 :
14156 712 : case CPTK_IS_VIRTUAL_BASE_OF:
14157 646 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14158 1342 : && lookup_base (type2, type1, ba_require_virtual,
14159 : NULL, tf_none) != NULL_TREE);
14160 :
14161 726008 : case CPTK_IS_VOLATILE:
14162 726008 : return CP_TYPE_VOLATILE_P (type1);
14163 :
14164 225463 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14165 225463 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
14166 :
14167 51495 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14168 51495 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/false);
14169 :
14170 79 : case CPTK_IS_DEDUCIBLE:
14171 79 : return type_targs_deducible_from (type1, type2);
14172 :
14173 28 : case CPTK_IS_CONSTEVAL_ONLY:
14174 28 : return consteval_only_p (type1);
14175 :
14176 : /* __array_rank, __builtin_type_order and __builtin_structured_binding_size
14177 : are handled in finish_trait_expr. */
14178 0 : case CPTK_RANK:
14179 0 : case CPTK_TYPE_ORDER:
14180 0 : case CPTK_STRUCTURED_BINDING_SIZE:
14181 0 : gcc_unreachable ();
14182 :
14183 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14184 : case CPTK_##CODE:
14185 : #include "cp-trait.def"
14186 : #undef DEFTRAIT_TYPE
14187 : /* Type-yielding traits are handled in finish_trait_type. */
14188 : break;
14189 : }
14190 :
14191 0 : gcc_unreachable ();
14192 : }
14193 :
14194 : /* Returns true if TYPE meets the requirements for the specified KIND,
14195 : false otherwise.
14196 :
14197 : When KIND == 1, TYPE must be an array of unknown bound,
14198 : or (possibly cv-qualified) void, or a complete type.
14199 :
14200 : When KIND == 2, TYPE must be a complete type, or array of complete type,
14201 : or (possibly cv-qualified) void.
14202 :
14203 : When KIND == 3:
14204 : If TYPE is a non-union class type, it must be complete.
14205 :
14206 : When KIND == 4:
14207 : If TYPE is a class type, it must be complete. */
14208 :
14209 : static bool
14210 21921010 : check_trait_type (tree type, int kind = 1)
14211 : {
14212 21921010 : if (type == NULL_TREE)
14213 : return true;
14214 :
14215 21921010 : if (TREE_CODE (type) == TREE_VEC)
14216 : {
14217 7246077 : for (tree arg : tree_vec_range (type))
14218 3084595 : if (!check_trait_type (arg, kind))
14219 21 : return false;
14220 4161482 : return true;
14221 : }
14222 :
14223 17759507 : if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
14224 : return true; // Array of unknown bound. Don't care about completeness.
14225 :
14226 17758963 : if (kind == 3 && !NON_UNION_CLASS_TYPE_P (type))
14227 : return true; // Not a non-union class type. Don't care about completeness.
14228 :
14229 17648657 : if (kind == 4 && TREE_CODE (type) == ARRAY_TYPE)
14230 : return true; // Not a class type. Don't care about completeness.
14231 :
14232 17648170 : if (VOID_TYPE_P (type))
14233 : return true;
14234 :
14235 17647070 : type = complete_type (strip_array_types (type));
14236 17647070 : if (!COMPLETE_TYPE_P (type)
14237 152 : && cxx_incomplete_type_diagnostic (NULL_TREE, type,
14238 : diagnostics::kind::permerror)
14239 17647222 : && !flag_permissive)
14240 : return false;
14241 : return true;
14242 : }
14243 :
14244 : /* True iff the conversion (if any) would be a direct reference
14245 : binding, not requiring complete types. This is LWG2939. */
14246 :
14247 : static bool
14248 8139578 : same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2)
14249 : {
14250 8139578 : tree from, to;
14251 8139578 : switch (kind)
14252 : {
14253 : /* These put the target type first. */
14254 : case CPTK_IS_CONSTRUCTIBLE:
14255 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14256 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14257 : case CPTK_IS_INVOCABLE:
14258 : case CPTK_IS_NOTHROW_INVOCABLE:
14259 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14260 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14261 : to = type1;
14262 : from = type2;
14263 : break;
14264 :
14265 : /* These put it second. */
14266 3697927 : case CPTK_IS_CONVERTIBLE:
14267 3697927 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14268 3697927 : to = type2;
14269 3697927 : from = type1;
14270 3697927 : break;
14271 :
14272 0 : default:
14273 0 : gcc_unreachable ();
14274 : }
14275 :
14276 8139578 : if (TREE_CODE (to) != REFERENCE_TYPE || !from)
14277 : return false;
14278 990421 : if (TREE_CODE (from) == TREE_VEC && TREE_VEC_LENGTH (from) == 1)
14279 57687 : from = TREE_VEC_ELT (from, 0);
14280 990421 : return (TYPE_P (from)
14281 1973088 : && (same_type_ignoring_top_level_qualifiers_p
14282 982667 : (non_reference (to), non_reference (from))));
14283 : }
14284 :
14285 : /* Helper for finish_trait_expr and tsubst_expr. Handle
14286 : CPTK_STRUCTURED_BINDING_SIZE in possibly SFINAE-friendly
14287 : way. */
14288 :
14289 : tree
14290 261 : finish_structured_binding_size (location_t loc, tree type,
14291 : tsubst_flags_t complain)
14292 : {
14293 261 : if (TYPE_REF_P (type))
14294 : {
14295 105 : if (complain & tf_error)
14296 99 : error_at (loc, "%qs argument %qT is a reference",
14297 : "__builtin_structured_binding_size", type);
14298 105 : return error_mark_node;
14299 : }
14300 156 : HOST_WIDE_INT ret = cp_decomp_size (loc, type, complain);
14301 156 : if (ret == -1)
14302 57 : return error_mark_node;
14303 99 : return maybe_wrap_with_location (build_int_cst (size_type_node, ret), loc);
14304 : }
14305 :
14306 : /* Process a trait expression. */
14307 :
14308 : tree
14309 24974808 : finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2)
14310 : {
14311 24974808 : if (type1 == error_mark_node
14312 24974805 : || type2 == error_mark_node)
14313 : return error_mark_node;
14314 :
14315 24974805 : if (processing_template_decl)
14316 : {
14317 3173026 : tree trait_expr = make_node (TRAIT_EXPR);
14318 3173026 : if (kind == CPTK_RANK || kind == CPTK_STRUCTURED_BINDING_SIZE)
14319 29139 : TREE_TYPE (trait_expr) = size_type_node;
14320 3143887 : else if (kind == CPTK_TYPE_ORDER)
14321 : {
14322 2894 : tree val = type_order_value (type1, type1);
14323 2894 : if (val != error_mark_node)
14324 2894 : TREE_TYPE (trait_expr) = TREE_TYPE (val);
14325 : }
14326 : else
14327 3140993 : TREE_TYPE (trait_expr) = boolean_type_node;
14328 3173026 : TRAIT_EXPR_TYPE1 (trait_expr) = type1;
14329 3173026 : TRAIT_EXPR_TYPE2 (trait_expr) = type2;
14330 3173026 : TRAIT_EXPR_KIND (trait_expr) = kind;
14331 3173026 : TRAIT_EXPR_LOCATION (trait_expr) = loc;
14332 3173026 : return trait_expr;
14333 : }
14334 :
14335 21801779 : switch (kind)
14336 : {
14337 51520 : case CPTK_HAS_NOTHROW_ASSIGN:
14338 51520 : case CPTK_HAS_TRIVIAL_ASSIGN:
14339 51520 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14340 51520 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14341 51520 : case CPTK_HAS_NOTHROW_COPY:
14342 51520 : case CPTK_HAS_TRIVIAL_COPY:
14343 51520 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14344 51520 : case CPTK_IS_DESTRUCTIBLE:
14345 51520 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14346 51520 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14347 51520 : if (!check_trait_type (type1))
14348 21 : return error_mark_node;
14349 : break;
14350 :
14351 288780 : case CPTK_IS_LITERAL_TYPE:
14352 288780 : case CPTK_IS_POD:
14353 288780 : case CPTK_IS_STD_LAYOUT:
14354 288780 : case CPTK_IS_TRIVIAL:
14355 288780 : case CPTK_IS_TRIVIALLY_COPYABLE:
14356 288780 : case CPTK_IS_CONSTEVAL_ONLY:
14357 288780 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14358 288780 : if (!check_trait_type (type1, /* kind = */ 2))
14359 33 : return error_mark_node;
14360 : break;
14361 :
14362 299274 : case CPTK_IS_ABSTRACT:
14363 299274 : case CPTK_IS_EMPTY:
14364 299274 : case CPTK_IS_POLYMORPHIC:
14365 299274 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14366 299274 : if (!check_trait_type (type1, /* kind = */ 3))
14367 15 : return error_mark_node;
14368 : break;
14369 :
14370 : /* N.B. std::is_aggregate is kind=2 but we don't need a complete element
14371 : type to know whether an array is an aggregate, so use kind=4 here. */
14372 449394 : case CPTK_IS_AGGREGATE:
14373 449394 : case CPTK_IS_FINAL:
14374 449394 : case CPTK_IS_IMPLICIT_LIFETIME:
14375 449394 : if (!check_trait_type (type1, /* kind = */ 4))
14376 17 : return error_mark_node;
14377 : break;
14378 :
14379 8139578 : case CPTK_IS_CONSTRUCTIBLE:
14380 8139578 : case CPTK_IS_CONVERTIBLE:
14381 8139578 : case CPTK_IS_INVOCABLE:
14382 8139578 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14383 8139578 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14384 8139578 : case CPTK_IS_NOTHROW_INVOCABLE:
14385 8139578 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14386 8139578 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14387 8139578 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14388 8139578 : /* Don't check completeness for direct reference binding. */;
14389 8139578 : if (same_type_ref_bind_p (kind, type1, type2))
14390 : break;
14391 8873743 : gcc_fallthrough ();
14392 :
14393 8873743 : case CPTK_IS_ASSIGNABLE:
14394 8873743 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14395 8873743 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14396 8873743 : if (!check_trait_type (type1)
14397 8873743 : || !check_trait_type (type2))
14398 63 : return error_mark_node;
14399 : break;
14400 :
14401 563628 : case CPTK_IS_BASE_OF:
14402 563628 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14403 563525 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14404 545511 : && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
14405 1084189 : && !complete_type_or_else (type2, NULL_TREE))
14406 : /* We already issued an error. */
14407 3 : return error_mark_node;
14408 : break;
14409 :
14410 715 : case CPTK_IS_VIRTUAL_BASE_OF:
14411 649 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14412 1348 : && !complete_type_or_else (type2, NULL_TREE))
14413 : /* We already issued an error. */
14414 3 : return error_mark_node;
14415 : break;
14416 :
14417 : case CPTK_IS_ARRAY:
14418 : case CPTK_IS_BOUNDED_ARRAY:
14419 : case CPTK_IS_CLASS:
14420 : case CPTK_IS_CONST:
14421 : case CPTK_IS_ENUM:
14422 : case CPTK_IS_FUNCTION:
14423 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14424 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14425 : case CPTK_IS_MEMBER_POINTER:
14426 : case CPTK_IS_OBJECT:
14427 : case CPTK_IS_POINTER:
14428 : case CPTK_IS_REFERENCE:
14429 : case CPTK_IS_SAME:
14430 : case CPTK_IS_SCOPED_ENUM:
14431 : case CPTK_IS_UNBOUNDED_ARRAY:
14432 : case CPTK_IS_UNION:
14433 : case CPTK_IS_VOLATILE:
14434 : break;
14435 :
14436 : case CPTK_RANK:
14437 : {
14438 : size_t rank = 0;
14439 122 : for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
14440 80 : ++rank;
14441 42 : return maybe_wrap_with_location (build_int_cst (size_type_node, rank),
14442 : loc);
14443 : }
14444 :
14445 122 : case CPTK_TYPE_ORDER:
14446 122 : return maybe_wrap_with_location (type_order_value (type1, type2), loc);
14447 :
14448 138 : case CPTK_STRUCTURED_BINDING_SIZE:
14449 138 : return finish_structured_binding_size (loc, type1, tf_warning_or_error);
14450 :
14451 204 : case CPTK_IS_LAYOUT_COMPATIBLE:
14452 204 : if (!array_of_unknown_bound_p (type1)
14453 189 : && TREE_CODE (type1) != VOID_TYPE
14454 387 : && !complete_type_or_else (type1, NULL_TREE))
14455 : /* We already issued an error. */
14456 6 : return error_mark_node;
14457 198 : if (!array_of_unknown_bound_p (type2)
14458 177 : && TREE_CODE (type2) != VOID_TYPE
14459 369 : && !complete_type_or_else (type2, NULL_TREE))
14460 : /* We already issued an error. */
14461 3 : return error_mark_node;
14462 : break;
14463 :
14464 79 : case CPTK_IS_DEDUCIBLE:
14465 79 : if (!DECL_TYPE_TEMPLATE_P (type1))
14466 : {
14467 0 : error ("%qD is not a class or alias template", type1);
14468 0 : return error_mark_node;
14469 : }
14470 : break;
14471 :
14472 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14473 : case CPTK_##CODE:
14474 : #include "cp-trait.def"
14475 : #undef DEFTRAIT_TYPE
14476 : /* Type-yielding traits are handled in finish_trait_type. */
14477 0 : gcc_unreachable ();
14478 : }
14479 :
14480 21801313 : tree val = (trait_expr_value (kind, type1, type2)
14481 21801313 : ? boolean_true_node : boolean_false_node);
14482 21801313 : return maybe_wrap_with_location (val, loc);
14483 : }
14484 :
14485 : /* Process a trait type. */
14486 :
14487 : tree
14488 9216892 : finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
14489 : tsubst_flags_t complain)
14490 : {
14491 9216892 : if (type1 == error_mark_node
14492 9216889 : || type2 == error_mark_node)
14493 : return error_mark_node;
14494 :
14495 9216889 : if (processing_template_decl)
14496 : {
14497 213531 : tree type = cxx_make_type (TRAIT_TYPE);
14498 213531 : TRAIT_TYPE_TYPE1 (type) = type1;
14499 213531 : TRAIT_TYPE_TYPE2 (type) = type2;
14500 213531 : TRAIT_TYPE_KIND_RAW (type) = build_int_cstu (integer_type_node, kind);
14501 : /* These traits are intended to be used in the definition of the ::type
14502 : member of the corresponding standard library type trait and aren't
14503 : mangleable (and thus won't appear directly in template signatures),
14504 : so structural equality should suffice. */
14505 213531 : SET_TYPE_STRUCTURAL_EQUALITY (type);
14506 213531 : return type;
14507 : }
14508 :
14509 9003358 : switch (kind)
14510 : {
14511 1406434 : case CPTK_ADD_LVALUE_REFERENCE:
14512 : /* [meta.trans.ref]. */
14513 1406434 : if (referenceable_type_p (type1))
14514 1406359 : return cp_build_reference_type (type1, /*rval=*/false);
14515 : return type1;
14516 :
14517 728427 : case CPTK_ADD_POINTER:
14518 : /* [meta.trans.ptr]. */
14519 728427 : if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
14520 : {
14521 728395 : if (TYPE_REF_P (type1))
14522 727336 : type1 = TREE_TYPE (type1);
14523 728395 : return build_pointer_type (type1);
14524 : }
14525 : return type1;
14526 :
14527 1907562 : case CPTK_ADD_RVALUE_REFERENCE:
14528 : /* [meta.trans.ref]. */
14529 1907562 : if (referenceable_type_p (type1))
14530 1907509 : return cp_build_reference_type (type1, /*rval=*/true);
14531 : return type1;
14532 :
14533 269602 : case CPTK_DECAY:
14534 269602 : if (TYPE_REF_P (type1))
14535 40756 : type1 = TREE_TYPE (type1);
14536 :
14537 269602 : if (TREE_CODE (type1) == ARRAY_TYPE)
14538 670 : return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
14539 670 : complain);
14540 268932 : else if (TREE_CODE (type1) == FUNCTION_TYPE)
14541 176 : return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
14542 : else
14543 268756 : return cv_unqualified (type1);
14544 :
14545 219 : case CPTK_REMOVE_ALL_EXTENTS:
14546 219 : return strip_array_types (type1);
14547 :
14548 1120530 : case CPTK_REMOVE_CV:
14549 1120530 : return cv_unqualified (type1);
14550 :
14551 660948 : case CPTK_REMOVE_CVREF:
14552 660948 : if (TYPE_REF_P (type1))
14553 331713 : type1 = TREE_TYPE (type1);
14554 660948 : return cv_unqualified (type1);
14555 :
14556 63845 : case CPTK_REMOVE_EXTENT:
14557 63845 : if (TREE_CODE (type1) == ARRAY_TYPE)
14558 9079 : type1 = TREE_TYPE (type1);
14559 : return type1;
14560 :
14561 49835 : case CPTK_REMOVE_POINTER:
14562 49835 : if (TYPE_PTR_P (type1))
14563 47130 : type1 = TREE_TYPE (type1);
14564 : return type1;
14565 :
14566 2643539 : case CPTK_REMOVE_REFERENCE:
14567 2643539 : if (TYPE_REF_P (type1))
14568 1631513 : type1 = TREE_TYPE (type1);
14569 : return type1;
14570 :
14571 106164 : case CPTK_TYPE_PACK_ELEMENT:
14572 106164 : return finish_type_pack_element (type1, type2, complain);
14573 :
14574 46253 : case CPTK_UNDERLYING_TYPE:
14575 46253 : return finish_underlying_type (type1);
14576 :
14577 : #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
14578 : case CPTK_##CODE:
14579 : #include "cp-trait.def"
14580 : #undef DEFTRAIT_EXPR
14581 : /* Expression-yielding traits are handled in finish_trait_expr. */
14582 : case CPTK_BASES:
14583 : case CPTK_DIRECT_BASES:
14584 : /* BASES and DIRECT_BASES are handled in finish_bases. */
14585 : break;
14586 : }
14587 :
14588 0 : gcc_unreachable ();
14589 : }
14590 :
14591 : /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
14592 : which is ignored for C++. */
14593 :
14594 : void
14595 0 : set_float_const_decimal64 (void)
14596 : {
14597 0 : }
14598 :
14599 : void
14600 0 : clear_float_const_decimal64 (void)
14601 : {
14602 0 : }
14603 :
14604 : bool
14605 1870989 : float_const_decimal64_p (void)
14606 : {
14607 1870989 : return 0;
14608 : }
14609 :
14610 :
14611 : /* Return true if T designates the implied `this' parameter. */
14612 :
14613 : bool
14614 6322771 : is_this_parameter (tree t)
14615 : {
14616 6322771 : if (!DECL_P (t) || DECL_NAME (t) != this_identifier)
14617 : return false;
14618 3567889 : gcc_assert (TREE_CODE (t) == PARM_DECL
14619 : || (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
14620 : || (cp_binding_oracle && VAR_P (t)));
14621 : return true;
14622 : }
14623 :
14624 : /* As above, or a C++23 explicit object parameter. */
14625 :
14626 : bool
14627 456 : is_object_parameter (tree t)
14628 : {
14629 456 : if (is_this_parameter (t))
14630 : return true;
14631 91 : if (TREE_CODE (t) != PARM_DECL)
14632 : return false;
14633 34 : tree ctx = DECL_CONTEXT (t);
14634 34 : return (ctx && DECL_XOBJ_MEMBER_FUNCTION_P (ctx)
14635 62 : && t == DECL_ARGUMENTS (ctx));
14636 : }
14637 :
14638 : /* Insert the deduced return type for an auto function. */
14639 :
14640 : void
14641 2249037 : apply_deduced_return_type (tree fco, tree return_type)
14642 : {
14643 2249037 : tree result;
14644 :
14645 2249037 : if (return_type == error_mark_node)
14646 : return;
14647 :
14648 2249034 : if (DECL_CONV_FN_P (fco))
14649 42 : DECL_NAME (fco) = make_conv_op_name (return_type);
14650 :
14651 2249034 : TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
14652 :
14653 2249034 : maybe_update_postconditions (fco);
14654 :
14655 : /* Apply the type to the result object. */
14656 :
14657 2249034 : result = DECL_RESULT (fco);
14658 2249034 : if (result == NULL_TREE)
14659 : return;
14660 2239559 : if (TREE_TYPE (result) == return_type)
14661 : return;
14662 :
14663 2239553 : if (!processing_template_decl && !VOID_TYPE_P (return_type)
14664 3755075 : && !complete_type_or_else (return_type, NULL_TREE))
14665 : return;
14666 :
14667 : /* We already have a DECL_RESULT from start_preparsed_function.
14668 : Now we need to redo the work it and allocate_struct_function
14669 : did to reflect the new type. */
14670 2239556 : result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
14671 2239556 : TYPE_MAIN_VARIANT (return_type));
14672 2239556 : DECL_ARTIFICIAL (result) = 1;
14673 2239556 : DECL_IGNORED_P (result) = 1;
14674 2239556 : cp_apply_type_quals_to_decl (cp_type_quals (return_type),
14675 : result);
14676 2239556 : DECL_RESULT (fco) = result;
14677 :
14678 2239556 : if (!uses_template_parms (fco))
14679 2239556 : if (function *fun = DECL_STRUCT_FUNCTION (fco))
14680 : {
14681 2239068 : bool aggr = aggregate_value_p (result, fco);
14682 : #ifdef PCC_STATIC_STRUCT_RETURN
14683 : fun->returns_pcc_struct = aggr;
14684 : #endif
14685 2239068 : fun->returns_struct = aggr;
14686 : }
14687 : }
14688 :
14689 : /* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true,
14690 : this is a right unary fold. Otherwise it is a left unary fold. */
14691 :
14692 : static tree
14693 741213 : finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir)
14694 : {
14695 : /* Build a pack expansion (assuming expr has pack type). */
14696 741213 : if (!uses_parameter_packs (expr))
14697 : {
14698 3 : error_at (location_of (expr), "operand of fold expression has no "
14699 : "unexpanded parameter packs");
14700 3 : return error_mark_node;
14701 : }
14702 741210 : tree pack = make_pack_expansion (expr);
14703 :
14704 : /* Build the fold expression. */
14705 741210 : tree code = build_int_cstu (integer_type_node, abs (op));
14706 741210 : tree fold = build_min_nt_loc (loc, dir, code, pack);
14707 741210 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14708 741210 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14709 741210 : FOLD_EXPR_OP (fold),
14710 741210 : FOLD_EXPR_MODIFY_P (fold));
14711 741210 : return fold;
14712 : }
14713 :
14714 : tree
14715 19869 : finish_left_unary_fold_expr (location_t loc, tree expr, int op)
14716 : {
14717 19869 : return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR);
14718 : }
14719 :
14720 : tree
14721 721344 : finish_right_unary_fold_expr (location_t loc, tree expr, int op)
14722 : {
14723 721344 : return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR);
14724 : }
14725 :
14726 : /* Build a binary fold expression over EXPR1 and EXPR2. The
14727 : associativity of the fold is determined by EXPR1 and EXPR2 (whichever
14728 : has an unexpanded parameter pack). */
14729 :
14730 : static tree
14731 184203 : finish_binary_fold_expr (location_t loc, tree pack, tree init,
14732 : int op, tree_code dir)
14733 : {
14734 184203 : pack = make_pack_expansion (pack);
14735 184203 : tree code = build_int_cstu (integer_type_node, abs (op));
14736 184203 : tree fold = build_min_nt_loc (loc, dir, code, pack, init);
14737 184203 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14738 184203 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14739 184203 : FOLD_EXPR_OP (fold),
14740 184203 : FOLD_EXPR_MODIFY_P (fold));
14741 184203 : return fold;
14742 : }
14743 :
14744 : tree
14745 184203 : finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op)
14746 : {
14747 : // Determine which expr has an unexpanded parameter pack and
14748 : // set the pack and initial term.
14749 184203 : bool pack1 = uses_parameter_packs (expr1);
14750 184203 : bool pack2 = uses_parameter_packs (expr2);
14751 184203 : if (pack1 && !pack2)
14752 794 : return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
14753 183409 : else if (pack2 && !pack1)
14754 183409 : return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
14755 : else
14756 : {
14757 0 : if (pack1)
14758 0 : error ("both arguments in binary fold have unexpanded parameter packs");
14759 : else
14760 0 : error ("no unexpanded parameter packs in binary fold");
14761 : }
14762 0 : return error_mark_node;
14763 : }
14764 :
14765 : /* Finish __builtin_launder (arg). */
14766 :
14767 : tree
14768 12811 : finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain)
14769 : {
14770 12811 : tree orig_arg = arg;
14771 12811 : if (!type_dependent_expression_p (arg))
14772 84 : arg = decay_conversion (arg, complain);
14773 12811 : if (error_operand_p (arg))
14774 0 : return error_mark_node;
14775 12811 : if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
14776 : {
14777 24 : error_at (loc, "type %qT of argument to %<__builtin_launder%> "
14778 24 : "is not a pointer to object type", TREE_TYPE (arg));
14779 24 : return error_mark_node;
14780 : }
14781 12787 : if (processing_template_decl)
14782 12727 : arg = orig_arg;
14783 12787 : return build_call_expr_internal_loc (loc, IFN_LAUNDER,
14784 25574 : TREE_TYPE (arg), 1, arg);
14785 : }
14786 :
14787 : /* Finish __builtin_convertvector (arg, type). */
14788 :
14789 : tree
14790 312 : cp_build_vec_convert (tree arg, location_t loc, tree type,
14791 : tsubst_flags_t complain)
14792 : {
14793 312 : if (error_operand_p (type))
14794 9 : return error_mark_node;
14795 303 : if (error_operand_p (arg))
14796 0 : return error_mark_node;
14797 :
14798 303 : tree ret = NULL_TREE;
14799 303 : if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
14800 295 : ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg),
14801 : decay_conversion (arg, complain),
14802 : loc, type, (complain & tf_error) != 0);
14803 :
14804 303 : if (!processing_template_decl)
14805 : return ret;
14806 :
14807 50 : return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg);
14808 : }
14809 :
14810 : /* Finish __builtin_bit_cast (type, arg). */
14811 :
14812 : tree
14813 272265 : cp_build_bit_cast (location_t loc, tree type, tree arg,
14814 : tsubst_flags_t complain)
14815 : {
14816 272265 : if (error_operand_p (type))
14817 0 : return error_mark_node;
14818 272265 : if (!dependent_type_p (type))
14819 : {
14820 197854 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
14821 9 : return error_mark_node;
14822 197845 : if (TREE_CODE (type) == ARRAY_TYPE)
14823 : {
14824 : /* std::bit_cast for destination ARRAY_TYPE is not possible,
14825 : as functions may not return an array, so don't bother trying
14826 : to support this (and then deal with VLAs etc.). */
14827 9 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14828 : "is an array type", type);
14829 9 : return error_mark_node;
14830 : }
14831 197836 : if (!trivially_copyable_p (type))
14832 : {
14833 18 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14834 : "is not trivially copyable", type);
14835 18 : return error_mark_node;
14836 : }
14837 197818 : if (consteval_only_p (type) || consteval_only_p (arg))
14838 : {
14839 4 : error_at (loc, "%<__builtin_bit_cast%> cannot be used with "
14840 : "consteval-only types");
14841 4 : return error_mark_node;
14842 : }
14843 : }
14844 :
14845 272225 : if (error_operand_p (arg))
14846 0 : return error_mark_node;
14847 :
14848 272225 : if (!type_dependent_expression_p (arg))
14849 : {
14850 109185 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
14851 : {
14852 : /* Don't perform array-to-pointer conversion. */
14853 39 : arg = mark_rvalue_use (arg, loc, true);
14854 39 : if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
14855 0 : return error_mark_node;
14856 : }
14857 : else
14858 109146 : arg = decay_conversion (arg, complain);
14859 :
14860 109185 : if (error_operand_p (arg))
14861 12 : return error_mark_node;
14862 :
14863 109173 : if (!trivially_copyable_p (TREE_TYPE (arg)))
14864 : {
14865 9 : error_at (cp_expr_loc_or_loc (arg, loc),
14866 : "%<__builtin_bit_cast%> source type %qT "
14867 9 : "is not trivially copyable", TREE_TYPE (arg));
14868 9 : return error_mark_node;
14869 : }
14870 109164 : if (!dependent_type_p (type)
14871 181767 : && !cp_tree_equal (TYPE_SIZE_UNIT (type),
14872 72603 : TYPE_SIZE_UNIT (TREE_TYPE (arg))))
14873 : {
14874 18 : error_at (loc, "%<__builtin_bit_cast%> source size %qE "
14875 : "not equal to destination type size %qE",
14876 18 : TYPE_SIZE_UNIT (TREE_TYPE (arg)),
14877 18 : TYPE_SIZE_UNIT (type));
14878 18 : return error_mark_node;
14879 : }
14880 : }
14881 :
14882 272186 : tree ret = build_min (BIT_CAST_EXPR, type, arg);
14883 272186 : SET_EXPR_LOCATION (ret, loc);
14884 :
14885 272186 : if (!processing_template_decl && CLASS_TYPE_P (type))
14886 300 : ret = get_target_expr (ret, complain);
14887 :
14888 : return ret;
14889 : }
14890 :
14891 : /* Diagnose invalid #pragma GCC unroll argument and adjust
14892 : it if needed. */
14893 :
14894 : tree
14895 22660 : cp_check_pragma_unroll (location_t loc, tree unroll)
14896 : {
14897 22660 : HOST_WIDE_INT lunroll = 0;
14898 22660 : if (type_dependent_expression_p (unroll))
14899 : ;
14900 45248 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll))
14901 45202 : || (!value_dependent_expression_p (unroll)
14902 22548 : && (!tree_fits_shwi_p (unroll)
14903 22522 : || (lunroll = tree_to_shwi (unroll)) < 0
14904 22507 : || lunroll >= USHRT_MAX)))
14905 : {
14906 90 : error_at (loc, "%<#pragma GCC unroll%> requires an"
14907 : " assignment-expression that evaluates to a non-negative"
14908 : " integral constant less than %u", USHRT_MAX);
14909 90 : unroll = integer_one_node;
14910 : }
14911 22534 : else if (TREE_CODE (unroll) == INTEGER_CST)
14912 : {
14913 22504 : unroll = fold_convert (integer_type_node, unroll);
14914 22504 : if (integer_zerop (unroll))
14915 12 : unroll = integer_one_node;
14916 : }
14917 22660 : return unroll;
14918 : }
14919 :
14920 : #include "gt-cp-semantics.h"
|