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 24052971922 : push_deferring_access_checks (deferring_kind deferring)
146 : {
147 : /* For context like template instantiation, access checking
148 : disabling applies to all nested context. */
149 24052971922 : if (deferred_access_no_check || deferring == dk_no_check)
150 309360989 : deferred_access_no_check++;
151 : else
152 : {
153 23743610933 : deferred_access e = {NULL, deferring};
154 23743610933 : vec_safe_push (deferred_access_stack, e);
155 : }
156 24052971922 : }
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 386274742 : reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
163 : {
164 386274742 : push_deferring_access_checks (dk_deferred);
165 386274742 : if (!deferred_access_no_check)
166 378571230 : deferred_access_stack->last().deferred_access_checks = checks;
167 386274742 : }
168 :
169 : /* Resume deferring access checks again after we stopped doing
170 : this previously. */
171 :
172 : void
173 183507212 : resume_deferring_access_checks (void)
174 : {
175 183507212 : if (!deferred_access_no_check)
176 183486898 : deferred_access_stack->last().deferring_access_checks_kind = dk_deferred;
177 183507212 : }
178 :
179 : /* Stop deferring access checks. */
180 :
181 : void
182 514550680 : stop_deferring_access_checks (void)
183 : {
184 514550680 : if (!deferred_access_no_check)
185 514490603 : deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred;
186 514550680 : }
187 :
188 : /* Discard the current deferred access checks and restore the
189 : previous states. */
190 :
191 : void
192 14910101354 : pop_deferring_access_checks (void)
193 : {
194 14910101354 : if (deferred_access_no_check)
195 237177903 : deferred_access_no_check--;
196 : else
197 14672923451 : deferred_access_stack->pop ();
198 14910101354 : }
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 1287162378 : get_deferred_access_checks (void)
207 : {
208 1287162378 : if (deferred_access_no_check)
209 : return NULL;
210 : else
211 1271302628 : 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 9142731795 : pop_to_parent_deferring_access_checks (void)
220 : {
221 9142731795 : if (deferred_access_no_check)
222 72183080 : deferred_access_no_check--;
223 : else
224 : {
225 9070548715 : vec<deferred_access_check, va_gc> *checks;
226 9070548715 : deferred_access *ptr;
227 :
228 9070548715 : checks = (deferred_access_stack->last ().deferred_access_checks);
229 :
230 9070548715 : deferred_access_stack->pop ();
231 9070548715 : ptr = &deferred_access_stack->last ();
232 9070548715 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
233 : {
234 : /* Check access. */
235 571643471 : 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 8702595554 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
244 : {
245 110743920 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe)
246 : {
247 9874585 : if (probe->binfo == chk->binfo &&
248 7812616 : probe->decl == chk->decl &&
249 976760 : probe->diag_decl == chk->diag_decl)
250 975820 : goto found;
251 : }
252 : /* Insert into parent's checks. */
253 100869335 : vec_safe_push (ptr->deferred_access_checks, *chk);
254 101845155 : found:;
255 : }
256 : }
257 : }
258 9142731795 : }
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 418676560 : enforce_access (tree basetype_path, tree decl, tree diag_decl,
334 : tsubst_flags_t complain, access_failure_info *afi = NULL)
335 : {
336 418676560 : gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
337 :
338 418676560 : if (flag_new_inheriting_ctors
339 528967203 : && 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 62274 : decl = strip_inheriting_ctors (decl);
345 62274 : basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl),
346 : ba_any, NULL, complain);
347 : }
348 :
349 418676560 : tree cs = current_scope ();
350 418676560 : if (in_template_context
351 418676560 : && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
352 41916967 : 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 41672866 : 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 377003694 : if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true))
382 : {
383 22127 : if (flag_new_inheriting_ctors)
384 22097 : diag_decl = strip_inheriting_ctors (diag_decl);
385 22127 : if (complain & tf_error)
386 : {
387 1153 : 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 1153 : 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 1153 : 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 1153 : 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 1153 : complain_about_access (decl, diag_decl, diag_location, true,
413 : access_failure_reason);
414 : }
415 22127 : if (afi)
416 412 : afi->record_access_failure (basetype_path, decl, diag_decl);
417 22127 : 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 1095857068 : perform_access_checks (vec<deferred_access_check, va_gc> *checks,
431 : tsubst_flags_t complain)
432 : {
433 1095857068 : int i;
434 1095857068 : deferred_access_check *chk;
435 1095857068 : location_t loc = input_location;
436 1095857068 : bool ok = true;
437 :
438 1095857068 : if (!checks)
439 : return true;
440 :
441 127525817 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
442 : {
443 70994246 : input_location = chk->loc;
444 70994246 : ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain);
445 : }
446 :
447 56531571 : input_location = loc;
448 56531571 : 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 286394233 : perform_deferred_access_checks (tsubst_flags_t complain)
469 : {
470 286394233 : 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 623865929 : perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
480 : tsubst_flags_t complain,
481 : access_failure_info *afi)
482 : {
483 623865929 : int i;
484 623865929 : deferred_access *ptr;
485 623865929 : deferred_access_check *chk;
486 :
487 : /* Exit if we are in a context that no access checking is performed. */
488 623865929 : if (deferred_access_no_check)
489 : return true;
490 :
491 598336407 : gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
492 :
493 598336407 : ptr = &deferred_access_stack->last ();
494 :
495 : /* If we are not supposed to defer access checks, just check now. */
496 598336407 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
497 : {
498 347682314 : bool ok = enforce_access (binfo, decl, diag_decl, complain, afi);
499 527433521 : return (complain & tf_error) ? true : ok;
500 : }
501 :
502 : /* See if we are already going to perform this check. */
503 305122189 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk)
504 : {
505 71497126 : if (chk->decl == decl && chk->binfo == binfo &&
506 17030109 : chk->diag_decl == diag_decl)
507 : {
508 : return true;
509 : }
510 : }
511 : /* If not, record the check. */
512 233625063 : deferred_access_check new_access = {binfo, decl, diag_decl, input_location};
513 233625063 : vec_safe_push (ptr->deferred_access_checks, new_access);
514 :
515 233625063 : 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 1505941689 : stmts_are_full_exprs_p (void)
524 : {
525 1505941689 : 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 1299844264 : add_stmt (tree t)
534 : {
535 1299844264 : enum tree_code code = TREE_CODE (t);
536 :
537 1299844264 : if (EXPR_P (t) && code != LABEL_EXPR)
538 : {
539 1249732277 : if (!EXPR_HAS_LOCATION (t))
540 199879068 : 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 1249732277 : if (STATEMENT_CODE_P (TREE_CODE (t)))
545 325231407 : STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
546 : }
547 :
548 1299844264 : if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
549 5793113 : 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 1299844264 : gcc_checking_assert (!stmt_list_stack->is_empty ());
554 1299844264 : append_to_statement_list_force (t, &cur_stmt_list);
555 :
556 1299844264 : return t;
557 : }
558 :
559 : /* Returns the stmt_tree to which statements are currently being added. */
560 :
561 : stmt_tree
562 7700865240 : current_stmt_tree (void)
563 : {
564 7700865240 : return (cfun
565 7662444198 : ? &cfun->language->base.x_stmt_tree
566 7700865240 : : &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 323047 : maybe_cleanup_point_expr (tree expr)
573 : {
574 323047 : if (!processing_template_decl && stmts_are_full_exprs_p ())
575 309614 : expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
576 323047 : 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 322347003 : maybe_cleanup_point_expr_void (tree expr)
586 : {
587 322347003 : if (!processing_template_decl && stmts_are_full_exprs_p ())
588 108110287 : expr = fold_build_cleanup_point_expr (void_type_node, expr);
589 322347003 : return expr;
590 : }
591 :
592 :
593 :
594 : /* Create a declaration statement for the declaration given by the DECL. */
595 :
596 : void
597 109085430 : add_decl_expr (tree decl)
598 : {
599 109085430 : tree r = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
600 109085430 : if (DECL_INITIAL (decl)
601 109085430 : || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
602 19568499 : r = maybe_cleanup_point_expr_void (r);
603 109085430 : add_stmt (r);
604 109085430 : }
605 :
606 : /* Set EXPR_LOCATION on one cleanup T to LOC. */
607 :
608 : static void
609 5791454 : set_one_cleanup_loc (tree t, location_t loc)
610 : {
611 5791454 : if (!t)
612 : return;
613 :
614 5791454 : if (TREE_CODE (t) != POSTCONDITION_STMT)
615 5791454 : 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 5791454 : if (TREE_CODE (t) == NOP_EXPR
622 0 : && TREE_TYPE (t) == void_type_node
623 5791454 : && 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 1226940434 : set_cleanup_locs (tree stmts, location_t loc)
631 : {
632 1232731888 : if (TREE_CODE (stmts) == CLEANUP_STMT)
633 : {
634 5791454 : set_one_cleanup_loc (CLEANUP_EXPR (stmts), loc);
635 5791454 : set_cleanup_locs (CLEANUP_BODY (stmts), loc);
636 : }
637 1226940434 : else if (TREE_CODE (stmts) == STATEMENT_LIST)
638 1090935846 : for (tree stmt : tsi_range (stmts))
639 844690189 : set_cleanup_locs (stmt, loc);
640 1226940434 : }
641 :
642 : /* True iff the innermost block scope is a try block. */
643 :
644 : static bool
645 382250245 : at_try_scope ()
646 : {
647 382250245 : cp_binding_level *b = current_binding_level;
648 382250575 : while (b && b->kind == sk_cleanup)
649 330 : b = b->level_chain;
650 382250245 : return b && b->kind == sk_try;
651 : }
652 :
653 : /* Finish a scope. */
654 :
655 : tree
656 382250245 : do_poplevel (tree stmt_list)
657 : {
658 382250245 : tree block = NULL;
659 :
660 382250245 : bool was_try = at_try_scope ();
661 :
662 382250245 : if (stmts_are_full_exprs_p ())
663 382187674 : block = poplevel (kept_level_p (), 1, 0);
664 :
665 : /* This needs to come after poplevel merges sk_cleanup statement_lists. */
666 382250245 : maybe_splice_retval_cleanup (stmt_list, was_try);
667 :
668 382250245 : stmt_list = pop_stmt_list (stmt_list);
669 :
670 : /* input_location is the last token of the scope, usually a }. */
671 382250245 : set_cleanup_locs (stmt_list, input_location);
672 :
673 382250245 : if (!processing_template_decl)
674 : {
675 117523066 : stmt_list = c_build_bind_expr (input_location, block, stmt_list);
676 : /* ??? See c_end_compound_stmt re statement expressions. */
677 : }
678 :
679 382250245 : return stmt_list;
680 : }
681 :
682 : /* Begin a new scope. */
683 :
684 : tree
685 382212760 : do_pushlevel (scope_kind sk)
686 : {
687 382212760 : tree ret = push_stmt_list ();
688 382212760 : if (stmts_are_full_exprs_p ())
689 382187728 : begin_scope (sk, NULL);
690 382212760 : 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 5791350 : push_cleanup (tree decl, tree cleanup, bool eh_only)
700 : {
701 5791350 : tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
702 5791350 : CLEANUP_EH_ONLY (stmt) = eh_only;
703 5791350 : add_stmt (stmt);
704 5791350 : CLEANUP_BODY (stmt) = push_stmt_list ();
705 5791350 : }
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 18291573 : begin_maybe_infinite_loop (tree cond)
716 : {
717 : /* Only track this while parsing a function, not during instantiation. */
718 18291573 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
719 2683850 : && !processing_template_decl))
720 : return;
721 15607225 : bool maybe_infinite = true;
722 15607225 : if (cond)
723 : {
724 15300709 : cond = fold_non_dependent_expr (cond);
725 15300709 : maybe_infinite = integer_nonzerop (cond);
726 : }
727 30907934 : vec_safe_push (cp_function_chain->infinite_loops,
728 15607225 : 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 1515837 : break_maybe_infinite_loop (void)
736 : {
737 1515837 : if (!cfun)
738 : return;
739 1515837 : 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 18291573 : end_maybe_infinite_loop (tree cond)
747 : {
748 18291573 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
749 2683850 : && !processing_template_decl))
750 : return;
751 15607225 : tree current = cp_function_chain->infinite_loops->pop();
752 15607225 : if (current != NULL_TREE)
753 : {
754 5041609 : cond = fold_non_dependent_expr (cond);
755 5041609 : if (integer_nonzerop (cond))
756 311736 : 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 88222439 : begin_cond (tree *cond_p)
767 : {
768 88222439 : if (processing_template_decl)
769 62533160 : *cond_p = push_stmt_list ();
770 88222439 : }
771 :
772 : /* Finish such a conditional. */
773 :
774 : static void
775 88222439 : finish_cond (tree *cond_p, tree expr)
776 : {
777 88222439 : if (processing_template_decl)
778 : {
779 62533160 : tree cond = pop_stmt_list (*cond_p);
780 :
781 62533160 : if (expr == NULL_TREE)
782 : /* Empty condition in 'for'. */
783 285908 : gcc_assert (empty_expr_stmt_p (cond));
784 62247252 : else if (check_for_bare_parameter_packs (expr))
785 0 : expr = error_mark_node;
786 62247252 : else if (!empty_expr_stmt_p (cond))
787 925733 : expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
788 : }
789 88222439 : *cond_p = expr;
790 88222439 : }
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 12319071 : adjust_loop_decl_cond (tree *body_p, tree *prep_p, tree *cleanup_p)
809 : {
810 12319071 : if (!TREE_SIDE_EFFECTS (*body_p))
811 12309389 : return;
812 :
813 9682 : gcc_assert (!processing_template_decl);
814 9682 : *prep_p = *body_p;
815 9682 : 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 9682 : current_binding_level->keep = true;
840 9682 : 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 9682 : if (tsi_end_p (iter))
847 91 : *body_p = NULL_TREE;
848 : else
849 9591 : *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 9682 : finish_loop_cond_prep (tree *body_p, tree *prep_p, tree cleanup)
862 : {
863 9682 : *prep_p = do_poplevel (*prep_p);
864 9682 : gcc_assert (TREE_CODE (*prep_p) == BIND_EXPR);
865 9682 : 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 9664 : tree stmt_list = BIND_EXPR_BODY (*prep_p);
872 9664 : gcc_assert (TREE_CODE (stmt_list) == STATEMENT_LIST);
873 9664 : 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 9573 : tree_stmt_iterator iter = tsi_start (stmt_list);
893 9805 : while (tsi_stmt (iter) != *body_p)
894 232 : tsi_next (&iter);
895 9573 : *body_p = tsi_split_stmt_list (input_location, iter);
896 : }
897 :
898 : /* Finish a goto-statement. */
899 :
900 : tree
901 2716 : finish_goto_stmt (tree destination)
902 : {
903 2716 : if (identifier_p (destination))
904 2579 : 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 2716 : if (TREE_CODE (destination) == LABEL_DECL)
909 2579 : 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 2707 : add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
926 :
927 2707 : tree stmt = build_stmt (input_location, GOTO_EXPR, destination);
928 2707 : check_goto (&TREE_OPERAND (stmt, 0));
929 :
930 2707 : return add_stmt (stmt);
931 : }
932 :
933 : /* Returns true if T corresponds to an assignment operator expression. */
934 :
935 : static bool
936 876504 : is_assignment_op_expr_p (tree t)
937 : {
938 876504 : if (t == NULL_TREE)
939 : return false;
940 :
941 876504 : if (TREE_CODE (t) == MODIFY_EXPR
942 876504 : || (TREE_CODE (t) == MODOP_EXPR
943 336 : && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR))
944 : return true;
945 :
946 875817 : tree call = extract_call_expr (t);
947 875817 : if (call == NULL_TREE
948 129548 : || call == error_mark_node
949 1005365 : || !CALL_EXPR_OPERATOR_SYNTAX (call))
950 : return false;
951 :
952 4658 : tree fndecl = cp_get_callee_fndecl_nofold (call);
953 4658 : return fndecl != NULL_TREE
954 4560 : && DECL_ASSIGNMENT_OPERATOR_P (fndecl)
955 4709 : && 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 91003832 : maybe_warn_unparenthesized_assignment (tree t, bool nested_p,
1019 : tsubst_flags_t complain)
1020 : {
1021 91003832 : tree type = TREE_TYPE (t);
1022 91003832 : t = STRIP_REFERENCE_REF (t);
1023 :
1024 91003832 : if ((complain & tf_warning)
1025 90943298 : && warn_parentheses
1026 876504 : && 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 91004179 : && (!nested_p
1032 176 : || (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 91003832 : }
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 53688816 : annotate_saver::annotate_saver (tree *cond) : m_annotations (nullptr)
1072 : {
1073 53688816 : tree *t = cond;
1074 53699078 : while (TREE_CODE (*t) == ANNOTATE_EXPR)
1075 10262 : t = &TREE_OPERAND (*t, 0);
1076 :
1077 53688816 : if (t != cond)
1078 : {
1079 10259 : m_annotations = *cond;
1080 10259 : *cond = *t;
1081 10259 : m_inner = t;
1082 : }
1083 53688816 : }
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 53688816 : annotate_saver::restore (tree new_inner)
1092 : {
1093 53688816 : 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 10259 : 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 10259 : *m_inner = new_inner;
1118 10259 : 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 93204840 : maybe_convert_cond (tree cond)
1127 : {
1128 : /* Empty conditions remain empty. */
1129 93204840 : if (!cond)
1130 : return NULL_TREE;
1131 :
1132 : /* Wait until we instantiate templates before doing conversion. */
1133 92839466 : if (type_dependent_expression_p (cond))
1134 39150650 : return cond;
1135 :
1136 : /* Strip any ANNOTATE_EXPRs from COND. */
1137 53688816 : 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,element} case. cp_finish_decomp saved the conversion
1142 : result in a TARGET_EXPR, pick it up from there. */
1143 372794 : if (DECL_DECOMPOSITION_P (cond)
1144 225 : && DECL_DECOMP_IS_BASE (cond)
1145 225 : && DECL_DECOMP_BASE (cond)
1146 53689038 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1147 56 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1148 :
1149 53688816 : if (warn_sequence_point && !processing_template_decl)
1150 326679 : verify_sequence_points (cond);
1151 :
1152 53688816 : maybe_warn_unparenthesized_assignment (cond, /*nested_p=*/false,
1153 : tf_warning_or_error);
1154 :
1155 : /* Do the conversion. */
1156 53688816 : cond = convert_from_reference (cond);
1157 53688816 : cond = condition_conversion (cond);
1158 :
1159 : /* Restore any ANNOTATE_EXPRs around COND. */
1160 53688816 : return annotations.restore (cond);
1161 : }
1162 :
1163 : /* Finish an expression-statement, whose EXPRESSION is as indicated. */
1164 :
1165 : tree
1166 165421000 : finish_expr_stmt (tree expr)
1167 : {
1168 165421000 : tree r = NULL_TREE;
1169 165421000 : location_t loc = EXPR_LOCATION (expr);
1170 :
1171 165235571 : if (expr != NULL_TREE)
1172 : {
1173 : /* If we ran into a problem, make sure we complained. */
1174 165420839 : gcc_assert (expr != error_mark_node || seen_error ());
1175 :
1176 165420839 : if (!processing_template_decl)
1177 : {
1178 60110155 : if (warn_sequence_point)
1179 812444 : verify_sequence_points (expr);
1180 60110155 : expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1181 : }
1182 105310684 : else if (!type_dependent_expression_p (expr))
1183 22830735 : convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1184 :
1185 165420836 : 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 165420836 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
1192 : {
1193 165420657 : if (TREE_CODE (expr) != EXPR_STMT
1194 162933477 : && !STATEMENT_CLASS_P (expr)
1195 162929326 : && TREE_CODE (expr) != STATEMENT_LIST)
1196 162783964 : expr = build_stmt (loc, EXPR_STMT, expr);
1197 165420657 : expr = maybe_cleanup_point_expr_void (expr);
1198 : }
1199 :
1200 165420836 : r = add_stmt (expr);
1201 : }
1202 :
1203 165420997 : return r;
1204 : }
1205 :
1206 :
1207 : /* Begin an if-statement. Returns a newly created IF_STMT if
1208 : appropriate. */
1209 :
1210 : tree
1211 75186213 : begin_if_stmt (void)
1212 : {
1213 75186213 : tree r, scope;
1214 75186213 : scope = do_pushlevel (sk_cond);
1215 75186213 : r = build_stmt (input_location, IF_STMT, NULL_TREE,
1216 : NULL_TREE, NULL_TREE, scope);
1217 75186213 : current_binding_level->this_entity = r;
1218 75186213 : begin_cond (&IF_COND (r));
1219 75186213 : 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 252669 : is_std_constant_evaluated_p (tree fn)
1227 : {
1228 : /* std::is_constant_evaluated takes no arguments. */
1229 252669 : if (call_expr_nargs (fn) != 0)
1230 : return false;
1231 :
1232 90216 : tree fndecl = cp_get_callee_fndecl_nofold (fn);
1233 90216 : if (fndecl == NULL_TREE)
1234 : return false;
1235 :
1236 28281 : if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
1237 : BUILT_IN_FRONTEND))
1238 : return true;
1239 :
1240 28252 : if (!decl_in_std_namespace_p (fndecl))
1241 : return false;
1242 :
1243 12913 : tree name = DECL_NAME (fndecl);
1244 12913 : 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 4685110 : find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
1252 : {
1253 4685110 : tree t = *tp;
1254 :
1255 4685110 : if (TYPE_P (t) || TREE_CONSTANT (t))
1256 : {
1257 830190 : *walk_subtrees = false;
1258 830190 : return NULL_TREE;
1259 : }
1260 :
1261 3854920 : switch (TREE_CODE (t))
1262 : {
1263 252669 : case CALL_EXPR:
1264 252669 : 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 75271844 : maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if,
1284 : bool trivial_infinite)
1285 : {
1286 75271844 : if (!warn_tautological_compare)
1287 : return;
1288 :
1289 : /* Suppress warning for std::is_constant_evaluated if the conditional
1290 : comes from a macro. */
1291 1431004 : if (from_macro_expansion_at (EXPR_LOCATION (cond)))
1292 : return;
1293 :
1294 603974 : cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r,
1295 : NULL);
1296 603974 : if (cond)
1297 : {
1298 2390 : 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 2356 : 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 2348 : 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 4620 : 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 75186213 : finish_if_stmt_cond (tree orig_cond, tree if_stmt)
1330 : {
1331 75186213 : tree cond = maybe_convert_cond (orig_cond);
1332 75186213 : maybe_warn_for_constant_evaluated (cond, IF_STMT_CONSTEXPR_P (if_stmt),
1333 : /*trivial_infinite=*/false);
1334 75186213 : if (IF_STMT_CONSTEXPR_P (if_stmt)
1335 15887951 : && !type_dependent_expression_p (cond)
1336 10877957 : && require_constant_expression (cond)
1337 10877926 : && !instantiation_dependent_expression_p (cond)
1338 : /* Wait until instantiation time, since only then COND has been
1339 : converted to bool. */
1340 81172763 : && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
1341 : {
1342 5986550 : cond = instantiate_non_dependent_expr (cond);
1343 5986550 : cond = cxx_constant_value (cond);
1344 : }
1345 69199663 : else if (processing_template_decl)
1346 51936178 : cond = orig_cond;
1347 75186213 : finish_cond (&IF_COND (if_stmt), cond);
1348 75186213 : add_stmt (if_stmt);
1349 75186213 : THEN_CLAUSE (if_stmt) = push_stmt_list ();
1350 75186213 : 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 75178441 : finish_then_clause (tree if_stmt)
1358 : {
1359 75178441 : THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
1360 75178441 : return if_stmt;
1361 : }
1362 :
1363 : /* Begin the else-clause of an if-statement. */
1364 :
1365 : void
1366 28123344 : begin_else_clause (tree if_stmt)
1367 : {
1368 28123344 : ELSE_CLAUSE (if_stmt) = push_stmt_list ();
1369 28123344 : }
1370 :
1371 : /* Finish the else-clause of an if-statement, which may be given by
1372 : IF_STMT. */
1373 :
1374 : void
1375 28123306 : finish_else_clause (tree if_stmt)
1376 : {
1377 28123306 : ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
1378 28123306 : }
1379 :
1380 : /* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as
1381 : read. */
1382 :
1383 : static tree
1384 853767776 : maybe_mark_exp_read_r (tree *tp, int *, void *)
1385 : {
1386 853767776 : tree t = *tp;
1387 853767776 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
1388 49580307 : mark_exp_read (t);
1389 853767776 : return NULL_TREE;
1390 : }
1391 :
1392 : /* Finish an if-statement. */
1393 :
1394 : void
1395 75178441 : finish_if_stmt (tree if_stmt)
1396 : {
1397 75178441 : tree scope = IF_SCOPE (if_stmt);
1398 75178441 : IF_SCOPE (if_stmt) = NULL;
1399 75178441 : 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 15880179 : cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt),
1405 : maybe_mark_exp_read_r, NULL);
1406 15880179 : cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt),
1407 : maybe_mark_exp_read_r, NULL);
1408 : }
1409 75178441 : add_stmt (do_poplevel (scope));
1410 75178441 : }
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 17649962 : finish_loop_cond (tree *condp, tree body)
1421 : {
1422 17649962 : if (TREE_CODE (*condp) == INTEGER_CST)
1423 : return;
1424 12673888 : bool trivially_empty = expr_first (body) == NULL_TREE;
1425 12673888 : bool trivial_infinite = false;
1426 12673888 : if (trivially_empty)
1427 : {
1428 98651 : tree c = fold_non_dependent_expr (*condp, tf_none,
1429 : /*manifestly_const_eval=*/true);
1430 98651 : trivial_infinite = c && integer_nonzerop (c);
1431 : }
1432 12673888 : if (warn_tautological_compare)
1433 : {
1434 85833 : tree cond = *condp;
1435 86200 : while (TREE_CODE (cond) == ANNOTATE_EXPR)
1436 367 : cond = TREE_OPERAND (cond, 0);
1437 85833 : if (trivial_infinite
1438 85897 : && !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1439 64 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1440 : /*trivial_infinite=*/true);
1441 85769 : else if (!trivially_empty
1442 375 : || !processing_template_decl
1443 86173 : || DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1444 85567 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1445 : /*trivial_infinite=*/false);
1446 : }
1447 12673888 : 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 4821461 : begin_while_stmt (void)
1459 : {
1460 4821461 : tree r;
1461 4821461 : r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1462 : NULL_TREE, NULL_TREE);
1463 4821461 : add_stmt (r);
1464 4821461 : WHILE_BODY (r) = do_pushlevel (sk_block);
1465 4821461 : begin_cond (&WHILE_COND (r));
1466 4821461 : return r;
1467 : }
1468 :
1469 : /* Process the COND of a while-statement, which may be given by
1470 : WHILE_STMT. */
1471 :
1472 : void
1473 4821461 : finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
1474 : tree unroll, bool novector)
1475 : {
1476 4821461 : cond = maybe_convert_cond (cond);
1477 4821461 : finish_cond (&WHILE_COND (while_stmt), cond);
1478 4821461 : begin_maybe_infinite_loop (cond);
1479 4821461 : 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 4821461 : if (unroll && cond != error_mark_node)
1487 27188 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1488 13594 : TREE_TYPE (WHILE_COND (while_stmt)),
1489 13594 : WHILE_COND (while_stmt),
1490 : build_int_cst (integer_type_node,
1491 : annot_expr_unroll_kind),
1492 : unroll);
1493 4821461 : 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 4821461 : adjust_loop_decl_cond (&WHILE_BODY (while_stmt),
1501 : &WHILE_COND_PREP (while_stmt),
1502 : &WHILE_COND_CLEANUP (while_stmt));
1503 4821461 : }
1504 :
1505 : /* Finish a while-statement, which may be given by WHILE_STMT. */
1506 :
1507 : void
1508 4821461 : finish_while_stmt (tree while_stmt)
1509 : {
1510 4821461 : end_maybe_infinite_loop (boolean_true_node);
1511 4821461 : if (WHILE_COND_PREP (while_stmt))
1512 9508 : finish_loop_cond_prep (&WHILE_BODY (while_stmt),
1513 : &WHILE_COND_PREP (while_stmt),
1514 9508 : WHILE_COND_CLEANUP (while_stmt));
1515 : else
1516 4811953 : WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
1517 4821461 : finish_loop_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
1518 4821461 : }
1519 :
1520 : /* Begin a do-statement. Returns a newly created DO_STMT if
1521 : appropriate. */
1522 :
1523 : tree
1524 5696265 : begin_do_stmt (void)
1525 : {
1526 5696265 : tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE,
1527 : NULL_TREE);
1528 5696265 : begin_maybe_infinite_loop (boolean_true_node);
1529 5696265 : add_stmt (r);
1530 5696265 : DO_BODY (r) = push_stmt_list ();
1531 5696265 : return r;
1532 : }
1533 :
1534 : /* Finish the body of a do-statement, which may be given by DO_STMT. */
1535 :
1536 : void
1537 5696265 : finish_do_body (tree do_stmt)
1538 : {
1539 5696265 : tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
1540 :
1541 5696265 : if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body))
1542 537190 : body = STATEMENT_LIST_TAIL (body)->stmt;
1543 :
1544 5696265 : if (IS_EMPTY_STMT (body))
1545 30 : warning (OPT_Wempty_body,
1546 : "suggest explicit braces around empty body in %<do%> statement");
1547 5696265 : }
1548 :
1549 : /* Finish a do-statement, which may be given by DO_STMT, and whose
1550 : COND is as indicated. */
1551 :
1552 : void
1553 5696265 : finish_do_stmt (tree cond, tree do_stmt, bool ivdep, tree unroll,
1554 : bool novector)
1555 : {
1556 5696265 : cond = maybe_convert_cond (cond);
1557 5696265 : 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 5696265 : if (check_for_bare_parameter_packs (cond))
1562 3 : cond = error_mark_node;
1563 5696265 : 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 5696265 : 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 5696265 : 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 5696265 : DO_COND (do_stmt) = cond;
1576 5696265 : tree do_body = DO_BODY (do_stmt);
1577 5696235 : if (CONVERT_EXPR_P (do_body)
1578 30 : && integer_zerop (TREE_OPERAND (do_body, 0))
1579 5696295 : && VOID_TYPE_P (TREE_TYPE (do_body)))
1580 : do_body = NULL_TREE;
1581 5696265 : finish_loop_cond (&DO_COND (do_stmt), do_body);
1582 5696265 : }
1583 :
1584 : /* Finish a return-statement. The EXPRESSION returned, if any, is as
1585 : indicated. */
1586 :
1587 : tree
1588 130257016 : finish_return_stmt (tree expr)
1589 : {
1590 130257016 : tree r;
1591 130257016 : bool no_warning;
1592 130257016 : bool dangling;
1593 :
1594 130257016 : expr = check_return_expr (expr, &no_warning, &dangling);
1595 :
1596 130257016 : if (error_operand_p (expr)
1597 130257016 : || (flag_openmp && !check_omp_return ()))
1598 : {
1599 : /* Suppress -Wreturn-type for this function. */
1600 1347 : if (warn_return_type)
1601 1341 : suppress_warning (current_function_decl, OPT_Wreturn_type);
1602 1347 : return error_mark_node;
1603 : }
1604 :
1605 130255669 : if (!processing_template_decl)
1606 : {
1607 45693833 : if (warn_sequence_point)
1608 1023833 : verify_sequence_points (expr);
1609 : }
1610 :
1611 130255669 : r = build_stmt (input_location, RETURN_EXPR, expr);
1612 130255669 : RETURN_EXPR_LOCAL_ADDR_P (r) = dangling;
1613 130255669 : if (no_warning)
1614 33 : suppress_warning (r, OPT_Wreturn_type);
1615 130255669 : r = maybe_cleanup_point_expr_void (r);
1616 130255669 : r = add_stmt (r);
1617 :
1618 130255669 : 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 7773847 : begin_for_scope (tree *init)
1627 : {
1628 7773847 : tree scope = do_pushlevel (sk_for);
1629 :
1630 7773847 : if (processing_template_decl)
1631 6173735 : *init = push_stmt_list ();
1632 : else
1633 1600112 : *init = NULL_TREE;
1634 :
1635 7773847 : 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 7497610 : begin_for_stmt (tree scope, tree init)
1644 : {
1645 7497610 : tree r;
1646 :
1647 7497610 : 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 7497610 : if (scope == NULL_TREE)
1652 : {
1653 1355901 : gcc_assert (!init);
1654 1355901 : scope = begin_for_scope (&init);
1655 : }
1656 :
1657 7497610 : FOR_INIT_STMT (r) = init;
1658 7497610 : FOR_SCOPE (r) = scope;
1659 :
1660 7497610 : 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 7497610 : finish_init_stmt (tree for_stmt)
1668 : {
1669 7497610 : if (processing_template_decl)
1670 5897498 : FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
1671 7497610 : add_stmt (for_stmt);
1672 7497610 : FOR_BODY (for_stmt) = do_pushlevel (sk_block);
1673 7497610 : begin_cond (&FOR_COND (for_stmt));
1674 7497610 : }
1675 :
1676 : /* Finish the COND of a for-statement, which may be given by
1677 : FOR_STMT. */
1678 :
1679 : void
1680 7497610 : finish_for_cond (tree cond, tree for_stmt, bool ivdep, tree unroll,
1681 : bool novector)
1682 : {
1683 7497610 : cond = maybe_convert_cond (cond);
1684 7497610 : finish_cond (&FOR_COND (for_stmt), cond);
1685 7497610 : begin_maybe_infinite_loop (cond);
1686 7497610 : 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 7497610 : 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 7497610 : 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 7497610 : adjust_loop_decl_cond (&FOR_BODY (for_stmt), &FOR_COND_PREP (for_stmt),
1708 : &FOR_COND_CLEANUP (for_stmt));
1709 7497610 : }
1710 :
1711 : /* Finish the increment-EXPRESSION in a for-statement, which may be
1712 : given by FOR_STMT. */
1713 :
1714 : void
1715 7485148 : finish_for_expr (tree expr, tree for_stmt)
1716 : {
1717 7485148 : 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 7031181 : if (type_unknown_p (expr))
1722 : {
1723 6 : cxx_incomplete_type_error (expr, TREE_TYPE (expr));
1724 6 : expr = error_mark_node;
1725 : }
1726 7031181 : if (!processing_template_decl)
1727 : {
1728 1526863 : if (warn_sequence_point)
1729 14959 : verify_sequence_points (expr);
1730 1526863 : expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
1731 : tf_warning_or_error);
1732 : }
1733 5504318 : else if (!type_dependent_expression_p (expr))
1734 1963859 : convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error);
1735 7031181 : expr = maybe_cleanup_point_expr_void (expr);
1736 7031181 : if (check_for_bare_parameter_packs (expr))
1737 0 : expr = error_mark_node;
1738 7031181 : 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 7773960 : find_range_for_decls (tree range_for_decl[3])
1749 : {
1750 7773960 : 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 31095840 : for (int i = 0; i < 3; i++)
1756 : {
1757 23321880 : tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i];
1758 23321880 : if (IDENTIFIER_BINDING (id)
1759 23321880 : && IDENTIFIER_BINDING (id)->scope == current_binding_level)
1760 : {
1761 274297 : range_for_decl[i] = IDENTIFIER_BINDING (id)->value;
1762 274297 : gcc_assert (VAR_P (range_for_decl[i])
1763 : && DECL_ARTIFICIAL (range_for_decl[i]));
1764 : }
1765 : }
1766 7773960 : }
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 7773847 : finish_for_stmt (tree for_stmt)
1775 : {
1776 7773847 : end_maybe_infinite_loop (boolean_true_node);
1777 :
1778 7773847 : if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
1779 276237 : RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
1780 : else
1781 : {
1782 7497610 : 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 7497436 : FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
1788 7497610 : if (FOR_COND (for_stmt))
1789 7132236 : finish_loop_cond (&FOR_COND (for_stmt),
1790 7132236 : FOR_EXPR (for_stmt) ? integer_one_node
1791 141469 : : FOR_BODY (for_stmt));
1792 : }
1793 :
1794 : /* Pop the scope for the body of the loop. */
1795 7773847 : tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
1796 7773847 : ? &RANGE_FOR_SCOPE (for_stmt)
1797 7497610 : : &FOR_SCOPE (for_stmt));
1798 7773847 : tree scope = *scope_ptr;
1799 7773847 : *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 7773847 : tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
1806 7773847 : find_range_for_decls (range_for_decl);
1807 :
1808 7773847 : 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 7773847 : if (!stmts_are_full_exprs_p ())
1813 12462 : return;
1814 :
1815 31045540 : for (int i = 0; i < 3; i++)
1816 23284155 : if (range_for_decl[i])
1817 274181 : DECL_NAME (range_for_decl[i])
1818 274181 : = 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 276237 : begin_range_for_stmt (tree scope, tree init)
1828 : {
1829 276237 : begin_maybe_infinite_loop (boolean_false_node);
1830 :
1831 276237 : tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE,
1832 : NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
1833 :
1834 276237 : if (scope == NULL_TREE)
1835 : {
1836 506 : gcc_assert (!init);
1837 506 : scope = begin_for_scope (&init);
1838 : }
1839 :
1840 : /* Since C++20, RANGE_FOR_STMTs can use the init tree, so save it. */
1841 276237 : RANGE_FOR_INIT_STMT (r) = init;
1842 276237 : RANGE_FOR_SCOPE (r) = scope;
1843 :
1844 276237 : 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 276237 : finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
1853 : {
1854 276237 : if (processing_template_decl)
1855 552474 : RANGE_FOR_INIT_STMT (range_for_stmt)
1856 552474 : = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt));
1857 276237 : RANGE_FOR_DECL (range_for_stmt) = decl;
1858 276237 : RANGE_FOR_EXPR (range_for_stmt) = expr;
1859 276237 : add_stmt (range_for_stmt);
1860 276237 : RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
1861 276237 : }
1862 :
1863 : /* Begin the scope of an expansion-statement. */
1864 :
1865 : tree
1866 2318 : begin_template_for_scope (tree *init)
1867 : {
1868 2318 : tree scope = do_pushlevel (sk_template_for);
1869 :
1870 2318 : if (processing_template_decl)
1871 547 : *init = push_stmt_list ();
1872 : else
1873 1771 : *init = NULL_TREE;
1874 :
1875 2318 : return scope;
1876 : }
1877 :
1878 : /* Finish a break-statement. */
1879 :
1880 : tree
1881 4820165 : 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 4820165 : if (!block_may_fallthru (cur_stmt_list))
1891 714 : return void_node;
1892 4819451 : note_break_stmt ();
1893 4819451 : return add_stmt (build_stmt (input_location, BREAK_STMT, NULL_TREE));
1894 : }
1895 :
1896 : /* Finish a continue-statement. */
1897 :
1898 : tree
1899 230903 : finish_continue_stmt (void)
1900 : {
1901 230903 : 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 717155 : begin_switch_stmt (void)
1909 : {
1910 717155 : tree r, scope;
1911 :
1912 717155 : scope = do_pushlevel (sk_cond);
1913 717155 : r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1914 : scope, NULL_TREE);
1915 :
1916 717155 : begin_cond (&SWITCH_STMT_COND (r));
1917 :
1918 717155 : return r;
1919 : }
1920 :
1921 : /* Finish the cond of a switch-statement. */
1922 :
1923 : void
1924 717155 : finish_switch_cond (tree cond, tree switch_stmt)
1925 : {
1926 717155 : tree orig_type = NULL;
1927 :
1928 717155 : if (!processing_template_decl)
1929 : {
1930 : /* Convert the condition to an integer or enumeration type. */
1931 294244 : 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,element} 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 294298 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == TARGET_EXPR)
1940 18 : cond = TARGET_EXPR_SLOT (DECL_DECOMP_BASE (cond));
1941 294244 : cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
1942 294244 : 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 294244 : orig_type = unlowered_expr_type (cond);
1950 294244 : if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
1951 205758 : orig_type = TREE_TYPE (cond);
1952 294244 : if (cond != error_mark_node)
1953 : {
1954 : /* [stmt.switch]
1955 :
1956 : Integral promotions are performed. */
1957 294211 : cond = perform_integral_promotions (cond);
1958 294211 : cond = maybe_cleanup_point_expr (cond);
1959 : }
1960 : }
1961 717155 : if (check_for_bare_parameter_packs (cond))
1962 0 : cond = error_mark_node;
1963 717155 : else if (!processing_template_decl && warn_sequence_point)
1964 2797 : verify_sequence_points (cond);
1965 :
1966 717155 : finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
1967 717155 : SWITCH_STMT_TYPE (switch_stmt) = orig_type;
1968 717155 : add_stmt (switch_stmt);
1969 717155 : push_switch (switch_stmt);
1970 717155 : SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
1971 717155 : }
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 717155 : finish_switch_stmt (tree switch_stmt)
1978 : {
1979 717155 : tree scope;
1980 :
1981 1434310 : SWITCH_STMT_BODY (switch_stmt) =
1982 717155 : pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
1983 717155 : pop_switch ();
1984 :
1985 717155 : scope = SWITCH_STMT_SCOPE (switch_stmt);
1986 717155 : SWITCH_STMT_SCOPE (switch_stmt) = NULL;
1987 717155 : add_stmt (do_poplevel (scope));
1988 717155 : }
1989 :
1990 : /* Begin a try-block. Returns a newly-created TRY_BLOCK if
1991 : appropriate. */
1992 :
1993 : tree
1994 1171453 : begin_try_block (void)
1995 : {
1996 1171453 : tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
1997 1171453 : add_stmt (r);
1998 1171453 : TRY_STMTS (r) = push_stmt_list ();
1999 1171453 : 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 2196 : begin_function_try_block (tree *compound_stmt)
2008 : {
2009 2196 : 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 2196 : *compound_stmt = begin_compound_stmt (0);
2013 2196 : current_binding_level->artificial = 1;
2014 2196 : r = begin_try_block ();
2015 2196 : FN_TRY_BLOCK_P (r) = 1;
2016 2196 : return r;
2017 : }
2018 :
2019 : /* Finish a try-block, which may be given by TRY_BLOCK. */
2020 :
2021 : void
2022 1171453 : finish_try_block (tree try_block)
2023 : {
2024 1171453 : TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
2025 1171453 : TRY_HANDLERS (try_block) = push_stmt_list ();
2026 1171453 : }
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 2196 : finish_function_try_block (tree try_block)
2051 : {
2052 2196 : finish_try_block (try_block);
2053 : /* FIXME : something queer about CTOR_INITIALIZER somehow following
2054 : the try block, but moving it inside. */
2055 2196 : in_function_try_handler = 1;
2056 2196 : }
2057 :
2058 : /* Finish a handler-sequence for a try-block, which may be given by
2059 : TRY_BLOCK. */
2060 :
2061 : void
2062 1171453 : finish_handler_sequence (tree try_block)
2063 : {
2064 1171453 : TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
2065 1171453 : check_handlers (TRY_HANDLERS (try_block));
2066 1171453 : }
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 2196 : finish_function_handler_sequence (tree try_block, tree compound_stmt)
2074 : {
2075 2196 : in_function_try_handler = 0;
2076 2196 : finish_handler_sequence (try_block);
2077 2196 : finish_compound_stmt (compound_stmt);
2078 2196 : }
2079 :
2080 : /* Begin a handler. Returns a HANDLER if appropriate. */
2081 :
2082 : tree
2083 1630562 : begin_handler (void)
2084 : {
2085 1630562 : tree r;
2086 :
2087 1630562 : r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
2088 1630562 : add_stmt (r);
2089 :
2090 : /* Create a binding level for the eh_info and the exception object
2091 : cleanup. */
2092 1630562 : HANDLER_BODY (r) = do_pushlevel (sk_catch);
2093 :
2094 1630562 : 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 1630562 : finish_handler_parms (tree decl, tree handler)
2103 : {
2104 1630562 : tree type = NULL_TREE;
2105 1630562 : if (processing_template_decl)
2106 : {
2107 1486802 : if (decl)
2108 : {
2109 482489 : decl = pushdecl (decl);
2110 482489 : decl = push_template_decl (decl);
2111 482489 : HANDLER_PARMS (handler) = decl;
2112 482489 : type = TREE_TYPE (decl);
2113 : }
2114 : }
2115 : else
2116 : {
2117 143760 : type = expand_start_catch_block (decl);
2118 143760 : if (warn_catch_value
2119 2116 : && type != NULL_TREE
2120 711 : && type != error_mark_node
2121 144471 : && !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 1630562 : HANDLER_TYPE (handler) = type;
2143 1630562 : }
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 1630562 : finish_handler (tree handler)
2150 : {
2151 1630562 : if (!processing_template_decl)
2152 143760 : expand_end_catch_block ();
2153 1630562 : HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
2154 1630562 : }
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 289754502 : begin_compound_stmt (unsigned int flags)
2165 : {
2166 289754502 : tree r;
2167 :
2168 289754502 : if (flags & BCS_NO_SCOPE)
2169 : {
2170 5515645 : r = push_stmt_list ();
2171 5515645 : 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 5515645 : keep_next_level (false);
2178 : }
2179 : else
2180 : {
2181 284238857 : scope_kind sk = sk_block;
2182 284238857 : if (flags & BCS_TRY_BLOCK)
2183 : sk = sk_try;
2184 283067595 : else if (flags & BCS_TRANSACTION)
2185 : sk = sk_transaction;
2186 283067360 : else if (flags & BCS_STMT_EXPR)
2187 29088 : sk = sk_stmt_expr;
2188 284238857 : 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 289754502 : if (processing_template_decl)
2198 : {
2199 194251273 : r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
2200 194251273 : BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
2201 194251273 : BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
2202 194251273 : TREE_SIDE_EFFECTS (r) = 1;
2203 : }
2204 :
2205 289754502 : return r;
2206 : }
2207 :
2208 : /* Finish a compound-statement, which is given by STMT. */
2209 :
2210 : void
2211 289754463 : finish_compound_stmt (tree stmt)
2212 : {
2213 289754463 : if (TREE_CODE (stmt) == BIND_EXPR)
2214 : {
2215 194251273 : 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 194251273 : if (TREE_CODE (body) == STATEMENT_LIST
2220 176652216 : && STATEMENT_LIST_HEAD (body) == NULL
2221 11806571 : && !BIND_EXPR_BODY_BLOCK (stmt)
2222 205543317 : && !BIND_EXPR_TRY_BLOCK (stmt))
2223 : stmt = body;
2224 : else
2225 182959326 : BIND_EXPR_BODY (stmt) = body;
2226 : }
2227 95503190 : else if (STATEMENT_LIST_NO_SCOPE (stmt))
2228 5478106 : stmt = pop_stmt_list (stmt);
2229 : else
2230 : {
2231 : /* Destroy any ObjC "super" receivers that may have been
2232 : created. */
2233 90025084 : objc_clear_super_receiver ();
2234 :
2235 90025084 : stmt = do_poplevel (stmt);
2236 : }
2237 :
2238 : /* ??? See c_end_compound_stmt wrt statement expressions. */
2239 289754463 : add_stmt (stmt);
2240 289754463 : }
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 56453 : finish_asm_string_expression (location_t loc, tree string)
2248 : {
2249 56453 : if (string == error_mark_node
2250 56440 : || 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 32356 : 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 32356 : tree r;
2277 32356 : tree t;
2278 32356 : int ninputs = list_length (input_operands);
2279 32356 : int noutputs = list_length (output_operands);
2280 :
2281 32356 : if (!processing_template_decl)
2282 : {
2283 12890 : const char *constraint;
2284 12890 : const char **oconstraints;
2285 12890 : bool allows_mem, allows_reg, is_inout;
2286 12890 : tree operand;
2287 12890 : int i;
2288 :
2289 12890 : oconstraints = XALLOCAVEC (const char *, noutputs);
2290 :
2291 25678 : string = finish_asm_string_expression (cp_expr_loc_or_loc (string, loc),
2292 : string);
2293 12890 : if (string == error_mark_node)
2294 109 : return error_mark_node;
2295 38388 : for (int i = 0; i < 2; ++i)
2296 88730 : for (t = i ? input_operands : output_operands; t; t = TREE_CHAIN (t))
2297 : {
2298 37546 : tree s = TREE_VALUE (TREE_PURPOSE (t));
2299 75074 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2300 37546 : if (s == error_mark_node)
2301 : return error_mark_node;
2302 37516 : TREE_VALUE (TREE_PURPOSE (t)) = s;
2303 : }
2304 18198 : for (t = clobbers; t; t = TREE_CHAIN (t))
2305 : {
2306 5417 : tree s = TREE_VALUE (t);
2307 10828 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2308 5417 : TREE_VALUE (t) = s;
2309 : }
2310 :
2311 12781 : string = resolve_asm_operand_names (string, output_operands,
2312 : input_operands, labels);
2313 :
2314 32432 : for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
2315 : {
2316 19651 : 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 19651 : STRIP_NOPS (operand);
2325 :
2326 19651 : operand = mark_lvalue_use (operand);
2327 :
2328 19651 : if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
2329 9 : operand = error_mark_node;
2330 :
2331 19651 : if (operand != error_mark_node
2332 19651 : && (TREE_READONLY (operand)
2333 19636 : || CP_TYPE_CONST_P (TREE_TYPE (operand))
2334 : /* Functions are not modifiable, even though they are
2335 : lvalues. */
2336 19636 : || 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 19636 : || (CLASS_TYPE_P (TREE_TYPE (operand))
2340 426 : && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
2341 6 : cxx_readonly_error (loc, operand, lv_asm);
2342 :
2343 : tree *op = &operand;
2344 19658 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2345 7 : op = &TREE_OPERAND (*op, 1);
2346 19651 : 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 19651 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2359 19651 : oconstraints[i] = constraint;
2360 :
2361 19651 : 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 19642 : if (!allows_reg && !cxx_mark_addressable (*op))
2368 0 : operand = error_mark_node;
2369 19642 : 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 812 : 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 19630 : 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 19651 : TREE_VALUE (t) = operand;
2415 : }
2416 :
2417 30641 : for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
2418 : {
2419 17860 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2420 17860 : bool constraint_parsed
2421 17860 : = 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 17860 : if (constraint_parsed && !allows_reg && allows_mem)
2427 718 : operand = mark_lvalue_use (TREE_VALUE (t));
2428 : else
2429 17142 : 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 17860 : 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 17860 : if (constraint_parsed)
2444 : {
2445 : /* If the operand is going to end up in memory,
2446 : mark it addressable. */
2447 17839 : 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 718 : STRIP_NOPS (operand);
2452 :
2453 718 : tree *op = &operand;
2454 725 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2455 7 : op = &TREE_OPERAND (*op, 1);
2456 718 : 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 718 : if (!cxx_mark_addressable (*op))
2469 0 : operand = error_mark_node;
2470 : }
2471 17121 : else if (!allows_reg && !allows_mem)
2472 : {
2473 : /* If constraint allows neither register nor memory,
2474 : try harder to get a constant. */
2475 465 : tree constop = maybe_constant_value (operand);
2476 465 : if (TREE_CONSTANT (constop))
2477 438 : operand = constop;
2478 : }
2479 17839 : 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 17839 : 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 17860 : 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 17743 : 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 17860 : TREE_VALUE (t) = operand;
2551 : }
2552 : }
2553 :
2554 32247 : r = build_stmt (loc, ASM_EXPR, string,
2555 : output_operands, input_operands,
2556 : clobbers, labels);
2557 32247 : ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
2558 32247 : ASM_INLINE_P (r) = inline_p;
2559 32247 : if (toplev_p)
2560 : {
2561 99 : symtab->finalize_toplevel_asm (r);
2562 99 : return r;
2563 : }
2564 32148 : r = maybe_cleanup_point_expr_void (r);
2565 32148 : return add_stmt (r);
2566 : }
2567 :
2568 : /* Finish a label with the indicated NAME. Returns the new label. */
2569 :
2570 : tree
2571 2491 : finish_label_stmt (tree name)
2572 : {
2573 2491 : tree decl = define_label (input_location, name);
2574 :
2575 2491 : if (decl == error_mark_node)
2576 : return error_mark_node;
2577 :
2578 2485 : add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
2579 :
2580 2485 : 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 3535857 : finish_decl_cleanup (tree decl, tree cleanup)
2603 : {
2604 3535857 : push_cleanup (decl, cleanup, false);
2605 3535857 : }
2606 :
2607 : /* If the current scope exits with an exception, run CLEANUP. */
2608 :
2609 : void
2610 2245706 : finish_eh_cleanup (tree cleanup)
2611 : {
2612 2245706 : push_cleanup (NULL, cleanup, true);
2613 2245706 : }
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 20693275 : 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 20693275 : mem_inits = nreverse (mem_inits);
2625 :
2626 20693275 : if (processing_template_decl)
2627 : {
2628 : tree mem;
2629 :
2630 34980261 : 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 20692650 : if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
2638 20692650 : && check_for_bare_parameter_packs (TREE_VALUE (mem)))
2639 3 : TREE_VALUE (mem) = error_mark_node;
2640 : }
2641 :
2642 14287611 : add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
2643 : CTOR_INITIALIZER, mem_inits));
2644 : }
2645 : else
2646 6405664 : emit_mem_initializers (mem_inits);
2647 20693275 : }
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 45483029 : force_paren_expr (tree expr, bool even_uneval /* = false */)
2655 : {
2656 : /* This is only needed for decltype(auto) in C++14. */
2657 45483029 : 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 44860070 : if (cp_unevaluated_operand && !even_uneval)
2663 : return expr;
2664 :
2665 37286320 : if (TREE_CODE (expr) == COMPONENT_REF
2666 37228342 : || TREE_CODE (expr) == SCOPE_REF
2667 74507921 : || REFERENCE_REF_P (expr))
2668 603755 : REF_PARENTHESIZED_P (expr) = true;
2669 36682565 : else if (DECL_P (tree_strip_any_location_wrapper (expr)))
2670 : {
2671 1751685 : location_t loc = cp_expr_location (expr);
2672 1751685 : const tree_code code = processing_template_decl ? PAREN_EXPR
2673 : : VIEW_CONVERT_EXPR;
2674 1751685 : expr = build1_loc (loc, code, TREE_TYPE (expr), expr);
2675 1751685 : 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 1006273553 : maybe_undo_parenthesized_ref (tree t)
2686 : {
2687 1006273553 : if (cxx_dialect < cxx14)
2688 : return t;
2689 :
2690 996481552 : if ((TREE_CODE (t) == PAREN_EXPR || TREE_CODE (t) == VIEW_CONVERT_EXPR)
2691 1104695548 : && REF_PARENTHESIZED_P (t))
2692 201648 : t = TREE_OPERAND (t, 0);
2693 :
2694 : return t;
2695 : }
2696 :
2697 : /* Finish a parenthesized expression EXPR. */
2698 :
2699 : cp_expr
2700 33872717 : finish_parenthesized_expr (cp_expr expr)
2701 : {
2702 33872717 : if (EXPR_P (expr))
2703 : {
2704 : /* This inhibits warnings in maybe_warn_unparenthesized_assignment
2705 : and c_common_truthvalue_conversion. */
2706 67338463 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wparentheses);
2707 : /* And maybe_warn_sizeof_array_div. */
2708 67338463 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wsizeof_array_div);
2709 : }
2710 :
2711 33872717 : if (TREE_CODE (expr) == OFFSET_REF
2712 33872717 : || 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 31181 : PTRMEM_OK_P (expr) = 0;
2716 :
2717 33872717 : tree stripped_expr = tree_strip_any_location_wrapper (expr);
2718 33872717 : if (TREE_CODE (stripped_expr) == STRING_CST)
2719 876730 : PAREN_STRING_LITERAL_P (stripped_expr) = 1;
2720 32995987 : else if (TREE_CODE (stripped_expr) == PACK_INDEX_EXPR)
2721 1448 : PACK_INDEX_PARENTHESIZED_P (stripped_expr) = true;
2722 :
2723 33872717 : expr = cp_expr (force_paren_expr (expr), expr.get_location ());
2724 :
2725 33872717 : 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 78318062 : finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
2733 : tsubst_flags_t complain /* = tf_warning_or_error */)
2734 : {
2735 78318062 : gcc_assert (TREE_CODE (decl) == FIELD_DECL);
2736 78318062 : bool try_omp_private = !object && omp_private_member_map;
2737 68147846 : tree ret;
2738 :
2739 68147846 : if (!object)
2740 : {
2741 68147846 : tree scope = qualifying_scope;
2742 68147846 : if (scope == NULL_TREE)
2743 : {
2744 68136344 : scope = context_for_name_lookup (decl);
2745 68136344 : 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 68147843 : object = maybe_dummy_object (scope, NULL);
2753 : }
2754 :
2755 78318059 : object = maybe_resolve_dummy (object, true);
2756 78318059 : 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 78318056 : if (is_dummy_object (object)
2762 35815 : && !cp_unevaluated_operand
2763 78318162 : && (!processing_template_decl || !current_class_ref))
2764 : {
2765 91 : if (complain & tf_error)
2766 : {
2767 74 : auto_diagnostic_group d;
2768 74 : if (current_function_decl
2769 74 : && DECL_STATIC_FUNCTION_P (current_function_decl))
2770 3 : error ("invalid use of member %qD in static member function", decl);
2771 71 : else if (current_function_decl
2772 63 : && processing_contract_condition
2773 71 : && DECL_CONSTRUCTOR_P (current_function_decl))
2774 0 : error ("invalid use of member %qD in constructor %<pre%> contract", decl);
2775 71 : else if (current_function_decl
2776 63 : && processing_contract_condition
2777 71 : && DECL_DESTRUCTOR_P (current_function_decl))
2778 0 : error ("invalid use of member %qD in destructor %<post%> contract", decl);
2779 : else
2780 71 : error ("invalid use of non-static data member %qD", decl);
2781 74 : inform (DECL_SOURCE_LOCATION (decl), "declared here");
2782 74 : }
2783 :
2784 91 : return error_mark_node;
2785 : }
2786 :
2787 78317965 : if (current_class_ptr)
2788 77991180 : TREE_USED (current_class_ptr) = 1;
2789 78317965 : if (processing_template_decl)
2790 : {
2791 62370773 : tree type = TREE_TYPE (decl);
2792 :
2793 62370773 : if (TYPE_REF_P (type))
2794 : /* Quals on the object don't matter. */;
2795 60026684 : else if (PACK_EXPANSION_P (type))
2796 : /* Don't bother trying to represent this. */
2797 : type = NULL_TREE;
2798 60023692 : 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 60019214 : int quals = cp_type_quals (TREE_TYPE (object));
2812 :
2813 60019214 : if (DECL_MUTABLE_P (decl))
2814 240101 : quals &= ~TYPE_QUAL_CONST;
2815 :
2816 60019214 : quals |= cp_type_quals (TREE_TYPE (decl));
2817 60019214 : type = cp_build_qualified_type (type, quals);
2818 : }
2819 :
2820 62370773 : if (qualifying_scope)
2821 : /* Wrap this in a SCOPE_REF for now. */
2822 9434 : ret = build_qualified_name (type, qualifying_scope, decl,
2823 : /*template_p=*/false);
2824 : else
2825 62361339 : ret = (convert_from_reference
2826 62361339 : (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 15947192 : tree access_type = TREE_TYPE (object);
2833 :
2834 15947192 : 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 15947192 : if (qualifying_scope)
2841 : {
2842 2021 : tree binfo = NULL_TREE;
2843 2021 : object = build_scoped_ref (object, qualifying_scope,
2844 : &binfo);
2845 : }
2846 :
2847 15947192 : ret = build_class_member_access_expr (object, decl,
2848 : /*access_path=*/NULL_TREE,
2849 : /*preserve_reference=*/false,
2850 : complain);
2851 : }
2852 78317965 : 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 4906617695 : 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 4906617695 : if (deferred_access_no_check)
2876 : return true;
2877 :
2878 : /* Determine the SCOPE of DECL. */
2879 4895549550 : tree scope = context_for_name_lookup (decl);
2880 : /* If the SCOPE is not a type, then DECL is not a member. */
2881 4895549550 : 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 4895549550 : || dependent_type_p (scope))
2886 4426878990 : return true;
2887 :
2888 468670560 : tree qualifying_type = NULL_TREE;
2889 : /* Compute the scope through which DECL is being accessed. */
2890 468670560 : 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 99613 : && CLASS_TYPE_P (object_type)
2900 468770156 : && 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 99587 : if (tree open = currently_open_class (object_type))
2905 : qualifying_type = open;
2906 : else
2907 : qualifying_type = object_type;
2908 : }
2909 468570973 : 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 622756677 : if (DECL_NONSTATIC_MEMBER_P (decl)
2915 311430035 : && current_class_ptr)
2916 41015 : if (tree current = current_nonlambda_class_type ())
2917 : {
2918 40992 : 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 3592 : 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 157192633 : qualifying_type = currently_open_derived_class (scope);
2938 :
2939 468571505 : 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 468633160 : && CLASS_TYPE_P (qualifying_type))
2943 441491573 : return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
2944 441491573 : 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 84013365 : 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 84013365 : gcc_assert (TYPE_P (qualifying_class));
2967 :
2968 84013365 : if (error_operand_p (expr))
2969 21 : return error_mark_node;
2970 :
2971 84013344 : if (DECL_P (expr)
2972 : /* Functions are marked after overload resolution; avoid redundant
2973 : warnings. */
2974 76823073 : && TREE_CODE (expr) != FUNCTION_DECL
2975 160836393 : && !mark_used (expr, complain))
2976 0 : return error_mark_node;
2977 :
2978 84013344 : if (template_p)
2979 : {
2980 268410 : 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 268401 : 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 84013344 : if (address_p && done
2994 161986 : && TREE_CODE (qualifying_class) != ENUMERAL_TYPE)
2995 : {
2996 161984 : if (TREE_CODE (expr) == SCOPE_REF)
2997 0 : expr = TREE_OPERAND (expr, 1);
2998 161984 : expr = build_offset_ref (qualifying_class, expr,
2999 : /*address_p=*/true, complain);
3000 161984 : return expr;
3001 : }
3002 :
3003 : /* No need to check access within an enum. */
3004 83851360 : if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE
3005 3577122 : && 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 80274241 : 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 80271577 : else if (TREE_CODE (expr) == FIELD_DECL)
3015 : {
3016 11502 : push_deferring_access_checks (dk_no_check);
3017 11502 : expr = finish_non_static_data_member (expr, NULL_TREE,
3018 : qualifying_class, complain);
3019 11502 : pop_deferring_access_checks ();
3020 : }
3021 80260075 : 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 6707442 : if (!shared_member_p (expr)
3026 444251 : && current_class_ptr
3027 7151006 : && DERIVED_FROM_P (qualifying_class,
3028 : current_nonlambda_class_type ()))
3029 443250 : expr = (build_class_member_access_expr
3030 443250 : (maybe_dummy_object (qualifying_class, NULL),
3031 : expr,
3032 443250 : BASELINK_ACCESS_BINFO (expr),
3033 : /*preserve_reference=*/false,
3034 : complain));
3035 6264192 : else if (done)
3036 : /* The expression is a qualified name whose address is not
3037 : being taken. */
3038 3543 : expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
3039 : complain);
3040 : }
3041 73552633 : else if (!template_p
3042 73341011 : && TREE_CODE (expr) == TEMPLATE_DECL
3043 73552716 : && !DECL_FUNCTION_TEMPLATE_P (expr))
3044 : {
3045 83 : if (complain & tf_error)
3046 5 : error ("%qE missing template arguments", expr);
3047 83 : 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 73552550 : if (processing_template_decl
3057 73552550 : && (!currently_open_class (qualifying_class)
3058 10544 : || TREE_CODE (expr) == IDENTIFIER_NODE
3059 10544 : || TREE_CODE (expr) == TEMPLATE_ID_EXPR
3060 82 : || TREE_CODE (expr) == BIT_NOT_EXPR))
3061 10934794 : expr = build_qualified_name (TREE_TYPE (expr),
3062 : qualifying_class, expr,
3063 : template_p);
3064 62617756 : else if (tree wrap = maybe_get_tls_wrapper_call (expr))
3065 9 : expr = wrap;
3066 :
3067 73552550 : 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 5537343 : begin_stmt_expr (void)
3078 : {
3079 5537343 : 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 29069 : finish_stmt_expr_expr (tree expr, tree stmt_expr)
3089 : {
3090 29069 : 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 29066 : if (expr)
3101 : {
3102 29051 : tree type = TREE_TYPE (expr);
3103 :
3104 29051 : 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 29036 : 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 28867 : 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 28836 : expr = force_rvalue (expr, tf_warning_or_error);
3131 28836 : if (error_operand_p (expr))
3132 0 : return error_mark_node;
3133 :
3134 : /* Update for array-to-pointer decay. */
3135 28836 : type = TREE_TYPE (expr);
3136 :
3137 : /* This TARGET_EXPR will initialize the outer one added by
3138 : finish_stmt_expr. */
3139 28836 : 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 28836 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
3145 28836 : expr = maybe_cleanup_point_expr (expr);
3146 28836 : add_stmt (expr);
3147 : }
3148 :
3149 : /* The type of the statement-expression is the type of the last
3150 : expression. */
3151 29036 : 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 5537343 : finish_stmt_expr (tree stmt_expr, bool has_no_scope)
3163 : {
3164 5537343 : tree type;
3165 5537343 : tree result;
3166 :
3167 5537343 : if (error_operand_p (stmt_expr))
3168 : {
3169 18 : pop_stmt_list (stmt_expr);
3170 18 : return error_mark_node;
3171 : }
3172 :
3173 5537325 : gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
3174 :
3175 5537325 : type = TREE_TYPE (stmt_expr);
3176 5537325 : result = pop_stmt_list (stmt_expr);
3177 5537325 : TREE_TYPE (result) = type;
3178 :
3179 5537325 : if (processing_template_decl)
3180 : {
3181 37732 : result = build_min (STMT_EXPR, type, result);
3182 37732 : TREE_SIDE_EFFECTS (result) = 1;
3183 37732 : STMT_EXPR_NO_SCOPE (result) = has_no_scope;
3184 : }
3185 5499593 : 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 62533332 : empty_expr_stmt_p (tree expr_stmt)
3221 : {
3222 62533337 : tree body = NULL_TREE;
3223 :
3224 62533337 : if (expr_stmt == void_node)
3225 : return true;
3226 :
3227 62533334 : if (expr_stmt)
3228 : {
3229 62533334 : if (TREE_CODE (expr_stmt) == EXPR_STMT)
3230 5 : body = EXPR_STMT_EXPR (expr_stmt);
3231 62533329 : else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
3232 : body = expr_stmt;
3233 : }
3234 :
3235 5 : if (body)
3236 : {
3237 61607465 : if (TREE_CODE (body) == STATEMENT_LIST)
3238 61607460 : 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 19006424 : perform_koenig_lookup (cp_expr fn_expr, vec<tree, va_gc> *args,
3251 : tsubst_flags_t complain)
3252 : {
3253 19006424 : tree identifier = NULL_TREE;
3254 19006424 : tree functions = NULL_TREE;
3255 19006424 : tree tmpl_args = NULL_TREE;
3256 19006424 : bool template_id = false;
3257 19006424 : location_t loc = fn_expr.get_location ();
3258 19006424 : tree fn = fn_expr.get_value ();
3259 :
3260 19006424 : STRIP_ANY_LOCATION_WRAPPER (fn);
3261 :
3262 19006424 : if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
3263 : {
3264 : /* Use a separate flag to handle null args. */
3265 3642788 : template_id = true;
3266 3642788 : tmpl_args = TREE_OPERAND (fn, 1);
3267 3642788 : fn = TREE_OPERAND (fn, 0);
3268 : }
3269 :
3270 : /* Find the name of the overloaded function. */
3271 19006424 : if (identifier_p (fn))
3272 : identifier = fn;
3273 : else
3274 : {
3275 26866336 : functions = fn;
3276 18808308 : 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 19006424 : if (!any_type_dependent_arguments_p (args)
3284 19006424 : && !any_dependent_template_arguments_p (tmpl_args))
3285 : {
3286 18146001 : fn = lookup_arg_dependent (identifier, functions, args);
3287 18146001 : if (!fn)
3288 : {
3289 : /* The unqualified name could not be resolved. */
3290 58839 : if (complain & tf_error)
3291 391 : fn = unqualified_fn_lookup_error (cp_expr (identifier, loc));
3292 : else
3293 : fn = identifier;
3294 : }
3295 : }
3296 :
3297 19006424 : if (fn && template_id && fn != error_mark_node)
3298 3642775 : fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
3299 :
3300 19006424 : 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 369199846 : finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
3316 : bool koenig_p, tsubst_flags_t complain)
3317 : {
3318 369199846 : tree result;
3319 369199846 : tree orig_fn;
3320 369199846 : vec<tree, va_gc> *orig_args = *args;
3321 369199846 : tsubst_flags_t orig_complain = complain;
3322 :
3323 369199846 : if (fn == error_mark_node)
3324 : return error_mark_node;
3325 :
3326 369198787 : complain &= ~tf_any_viable;
3327 369198787 : 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 369198787 : fn = maybe_undo_parenthesized_ref (fn);
3332 :
3333 369198787 : STRIP_ANY_LOCATION_WRAPPER (fn);
3334 :
3335 369198787 : orig_fn = fn;
3336 :
3337 369198787 : 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 369198781 : 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 238047519 : if (is_overloaded_fn (fn))
3349 : {
3350 145873276 : tree ifn = get_first_fn (fn);
3351 145873276 : if (TREE_CODE (ifn) == FUNCTION_DECL
3352 145873276 : && dependent_local_decl_p (ifn))
3353 40502 : 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 238047519 : if (type_dependent_expression_p (fn)
3360 238047519 : || any_type_dependent_arguments_p (*args))
3361 : {
3362 216417215 : if (koenig_p
3363 10587192 : && TREE_CODE (orig_fn) == FUNCTION_DECL
3364 219747100 : && !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 858093 : orig_fn = ovl_make (orig_fn, NULL_TREE);
3370 216417215 : result = build_min_nt_call_vec (orig_fn, *args);
3371 294279669 : SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
3372 216417215 : 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 216417215 : suppress_warning (result, OPT_Wpessimizing_move);
3377 :
3378 216417215 : if (cfun && cp_function_chain && !cp_unevaluated_operand)
3379 : {
3380 188510054 : bool abnormal = true;
3381 188784679 : for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter)
3382 : {
3383 104608724 : tree fndecl = STRIP_TEMPLATE (*iter);
3384 104608724 : if (TREE_CODE (fndecl) != FUNCTION_DECL
3385 104608646 : || !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 188510054 : if (abnormal)
3397 84175955 : current_function_returns_abnormally = 1;
3398 : }
3399 216417215 : if (TREE_CODE (fn) == COMPONENT_REF)
3400 100087558 : maybe_generic_this_capture (TREE_OPERAND (fn, 0),
3401 100087558 : TREE_OPERAND (fn, 1));
3402 216417215 : return result;
3403 : }
3404 21630304 : orig_args = make_tree_vector_copy (*args);
3405 : }
3406 :
3407 152781566 : if (TREE_CODE (fn) == COMPONENT_REF)
3408 : {
3409 29011519 : tree member = TREE_OPERAND (fn, 1);
3410 29011519 : if (BASELINK_P (member))
3411 : {
3412 28823601 : tree object = TREE_OPERAND (fn, 0);
3413 57241916 : 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 28823601 : complain);
3420 : }
3421 : }
3422 :
3423 : /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */
3424 123957965 : if (TREE_CODE (fn) == ADDR_EXPR
3425 123957965 : && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
3426 9 : fn = TREE_OPERAND (fn, 0);
3427 :
3428 123957965 : if (is_overloaded_fn (fn))
3429 115250760 : fn = baselink_for_fns (fn);
3430 :
3431 123957965 : result = NULL_TREE;
3432 123957965 : if (BASELINK_P (fn))
3433 : {
3434 14129040 : 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 14129040 : 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 14129001 : object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
3464 : NULL);
3465 :
3466 16128607 : 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 109828925 : else if (is_overloaded_fn (fn))
3474 : {
3475 : /* If the function is an overloaded builtin, resolve it. */
3476 101121720 : if (TREE_CODE (fn) == FUNCTION_DECL
3477 101121720 : && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3478 18779520 : || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
3479 9462015 : result = resolve_overloaded_builtin (input_location, fn, *args,
3480 : complain & tf_error);
3481 :
3482 9462015 : if (!result)
3483 : {
3484 100778422 : tree alloc_size_attr = NULL_TREE;
3485 100778422 : if (warn_calloc_transposed_args
3486 711608 : && TREE_CODE (fn) == FUNCTION_DECL
3487 100778422 : && (alloc_size_attr
3488 430720 : = lookup_attribute ("alloc_size",
3489 430720 : TYPE_ATTRIBUTES (TREE_TYPE (fn)))))
3490 3401 : if (TREE_VALUE (alloc_size_attr) == NULL_TREE
3491 3401 : || TREE_CHAIN (TREE_VALUE (alloc_size_attr)) == NULL_TREE)
3492 : alloc_size_attr = NULL_TREE;
3493 99063457 : if ((warn_sizeof_pointer_memaccess || alloc_size_attr)
3494 1715025 : && (complain & tf_warning)
3495 1494370 : && !vec_safe_is_empty (*args)
3496 101928784 : && !processing_template_decl)
3497 : {
3498 : location_t sizeof_arg_loc[6];
3499 : tree sizeof_arg[6];
3500 : unsigned int i;
3501 8254388 : for (i = 0; i < (alloc_size_attr ? 6 : 3); i++)
3502 : {
3503 3095598 : tree t;
3504 :
3505 3095598 : sizeof_arg_loc[i] = UNKNOWN_LOCATION;
3506 3095598 : sizeof_arg[i] = NULL_TREE;
3507 3095598 : if (i >= (*args)->length ())
3508 652878 : continue;
3509 2442720 : t = (**args)[i];
3510 2442720 : if (TREE_CODE (t) != SIZEOF_EXPR)
3511 2436063 : continue;
3512 6657 : if (SIZEOF_EXPR_TYPE_P (t))
3513 2663 : sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
3514 : else
3515 3994 : sizeof_arg[i] = TREE_OPERAND (t, 0);
3516 6657 : sizeof_arg_loc[i] = EXPR_LOCATION (t);
3517 : }
3518 1031806 : if (warn_sizeof_pointer_memaccess)
3519 : {
3520 1031746 : auto same_p = same_type_ignoring_top_level_qualifiers_p;
3521 1031746 : sizeof_pointer_memaccess_warning (sizeof_arg_loc, fn, *args,
3522 : sizeof_arg, same_p);
3523 : }
3524 1031806 : if (alloc_size_attr)
3525 60 : warn_for_calloc (sizeof_arg_loc, fn, *args, sizeof_arg,
3526 : alloc_size_attr);
3527 : }
3528 :
3529 100778422 : if ((complain & tf_warning)
3530 55552544 : && TREE_CODE (fn) == FUNCTION_DECL
3531 26529049 : && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
3532 140545 : && vec_safe_length (*args) == 3
3533 100918967 : && !any_type_dependent_arguments_p (*args))
3534 : {
3535 140545 : tree arg0 = (*orig_args)[0];
3536 140545 : tree arg1 = (*orig_args)[1];
3537 140545 : tree arg2 = (*orig_args)[2];
3538 140545 : int literal_mask = ((literal_integer_zerop (arg1) << 1)
3539 140545 : | (literal_integer_zerop (arg2) << 2));
3540 140545 : warn_for_memset (input_location, arg0, arg2, literal_mask);
3541 : }
3542 :
3543 : /* A call to a namespace-scope function. */
3544 100778422 : result = build_new_function_call (fn, args, orig_complain);
3545 : }
3546 : }
3547 8707205 : else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
3548 : {
3549 158941 : 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 158941 : tree ob = TREE_OPERAND (fn, 0);
3556 158941 : if (obvalue_p (ob))
3557 158923 : 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 8548264 : 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 2580747 : result = build_op_call (fn, args, complain);
3566 :
3567 117633632 : if (!result)
3568 : /* A call where the function is unknown. */
3569 5967517 : result = cp_build_function_call_vec (fn, args, complain);
3570 :
3571 123944447 : if (processing_template_decl && result != error_mark_node)
3572 : {
3573 16554751 : if (INDIRECT_REF_P (result))
3574 1132235 : 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 16554751 : if (TREE_CODE (result) == CALL_EXPR
3579 16545075 : && really_overloaded_fn (orig_fn))
3580 : {
3581 6100730 : tree sel_fn = CALL_EXPR_FN (result);
3582 6100730 : if (TREE_CODE (sel_fn) == COMPONENT_REF)
3583 : {
3584 : /* The non-dependent result of build_new_method_call. */
3585 259172 : sel_fn = TREE_OPERAND (sel_fn, 1);
3586 259172 : gcc_assert (BASELINK_P (sel_fn));
3587 : }
3588 5841558 : 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 5841558 : sel_fn = TREE_OPERAND (sel_fn, 0);
3592 : orig_fn = sel_fn;
3593 : }
3594 :
3595 16554751 : tree r = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
3596 16554751 : SET_EXPR_LOCATION (r, input_location);
3597 16554751 : KOENIG_LOOKUP_P (r) = koenig_p;
3598 16554751 : TREE_NO_WARNING (r) = TREE_NO_WARNING (result);
3599 16554751 : release_tree_vector (orig_args);
3600 16554751 : 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 2656564 : 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 2656564 : location_t combined_loc = make_location (input_location,
3620 : expr.get_start (),
3621 : get_finish (input_location));
3622 2656564 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3623 2656564 : NULL_TREE, tf_warning_or_error);
3624 : /* TODO: build_x_unary_op doesn't honor the location, so set it here. */
3625 2656564 : result.set_location (combined_loc);
3626 2656564 : return result;
3627 : }
3628 :
3629 : /* Finish a use of `this'. Returns an expression for `this'. */
3630 :
3631 : tree
3632 36350743 : finish_this_expr (void)
3633 : {
3634 36350743 : tree result = NULL_TREE;
3635 :
3636 72701362 : if (current_class_ref && !LAMBDA_TYPE_P (TREE_TYPE (current_class_ref)))
3637 36052480 : result = current_class_ptr;
3638 596510 : else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
3639 298187 : result = (lambda_expr_this_capture
3640 298187 : (CLASSTYPE_LAMBDA_EXPR (current_class_type), /*add*/true));
3641 : else
3642 76 : gcc_checking_assert (!current_class_ptr);
3643 :
3644 36350667 : if (result)
3645 : /* The keyword 'this' is a prvalue expression. */
3646 36350664 : return rvalue (result);
3647 :
3648 79 : tree fn = current_nonlambda_function ();
3649 79 : if (fn && DECL_XOBJ_MEMBER_FUNCTION_P (fn))
3650 : {
3651 6 : auto_diagnostic_group d;
3652 6 : error ("%<this%> is unavailable for explicit object member "
3653 : "functions");
3654 6 : tree xobj_parm = DECL_ARGUMENTS (fn);
3655 6 : gcc_assert (xobj_parm);
3656 6 : tree parm_name = DECL_NAME (xobj_parm);
3657 :
3658 6 : static tree remembered_fn = NULL_TREE;
3659 : /* Only output this diagnostic once per function. */
3660 6 : if (remembered_fn == fn)
3661 : /* Early escape. */;
3662 6 : else if (parm_name)
3663 6 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3664 : "use explicit object parameter %qs instead",
3665 3 : IDENTIFIER_POINTER (parm_name));
3666 : else
3667 3 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3668 : "name the explicit object parameter");
3669 :
3670 6 : remembered_fn = fn;
3671 6 : }
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 79 : 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 158992 : finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
3692 : location_t loc, tsubst_flags_t complain)
3693 : {
3694 158992 : if (object == error_mark_node || destructor == error_mark_node)
3695 : return error_mark_node;
3696 :
3697 158983 : gcc_assert (TYPE_P (destructor));
3698 :
3699 158983 : if (!processing_template_decl)
3700 : {
3701 158962 : 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 158962 : if (is_auto (destructor))
3708 3 : destructor = TREE_TYPE (object);
3709 158962 : 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 158959 : 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 158968 : tree type = (type_dependent_expression_p (object)
3742 158968 : ? NULL_TREE : void_type_node);
3743 :
3744 158968 : return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
3745 158968 : scope, destructor);
3746 : }
3747 :
3748 : /* Finish an expression of the form CODE EXPR. */
3749 :
3750 : cp_expr
3751 38782991 : 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 38782991 : location_t combined_loc = make_location (op_loc,
3760 : op_loc, expr.get_finish ());
3761 38782991 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3762 38782991 : NULL_TREE, complain);
3763 : /* TODO: build_x_unary_op doesn't always honor the location. */
3764 38782991 : result.set_location (combined_loc);
3765 :
3766 38782991 : if (result == error_mark_node)
3767 : return result;
3768 :
3769 38782488 : 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 38782488 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
3775 : return result;
3776 :
3777 20934694 : tree result_ovl = result;
3778 20934694 : tree expr_ovl = expr;
3779 :
3780 20934694 : if (!processing_template_decl)
3781 1839167 : expr_ovl = cp_fully_fold (expr_ovl);
3782 :
3783 20934694 : if (!CONSTANT_CLASS_P (expr_ovl)
3784 20934694 : || TREE_OVERFLOW_P (expr_ovl))
3785 : return result;
3786 :
3787 255618 : if (!processing_template_decl)
3788 246247 : result_ovl = cp_fully_fold (result_ovl);
3789 :
3790 255618 : 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 9868135 : finish_compound_literal (tree type, tree compound_literal,
3818 : tsubst_flags_t complain,
3819 : fcl_t fcl_context)
3820 : {
3821 9868135 : if (type == error_mark_node)
3822 : return error_mark_node;
3823 :
3824 9868083 : 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 9868071 : 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 9868047 : if (template_placeholder_p (type))
3861 : {
3862 192269 : type = do_auto_deduction (type, compound_literal, type, complain,
3863 : adc_variable_type);
3864 192269 : if (type == error_mark_node)
3865 : return error_mark_node;
3866 : }
3867 : /* C++23 auto{x}. */
3868 9675778 : else if (is_auto (type)
3869 162 : && !AUTO_IS_DECLTYPE (type)
3870 9675937 : && CONSTRUCTOR_NELTS (compound_literal) == 1)
3871 : {
3872 150 : if (is_constrained_auto (type))
3873 : {
3874 3 : if (complain & tf_error)
3875 3 : error ("%<auto{x}%> cannot be constrained");
3876 3 : return error_mark_node;
3877 : }
3878 147 : 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 147 : type = do_auto_deduction (type, compound_literal, type, complain,
3887 : adc_variable_type);
3888 147 : 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 9867902 : tree orig_cl = NULL_TREE;
3894 :
3895 9867902 : if (processing_template_decl)
3896 : {
3897 5157465 : const bool dependent_p
3898 5157465 : = (instantiation_dependent_expression_p (compound_literal)
3899 5157465 : || dependent_type_p (type));
3900 1705480 : 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 1705480 : orig_cl = unshare_constructor (compound_literal);
3906 5157465 : TREE_TYPE (orig_cl) = type;
3907 : /* Mark the expression as a compound literal. */
3908 5157465 : TREE_HAS_CONSTRUCTOR (orig_cl) = 1;
3909 : /* And as instantiation-dependent. */
3910 5157465 : CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p;
3911 5157465 : 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 5157465 : if (dependent_p)
3915 : return orig_cl;
3916 : /* Otherwise, do go on to e.g. check narrowing. */
3917 : }
3918 :
3919 6415917 : type = complete_type (type);
3920 :
3921 6415917 : 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 1073306 : CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
3928 1073306 : compound_literal = build_tree_list (NULL_TREE, compound_literal);
3929 1073306 : return build_functional_cast (input_location, type,
3930 1073306 : compound_literal, complain);
3931 : }
3932 :
3933 5342611 : if (TREE_CODE (type) == ARRAY_TYPE
3934 5342611 : && check_array_initializer (NULL_TREE, type, compound_literal))
3935 9 : return error_mark_node;
3936 5342602 : compound_literal = reshape_init (type, compound_literal, complain);
3937 5132962 : if (SCALAR_TYPE_P (type)
3938 733509 : && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
3939 5558709 : && !check_narrowing (type, compound_literal, complain))
3940 131 : return error_mark_node;
3941 5342471 : if (TREE_CODE (type) == ARRAY_TYPE
3942 5342471 : && TYPE_DOMAIN (type) == NULL_TREE)
3943 : {
3944 1253 : cp_complete_array_type_or_error (&type, compound_literal,
3945 : false, complain);
3946 1253 : if (type == error_mark_node)
3947 : return error_mark_node;
3948 : }
3949 5342468 : if (abstract_virtuals_error (ACU_UNKNOWN, type, complain))
3950 7 : return error_mark_node;
3951 5342461 : compound_literal = digest_init_flags (type, compound_literal,
3952 : LOOKUP_NORMAL | LOOKUP_NO_NARROWING,
3953 : complain);
3954 5342461 : if (compound_literal == error_mark_node)
3955 : return error_mark_node;
3956 :
3957 : /* If we're in a template, return the original compound literal. */
3958 5341840 : if (orig_cl)
3959 : return orig_cl;
3960 :
3961 3723976 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
3962 : {
3963 3046286 : TREE_HAS_CONSTRUCTOR (compound_literal) = true;
3964 3046286 : if (fcl_context == fcl_c99)
3965 37961 : CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1;
3966 : }
3967 :
3968 : /* Put static/constant array temporaries in static variables. */
3969 : /* FIXME all C99 compound literals should be variables rather than C++
3970 : temporaries, unless they are used as an aggregate initializer. */
3971 4898478 : if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
3972 2558925 : && fcl_context == fcl_c99
3973 83 : && TREE_CODE (type) == ARRAY_TYPE
3974 31 : && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
3975 3724007 : && initializer_constant_valid_p (compound_literal, type))
3976 : {
3977 31 : tree decl = create_temporary_var (type);
3978 31 : DECL_CONTEXT (decl) = NULL_TREE;
3979 31 : DECL_INITIAL (decl) = compound_literal;
3980 31 : TREE_STATIC (decl) = 1;
3981 31 : if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
3982 : {
3983 : /* 5.19 says that a constant expression can include an
3984 : lvalue-rvalue conversion applied to "a glvalue of literal type
3985 : that refers to a non-volatile temporary object initialized
3986 : with a constant expression". Rather than try to communicate
3987 : that this VAR_DECL is a temporary, just mark it constexpr. */
3988 24 : DECL_DECLARED_CONSTEXPR_P (decl) = true;
3989 24 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
3990 24 : TREE_CONSTANT (decl) = true;
3991 : }
3992 31 : cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
3993 31 : decl = pushdecl_top_level (decl);
3994 31 : DECL_NAME (decl) = make_anon_name ();
3995 31 : SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
3996 : /* Make sure the destructor is callable. */
3997 31 : tree clean = cxx_maybe_build_cleanup (decl, complain);
3998 31 : if (clean == error_mark_node)
3999 : return error_mark_node;
4000 31 : return decl;
4001 : }
4002 :
4003 : /* Represent other compound literals with TARGET_EXPR so we produce
4004 : a prvalue, and can elide copies. */
4005 3723945 : if (!VECTOR_TYPE_P (type)
4006 3683378 : && (TREE_CODE (compound_literal) == CONSTRUCTOR
4007 677684 : || TREE_CODE (compound_literal) == VEC_INIT_EXPR))
4008 : {
4009 : /* The CONSTRUCTOR is now an initializer, not a compound literal. */
4010 3005694 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
4011 3005694 : TREE_HAS_CONSTRUCTOR (compound_literal) = false;
4012 3005694 : compound_literal = get_target_expr (compound_literal, complain);
4013 : }
4014 : else
4015 : /* For e.g. int{42} just make sure it's a prvalue. */
4016 718251 : compound_literal = rvalue (compound_literal);
4017 :
4018 : return compound_literal;
4019 : }
4020 :
4021 : /* Return the declaration for the function-name variable indicated by
4022 : ID. */
4023 :
4024 : tree
4025 295038 : finish_fname (tree id)
4026 : {
4027 295038 : tree decl = fname_decl (input_location, C_RID_CODE (id), id);
4028 : /* [expr.prim.lambda.closure]/16 "Unless the compound-statement is that
4029 : of a consteval-block-declaration, a variable __func__ is implicitly
4030 : defined...". We could be in a consteval block in a function, though,
4031 : and then we shouldn't warn. */
4032 295038 : if (current_function_decl
4033 295038 : && !current_nonlambda_function (/*only_skip_consteval_block_p=*/true))
4034 8 : pedwarn (input_location, 0, "%qD is not defined outside of function scope",
4035 : decl);
4036 295038 : if (processing_template_decl && current_function_decl
4037 217193 : && decl != error_mark_node)
4038 217193 : decl = DECL_NAME (decl);
4039 295038 : return decl;
4040 : }
4041 :
4042 : /* Finish a translation unit. */
4043 :
4044 : void
4045 100592 : finish_translation_unit (void)
4046 : {
4047 : /* In case there were missing closebraces,
4048 : get us back to the global binding level. */
4049 100592 : pop_everything ();
4050 201184 : while (current_namespace != global_namespace)
4051 0 : pop_namespace ();
4052 :
4053 : /* Do file scope __FUNCTION__ et al. */
4054 100592 : finish_fname_decls ();
4055 :
4056 100592 : if (vec_safe_length (scope_chain->omp_declare_target_attribute))
4057 : {
4058 12 : cp_omp_declare_target_attr
4059 12 : a = scope_chain->omp_declare_target_attribute->pop ();
4060 12 : if (!errorcount)
4061 9 : error ("%qs without corresponding %qs",
4062 : a.device_type >= 0 ? "#pragma omp begin declare target"
4063 : : "#pragma omp declare target",
4064 : "#pragma omp end declare target");
4065 24 : vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0);
4066 : }
4067 100592 : if (vec_safe_length (scope_chain->omp_declare_variant_attribute))
4068 : {
4069 0 : if (!errorcount)
4070 0 : error ("%<omp begin declare variant%> without corresponding "
4071 : "%<omp end declare variant%>");
4072 0 : vec_safe_truncate (scope_chain->omp_declare_variant_attribute, 0);
4073 : }
4074 100592 : if (vec_safe_length (scope_chain->omp_begin_assumes))
4075 : {
4076 3 : if (!errorcount)
4077 3 : error ("%qs without corresponding %qs",
4078 : "#pragma omp begin assumes", "#pragma omp end assumes");
4079 3 : vec_safe_truncate (scope_chain->omp_begin_assumes, 0);
4080 : }
4081 100592 : }
4082 :
4083 : /* Finish a template type parameter, specified as AGGR IDENTIFIER.
4084 : Returns the parameter. */
4085 :
4086 : tree
4087 162399207 : finish_template_type_parm (tree aggr, tree identifier)
4088 : {
4089 162399207 : if (aggr != class_type_node)
4090 : {
4091 0 : permerror (input_location, "template type parameters must use the keyword %<class%> or %<typename%>");
4092 0 : aggr = class_type_node;
4093 : }
4094 :
4095 162399207 : return build_tree_list (aggr, identifier);
4096 : }
4097 :
4098 : /* Finish a template template parameter, specified as AGGR IDENTIFIER.
4099 : Returns the parameter. */
4100 :
4101 : tree
4102 412473 : finish_template_template_parm (tree aggr, tree identifier)
4103 : {
4104 412473 : tree decl = build_decl (input_location,
4105 : TYPE_DECL, identifier, NULL_TREE);
4106 :
4107 412473 : tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
4108 412473 : DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
4109 412473 : DECL_TEMPLATE_RESULT (tmpl) = decl;
4110 412473 : DECL_ARTIFICIAL (decl) = 1;
4111 :
4112 : /* Associate the constraints with the underlying declaration,
4113 : not the template. */
4114 412473 : tree constr = current_template_constraints ();
4115 412473 : set_constraints (decl, constr);
4116 :
4117 412473 : end_template_decl ();
4118 :
4119 412473 : gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
4120 :
4121 412473 : check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
4122 : /*is_primary=*/true, /*is_partial=*/false,
4123 : /*is_friend=*/0);
4124 :
4125 412473 : return finish_template_type_parm (aggr, tmpl);
4126 : }
4127 :
4128 : /* ARGUMENT is the default-argument value for a template template
4129 : parameter. If ARGUMENT is invalid, issue error messages and return
4130 : the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
4131 :
4132 : tree
4133 866 : check_template_template_default_arg (tree argument)
4134 : {
4135 866 : if (TREE_CODE (argument) != TEMPLATE_DECL
4136 : && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
4137 : && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
4138 : {
4139 : if (TREE_CODE (argument) == TYPE_DECL)
4140 : {
4141 18 : if (tree t = maybe_get_template_decl_from_type_decl (argument))
4142 18 : if (TREE_CODE (t) == TEMPLATE_DECL)
4143 : return t;
4144 15 : error ("invalid use of type %qT as a default value for a template "
4145 15 : "template-parameter", TREE_TYPE (argument));
4146 : }
4147 : else
4148 0 : error ("invalid default argument for a template template parameter");
4149 15 : return error_mark_node;
4150 : }
4151 :
4152 : return argument;
4153 : }
4154 :
4155 : /* Begin a class definition, as indicated by T. */
4156 :
4157 : tree
4158 31194285 : begin_class_definition (tree t)
4159 : {
4160 31194285 : if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
4161 33 : return error_mark_node;
4162 :
4163 31194390 : if (processing_template_parmlist && !LAMBDA_TYPE_P (t))
4164 : {
4165 9 : error ("definition of %q#T inside template parameter list", t);
4166 9 : return error_mark_node;
4167 : }
4168 :
4169 : /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
4170 : are passed the same as decimal scalar types. */
4171 31194243 : if (TREE_CODE (t) == RECORD_TYPE
4172 30672930 : && !processing_template_decl)
4173 : {
4174 11010352 : tree ns = TYPE_CONTEXT (t);
4175 11010349 : if (ns && TREE_CODE (ns) == NAMESPACE_DECL
4176 9041689 : && DECL_CONTEXT (ns) == std_node
4177 2198417 : && DECL_NAME (ns)
4178 13208749 : && id_equal (DECL_NAME (ns), "decimal"))
4179 : {
4180 150 : const char *n = TYPE_NAME_STRING (t);
4181 150 : if ((strcmp (n, "decimal32") == 0)
4182 101 : || (strcmp (n, "decimal64") == 0)
4183 46 : || (strcmp (n, "decimal128") == 0))
4184 147 : TYPE_TRANSPARENT_AGGR (t) = 1;
4185 : }
4186 : }
4187 :
4188 : /* A non-implicit typename comes from code like:
4189 :
4190 : template <typename T> struct A {
4191 : template <typename U> struct A<T>::B ...
4192 :
4193 : This is erroneous. */
4194 20183891 : else if (TREE_CODE (t) == TYPENAME_TYPE)
4195 : {
4196 0 : error ("invalid definition of qualified type %qT", t);
4197 0 : t = error_mark_node;
4198 : }
4199 :
4200 31194243 : if (t == error_mark_node || ! MAYBE_CLASS_TYPE_P (t))
4201 : {
4202 0 : t = make_class_type (RECORD_TYPE);
4203 0 : pushtag (make_anon_name (), t);
4204 : }
4205 :
4206 31194243 : if (TYPE_BEING_DEFINED (t))
4207 : {
4208 0 : t = make_class_type (TREE_CODE (t));
4209 0 : pushtag (TYPE_IDENTIFIER (t), t);
4210 : }
4211 :
4212 31194243 : maybe_process_partial_specialization (t);
4213 31194243 : pushclass (t);
4214 31194243 : TYPE_BEING_DEFINED (t) = 1;
4215 31194243 : class_binding_level->defining_class_p = 1;
4216 :
4217 31194243 : if (flag_pack_struct)
4218 : {
4219 99 : tree v;
4220 99 : TYPE_PACKED (t) = 1;
4221 : /* Even though the type is being defined for the first time
4222 : here, there might have been a forward declaration, so there
4223 : might be cv-qualified variants of T. */
4224 99 : for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
4225 0 : TYPE_PACKED (v) = 1;
4226 : }
4227 : /* Reset the interface data, at the earliest possible
4228 : moment, as it might have been set via a class foo;
4229 : before. */
4230 64764941 : if (! TYPE_UNNAMED_P (t))
4231 : {
4232 30445249 : struct c_fileinfo *finfo = \
4233 30445249 : get_fileinfo (LOCATION_FILE (input_location));
4234 30445249 : CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
4235 30445249 : SET_CLASSTYPE_INTERFACE_UNKNOWN_X
4236 : (t, finfo->interface_unknown);
4237 : }
4238 31194243 : reset_specialization ();
4239 :
4240 : /* Make a declaration for this class in its own scope. */
4241 31194243 : build_self_reference ();
4242 :
4243 31194243 : return t;
4244 : }
4245 :
4246 : /* Finish the member declaration given by DECL. */
4247 :
4248 : void
4249 421999888 : finish_member_declaration (tree decl)
4250 : {
4251 421999888 : if (decl == error_mark_node || decl == NULL_TREE)
4252 : return;
4253 :
4254 421998839 : if (decl == void_type_node)
4255 : /* The COMPONENT was a friend, not a member, and so there's
4256 : nothing for us to do. */
4257 : return;
4258 :
4259 : /* We should see only one DECL at a time. */
4260 421998839 : gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
4261 :
4262 : /* Don't add decls after definition. */
4263 421998860 : gcc_assert (TYPE_BEING_DEFINED (current_class_type)
4264 : /* We can add lambda types when late parsing default
4265 : arguments. */
4266 : || LAMBDA_TYPE_P (TREE_TYPE (decl)));
4267 :
4268 : /* Set up access control for DECL. */
4269 421998839 : TREE_PRIVATE (decl)
4270 421998839 : = (current_access_specifier == access_private_node);
4271 421998839 : TREE_PROTECTED (decl)
4272 421998839 : = (current_access_specifier == access_protected_node);
4273 421998839 : if (TREE_CODE (decl) == TEMPLATE_DECL)
4274 : {
4275 48292827 : TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
4276 48292827 : TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
4277 : }
4278 :
4279 : /* Mark the DECL as a member of the current class, unless it's
4280 : a member of an enumeration. */
4281 421998839 : if (TREE_CODE (decl) != CONST_DECL)
4282 419629512 : DECL_CONTEXT (decl) = current_class_type;
4283 :
4284 421998839 : if (TREE_TYPE (decl)
4285 418454985 : && ANON_AGGR_TYPE_P (TREE_TYPE (decl))
4286 422387311 : && TREE_CODE (decl) != TYPE_DECL)
4287 : {
4288 : /* Remember the single FIELD_DECL an anonymous aggregate type is used
4289 : for. */
4290 283088 : if (TREE_CODE (decl) == FIELD_DECL && DECL_NAME (decl) == NULL_TREE)
4291 : {
4292 283072 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
4293 283072 : gcc_assert (!ANON_AGGR_TYPE_FIELD (type));
4294 283072 : SET_ANON_AGGR_TYPE_FIELD (type, decl);
4295 : }
4296 : /* [class.union.anon]/1: Each object of such an unnamed type shall
4297 : be such an unnamed object. */
4298 16 : else if (ANON_UNION_TYPE_P (TREE_TYPE (decl)))
4299 : {
4300 10 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
4301 10 : auto_diagnostic_group d;
4302 10 : error_at (location_of (decl),
4303 : "declaration of member %qD with anonymous union type %qT",
4304 10 : decl, TREE_TYPE (decl));
4305 10 : inform (DECL_SOURCE_LOCATION (adecl),
4306 : "anonymous union declared here");
4307 10 : }
4308 : else
4309 : {
4310 6 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
4311 6 : auto_diagnostic_group d;
4312 6 : error_at (location_of (decl),
4313 : "declaration of member %qD with anonymous struct type %qT",
4314 6 : decl, TREE_TYPE (decl));
4315 6 : inform (DECL_SOURCE_LOCATION (adecl),
4316 : "anonymous struct declared here");
4317 6 : }
4318 : }
4319 421715751 : else if (TREE_TYPE (decl)
4320 418171897 : && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
4321 423280344 : && TREE_CODE (decl) != TYPE_DECL)
4322 : {
4323 1501295 : tree type = strip_array_types (TREE_TYPE (decl));
4324 1501295 : if (ANON_AGGR_TYPE_P (type))
4325 : {
4326 : /* [class.union.anon]/1: Each object of such an unnamed type shall
4327 : be such an unnamed object. */
4328 12 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (type));
4329 12 : auto_diagnostic_group d;
4330 12 : if (ANON_UNION_TYPE_P (type))
4331 : {
4332 8 : error_at (location_of (decl),
4333 : "declaration of member %qD with array of anonymous "
4334 8 : "union type %qT", decl, TREE_TYPE (decl));
4335 8 : inform (DECL_SOURCE_LOCATION (adecl),
4336 : "anonymous union declared here");
4337 : }
4338 : else
4339 : {
4340 4 : error_at (location_of (decl),
4341 : "declaration of member %qD with array of anonymous "
4342 4 : "struct type %qT", decl, TREE_TYPE (decl));
4343 4 : inform (DECL_SOURCE_LOCATION (adecl),
4344 : "anonymous struct declared here");
4345 : }
4346 12 : }
4347 : }
4348 :
4349 421998839 : if (TREE_CODE (decl) == USING_DECL)
4350 : /* Avoid debug info for class-scope USING_DECLS for now, we'll
4351 : call cp_emit_debug_info_for_using later. */
4352 3453038 : DECL_IGNORED_P (decl) = 1;
4353 :
4354 : /* Check for bare parameter packs in the non-static data member
4355 : declaration. */
4356 421998839 : if (TREE_CODE (decl) == FIELD_DECL)
4357 : {
4358 30945986 : if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
4359 9 : TREE_TYPE (decl) = error_mark_node;
4360 30945986 : if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
4361 0 : DECL_ATTRIBUTES (decl) = NULL_TREE;
4362 : }
4363 :
4364 : /* [dcl.link]
4365 :
4366 : A C language linkage is ignored for the names of class members
4367 : and the member function type of class member functions. */
4368 421998839 : if (DECL_LANG_SPECIFIC (decl))
4369 385181224 : SET_DECL_LANGUAGE (decl, lang_cplusplus);
4370 :
4371 421998839 : bool add = false;
4372 :
4373 : /* Functions and non-functions are added differently. */
4374 421998839 : if (DECL_DECLARES_FUNCTION_P (decl))
4375 218261537 : add = add_method (current_class_type, decl, false);
4376 : /* Enter the DECL into the scope of the class, if the class
4377 : isn't a closure (whose fields are supposed to be unnamed). */
4378 203737302 : else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
4379 199951133 : || maybe_push_used_methods (decl)
4380 401784624 : || pushdecl_class_level (decl))
4381 : add = true;
4382 :
4383 218261537 : if (add)
4384 : {
4385 : /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
4386 : go at the beginning. The reason is that
4387 : legacy_nonfn_member_lookup searches the list in order, and we
4388 : want a field name to override a type name so that the "struct
4389 : stat hack" will work. In particular:
4390 :
4391 : struct S { enum E { }; static const int E = 5; int ary[S::E]; } s;
4392 :
4393 : is valid. */
4394 :
4395 421985558 : if (TREE_CODE (decl) == TYPE_DECL)
4396 144566354 : TYPE_FIELDS (current_class_type)
4397 289132708 : = chainon (TYPE_FIELDS (current_class_type), decl);
4398 : else
4399 : {
4400 277419204 : DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
4401 277419204 : TYPE_FIELDS (current_class_type) = decl;
4402 : }
4403 :
4404 421985558 : maybe_add_class_template_decl_list (current_class_type, decl,
4405 : /*friend_p=*/0);
4406 : }
4407 : }
4408 :
4409 : /* Finish processing a complete template declaration. The PARMS are
4410 : the template parameters. */
4411 :
4412 : void
4413 93076393 : finish_template_decl (tree parms)
4414 : {
4415 93076393 : if (parms)
4416 93076384 : end_template_decl ();
4417 : else
4418 9 : end_specialization ();
4419 93076393 : }
4420 :
4421 : // Returns the template type of the class scope being entered. If we're
4422 : // entering a constrained class scope. TYPE is the class template
4423 : // scope being entered and we may need to match the intended type with
4424 : // a constrained specialization. For example:
4425 : //
4426 : // template<Object T>
4427 : // struct S { void f(); }; #1
4428 : //
4429 : // template<Object T>
4430 : // void S<T>::f() { } #2
4431 : //
4432 : // We check, in #2, that S<T> refers precisely to the type declared by
4433 : // #1 (i.e., that the constraints match). Note that the following should
4434 : // be an error since there is no specialization of S<T> that is
4435 : // unconstrained, but this is not diagnosed here.
4436 : //
4437 : // template<typename T>
4438 : // void S<T>::f() { }
4439 : //
4440 : // We cannot diagnose this problem here since this function also matches
4441 : // qualified template names that are not part of a definition. For example:
4442 : //
4443 : // template<Integral T, Floating_point U>
4444 : // typename pair<T, U>::first_type void f(T, U);
4445 : //
4446 : // Here, it is unlikely that there is a partial specialization of
4447 : // pair constrained for Integral and Floating_point arguments.
4448 : //
4449 : // The general rule is: if a constrained specialization with matching
4450 : // constraints is found return that type. Also note that if TYPE is not a
4451 : // class-type (e.g. a typename type), then no fixup is needed.
4452 :
4453 : static tree
4454 18306333 : fixup_template_type (tree type)
4455 : {
4456 : // Find the template parameter list at the a depth appropriate to
4457 : // the scope we're trying to enter.
4458 18306333 : tree parms = current_template_parms;
4459 18306333 : int depth = template_class_depth (type);
4460 40813401 : for (int n = current_template_depth; n > depth && parms; --n)
4461 4200735 : parms = TREE_CHAIN (parms);
4462 18306333 : if (!parms)
4463 : return type;
4464 18306323 : tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms);
4465 18306323 : tree cur_constr = build_constraints (cur_reqs, NULL_TREE);
4466 :
4467 : // Search for a specialization whose type and constraints match.
4468 18306323 : tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
4469 18306323 : tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
4470 35485020 : while (specs)
4471 : {
4472 17619323 : tree spec_constr = get_constraints (TREE_VALUE (specs));
4473 :
4474 : // If the type and constraints match a specialization, then we
4475 : // are entering that type.
4476 17619323 : if (same_type_p (type, TREE_TYPE (specs))
4477 17619323 : && equivalent_constraints (cur_constr, spec_constr))
4478 440626 : return TREE_TYPE (specs);
4479 17178697 : specs = TREE_CHAIN (specs);
4480 : }
4481 :
4482 : // If no specialization matches, then must return the type
4483 : // previously found.
4484 : return type;
4485 : }
4486 :
4487 : /* Finish processing a template-id (which names a type) of the form
4488 : NAME < ARGS >. Return the TYPE_DECL for the type named by the
4489 : template-id. If ENTERING_SCOPE is nonzero we are about to enter
4490 : the scope of template-id indicated. */
4491 :
4492 : tree
4493 189095423 : finish_template_type (tree name, tree args, int entering_scope)
4494 : {
4495 189095423 : tree type;
4496 :
4497 189095423 : type = lookup_template_class (name, args,
4498 : NULL_TREE, NULL_TREE,
4499 : tf_warning_or_error | tf_user);
4500 189095420 : if (entering_scope)
4501 19336743 : type = adjust_type_for_entering_scope (type);
4502 :
4503 : /* If we might be entering the scope of a partial specialization,
4504 : find the one with the right constraints. */
4505 189095420 : if (flag_concepts
4506 186399801 : && entering_scope
4507 18975619 : && CLASS_TYPE_P (type)
4508 18807408 : && CLASSTYPE_TEMPLATE_INFO (type)
4509 18807399 : && dependent_type_p (type)
4510 207401753 : && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
4511 18306333 : type = fixup_template_type (type);
4512 :
4513 189095420 : if (type == error_mark_node)
4514 : return type;
4515 189093130 : else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
4516 148484319 : return TYPE_STUB_DECL (type);
4517 : else
4518 40608811 : return TYPE_NAME (type);
4519 : }
4520 :
4521 : /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER
4522 : and ANNOTATIONS.
4523 : Return a TREE_LIST containing the ACCESS_SPECIFIER (or if there are
4524 : ANNOTATIONS, TREE_LIST containing the ACCESS_SPECIFIER and ANNOTATIONS)
4525 : and the BASE_CLASS, or NULL_TREE if an error occurred. The
4526 : ACCESS_SPECIFIER is one of
4527 : access_{default,public,protected,private}_node. For a virtual base
4528 : we set TREE_TYPE. */
4529 :
4530 : tree
4531 11479822 : finish_base_specifier (tree base, tree access, bool virtual_p,
4532 : tree annotations)
4533 : {
4534 11479822 : tree result;
4535 :
4536 11479822 : if (base == error_mark_node)
4537 : {
4538 0 : error ("invalid base-class specification");
4539 0 : result = NULL_TREE;
4540 : }
4541 11479822 : else if (! MAYBE_CLASS_TYPE_P (base))
4542 : {
4543 3 : error ("%qT is not a class type", base);
4544 3 : result = NULL_TREE;
4545 : }
4546 : else
4547 : {
4548 11479819 : if (cp_type_quals (base) != 0)
4549 : {
4550 : /* DR 484: Can a base-specifier name a cv-qualified
4551 : class type? */
4552 12 : base = TYPE_MAIN_VARIANT (base);
4553 : }
4554 11479819 : if (annotations)
4555 18 : access = build_tree_list (access, nreverse (annotations));
4556 11479819 : result = build_tree_list (access, base);
4557 11479819 : if (virtual_p)
4558 26200 : TREE_TYPE (result) = integer_type_node;
4559 : }
4560 :
4561 11479822 : return result;
4562 : }
4563 :
4564 : /* If FNS is a member function, a set of member functions, or a
4565 : template-id referring to one or more member functions, return a
4566 : BASELINK for FNS, incorporating the current access context.
4567 : Otherwise, return FNS unchanged. */
4568 :
4569 : tree
4570 185301576 : baselink_for_fns (tree fns)
4571 : {
4572 185301576 : tree scope;
4573 185301576 : tree cl;
4574 :
4575 185301576 : if (BASELINK_P (fns)
4576 185301576 : || error_operand_p (fns))
4577 : return fns;
4578 :
4579 171292501 : scope = ovl_scope (fns);
4580 171292501 : if (!CLASS_TYPE_P (scope))
4581 : return fns;
4582 :
4583 8933046 : cl = currently_open_derived_class (scope);
4584 8933046 : if (!cl)
4585 6538623 : cl = scope;
4586 8933046 : tree access_path = TYPE_BINFO (cl);
4587 8933046 : tree conv_path = (cl == scope ? access_path
4588 712967 : : lookup_base (cl, scope, ba_any, NULL, tf_none));
4589 8933046 : return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE);
4590 : }
4591 :
4592 : /* Returns true iff we are currently parsing a lambda-declarator. */
4593 :
4594 : bool
4595 1984823845 : parsing_lambda_declarator ()
4596 : {
4597 1984823845 : cp_binding_level *b = current_binding_level;
4598 1986841949 : while (b->kind == sk_template_parms || b->kind == sk_function_parms)
4599 2018104 : b = b->level_chain;
4600 1984823845 : return b->kind == sk_lambda;
4601 : }
4602 :
4603 : /* Returns true iff DECL is a variable from a function outside
4604 : the current one. */
4605 :
4606 : static bool
4607 2650641453 : outer_var_p (tree decl)
4608 : {
4609 : /* These should have been stripped or otherwise handled by the caller. */
4610 2650641453 : gcc_checking_assert (!REFERENCE_REF_P (decl));
4611 :
4612 1744779990 : return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
4613 2434088998 : && DECL_FUNCTION_SCOPE_P (decl)
4614 : /* Don't get confused by temporaries. */
4615 2016720262 : && DECL_NAME (decl)
4616 4643566002 : && (DECL_CONTEXT (decl) != current_function_decl
4617 1982663900 : || parsing_nsdmi ()
4618 : /* Also consider captures as outer vars if we are in
4619 : decltype in a lambda declarator as in:
4620 : auto l = [j=0]() -> decltype((j)) { ... }
4621 : for the sake of finish_decltype_type.
4622 :
4623 : (Similar issue also affects non-lambdas, but vexing parse
4624 : makes it more difficult to handle than lambdas.) */
4625 1982662553 : || parsing_lambda_declarator ()));
4626 : }
4627 :
4628 : /* As above, but also checks that DECL is automatic. */
4629 :
4630 : bool
4631 2650641453 : outer_automatic_var_p (tree decl)
4632 : {
4633 2650641453 : return (outer_var_p (decl)
4634 2650641453 : && !TREE_STATIC (decl));
4635 : }
4636 :
4637 : /* Note whether capture proxy D is only used in a contract condition. */
4638 :
4639 : static void
4640 176405 : set_contract_capture_flag (tree d, bool val)
4641 : {
4642 176405 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (d));
4643 176405 : tree proxy = DECL_VALUE_EXPR (d);
4644 176405 : gcc_checking_assert (TREE_CODE (proxy) == COMPONENT_REF
4645 : && TREE_CODE (TREE_OPERAND (proxy, 1)) == FIELD_DECL);
4646 176405 : DECL_CONTRACT_CAPTURE_P (TREE_OPERAND (proxy, 1)) = val;
4647 176405 : }
4648 :
4649 : /* DECL satisfies outer_automatic_var_p. Possibly complain about it or
4650 : rewrite it for lambda capture.
4651 :
4652 : If ODR_USE is true, we're being called from mark_use, and we complain about
4653 : use of constant variables. If ODR_USE is false, we're being called for the
4654 : id-expression, and we do lambda capture. */
4655 :
4656 : tree
4657 5298630 : process_outer_var_ref (tree decl, tsubst_flags_t complain,
4658 : bool odr_use/*=false*/)
4659 : {
4660 5298630 : if (cp_unevaluated_operand)
4661 : {
4662 3137101 : tree type = TREE_TYPE (decl);
4663 3137101 : if (!dependent_type_p (type)
4664 3137101 : && variably_modified_type_p (type, NULL_TREE))
4665 : /* VLAs are used even in unevaluated context. */;
4666 : else
4667 : /* It's not a use (3.2) if we're in an unevaluated context. */
4668 3137095 : return decl;
4669 : }
4670 2161535 : if (decl == error_mark_node)
4671 : return decl;
4672 :
4673 2161529 : tree context = DECL_CONTEXT (decl);
4674 2161529 : tree containing_function = current_function_decl;
4675 2161529 : tree lambda_stack = NULL_TREE;
4676 2161529 : tree lambda_expr = NULL_TREE;
4677 2161529 : tree initializer = convert_from_reference (decl);
4678 2161529 : tree var = strip_normal_capture_proxy (decl);
4679 :
4680 : /* Mark it as used now even if the use is ill-formed. */
4681 2161529 : if (!mark_used (decl, complain))
4682 3 : return error_mark_node;
4683 :
4684 2161526 : if (parsing_nsdmi () || parsing_lambda_declarator ())
4685 : containing_function = NULL_TREE;
4686 :
4687 4322144 : if (containing_function && LAMBDA_FUNCTION_P (containing_function))
4688 : {
4689 : /* Check whether we've already built a proxy. */
4690 2160957 : tree d = retrieve_local_specialization (var);
4691 :
4692 2160957 : if (d && d != decl && is_capture_proxy (d))
4693 : {
4694 1125261 : if (flag_contracts && !processing_contract_condition)
4695 : /* We might have created a capture for a contract_assert ref. to
4696 : some var, if that is now captured 'normally' then this is OK.
4697 : Otherwise we leave the capture marked as incorrect. */
4698 176399 : set_contract_capture_flag (d, false);
4699 1125261 : if (DECL_CONTEXT (d) == containing_function)
4700 : /* We already have an inner proxy. */
4701 : return d;
4702 : else
4703 : /* We need to capture an outer proxy. */
4704 6343 : return process_outer_var_ref (d, complain, odr_use);
4705 : }
4706 : }
4707 :
4708 : /* If we are in a lambda function, we can move out until we hit
4709 : 1. the context,
4710 : 2. a non-lambda function, or
4711 : 3. a non-default capturing lambda function. */
4712 2078616 : while (context != containing_function
4713 : /* containing_function can be null with invalid generic lambdas. */
4714 2078616 : && containing_function
4715 3122376 : && LAMBDA_FUNCTION_P (containing_function))
4716 : {
4717 1043760 : tree closure = DECL_CONTEXT (containing_function);
4718 1043760 : lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure);
4719 :
4720 1043760 : if (TYPE_CLASS_SCOPE_P (closure))
4721 : /* A lambda in an NSDMI (c++/64496). */
4722 : break;
4723 :
4724 1043757 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4725 : break;
4726 :
4727 1042351 : lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack);
4728 :
4729 1042351 : containing_function = decl_function_context (containing_function);
4730 : }
4731 :
4732 : /* In a lambda within a template, wait until instantiation time to implicitly
4733 : capture a parameter pack. We want to wait because we don't know if we're
4734 : capturing the whole pack or a single element, and it's OK to wait because
4735 : find_parameter_packs_r walks into the lambda body. */
4736 1036265 : if (context == containing_function
4737 1036265 : && DECL_PACK_P (decl))
4738 : return decl;
4739 :
4740 992241 : if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
4741 : {
4742 6 : if (complain & tf_error)
4743 6 : error ("cannot capture member %qD of anonymous union", decl);
4744 6 : return error_mark_node;
4745 : }
4746 : /* Do lambda capture when processing the id-expression, not when
4747 : odr-using a variable, but uses in a contract must not cause a capture. */
4748 992235 : if (!odr_use && context == containing_function)
4749 : {
4750 990257 : decl = add_default_capture (lambda_stack,
4751 990257 : /*id=*/DECL_NAME (decl), initializer);
4752 990257 : if (flag_contracts && processing_contract_condition)
4753 6 : set_contract_capture_flag (decl, true);
4754 : }
4755 : /* Only an odr-use of an outer automatic variable causes an
4756 : error, and a constant variable can decay to a prvalue
4757 : constant without odr-use. So don't complain yet. */
4758 1978 : else if (!odr_use && decl_constant_var_p (var))
4759 : return var;
4760 : /* Don't complain when DECL is dependent, because it can turn out to
4761 : be constant (and therefore needing no capture) when instantiating. */
4762 452 : else if (VAR_P (var) && instantiation_dependent_expression_p (var))
4763 : return var;
4764 434 : else if (lambda_expr)
4765 : {
4766 60 : if (complain & tf_error)
4767 : {
4768 56 : auto_diagnostic_group d;
4769 56 : error ("%qD is not captured", decl);
4770 56 : tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
4771 56 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4772 53 : inform (location_of (closure),
4773 : "the lambda has no capture-default");
4774 3 : else if (TYPE_CLASS_SCOPE_P (closure))
4775 3 : inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot "
4776 : "capture variables from the enclosing context",
4777 3 : TYPE_CONTEXT (closure));
4778 56 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4779 56 : }
4780 60 : return error_mark_node;
4781 : }
4782 374 : else if (processing_contract_condition && TREE_CODE (decl) == PARM_DECL)
4783 : /* Use of a parameter in a contract condition is fine. */
4784 : return decl;
4785 : else
4786 : {
4787 53 : if (complain & tf_error)
4788 : {
4789 39 : auto_diagnostic_group d;
4790 57 : error (VAR_P (decl)
4791 : ? G_("use of local variable with automatic storage from "
4792 : "containing function")
4793 : : G_("use of parameter from containing function"));
4794 39 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4795 39 : }
4796 53 : return error_mark_node;
4797 : }
4798 : return decl;
4799 : }
4800 :
4801 : /* ID_EXPRESSION is a representation of parsed, but unprocessed,
4802 : id-expression. (See cp_parser_id_expression for details.) SCOPE,
4803 : if non-NULL, is the type or namespace used to explicitly qualify
4804 : ID_EXPRESSION. DECL is the entity to which that name has been
4805 : resolved.
4806 :
4807 : *CONSTANT_EXPRESSION_P is true if we are presently parsing a
4808 : constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
4809 : be set to true if this expression isn't permitted in a
4810 : constant-expression, but it is otherwise not set by this function.
4811 : *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
4812 : constant-expression, but a non-constant expression is also
4813 : permissible.
4814 :
4815 : DONE is true if this expression is a complete postfix-expression;
4816 : it is false if this expression is followed by '->', '[', '(', etc.
4817 : ADDRESS_P is true iff this expression is the operand of '&'.
4818 : TEMPLATE_P is true iff the qualified-id was of the form
4819 : "A::template B". TEMPLATE_ARG_P is true iff this qualified name
4820 : appears as a template argument.
4821 :
4822 : If an error occurs, and it is the kind of error that might cause
4823 : the parser to abort a tentative parse, *ERROR_MSG is filled in. It
4824 : is the caller's responsibility to issue the message. *ERROR_MSG
4825 : will be a string with static storage duration, so the caller need
4826 : not "free" it.
4827 :
4828 : Return an expression for the entity, after issuing appropriate
4829 : diagnostics. This function is also responsible for transforming a
4830 : reference to a non-static member into a COMPONENT_REF that makes
4831 : the use of "this" explicit.
4832 :
4833 : Upon return, *IDK will be filled in appropriately. */
4834 : static cp_expr
4835 787847788 : finish_id_expression_1 (tree id_expression,
4836 : tree decl,
4837 : tree scope,
4838 : cp_id_kind *idk,
4839 : bool integral_constant_expression_p,
4840 : bool allow_non_integral_constant_expression_p,
4841 : bool *non_integral_constant_expression_p,
4842 : bool template_p,
4843 : bool done,
4844 : bool address_p,
4845 : bool template_arg_p,
4846 : const char **error_msg,
4847 : location_t location)
4848 : {
4849 787847788 : decl = strip_using_decl (decl);
4850 :
4851 : /* Initialize the output parameters. */
4852 787847788 : *idk = CP_ID_KIND_NONE;
4853 787847788 : *error_msg = NULL;
4854 :
4855 787847788 : if (id_expression == error_mark_node)
4856 12 : return error_mark_node;
4857 : /* If we have a template-id, then no further lookup is
4858 : required. If the template-id was for a template-class, we
4859 : will sometimes have a TYPE_DECL at this point. */
4860 787847776 : else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4861 733002818 : || TREE_CODE (decl) == TYPE_DECL)
4862 : ;
4863 : /* Look up the name. */
4864 : else
4865 : {
4866 733001897 : if (decl == error_mark_node)
4867 : {
4868 : /* Name lookup failed. */
4869 130868 : if (scope
4870 374 : && !dependent_namespace_p (scope)
4871 131242 : && (!TYPE_P (scope)
4872 119 : || (!dependentish_scope_p (scope)
4873 115 : && !(identifier_p (id_expression)
4874 100 : && IDENTIFIER_CONV_OP_P (id_expression)
4875 3 : && dependent_type_p (TREE_TYPE (id_expression))))))
4876 : {
4877 : /* If the qualifying type is non-dependent (and the name
4878 : does not name a conversion operator to a dependent
4879 : type), issue an error. */
4880 364 : qualified_name_lookup_error (scope, id_expression, decl, location);
4881 364 : return error_mark_node;
4882 : }
4883 130504 : else if (!scope)
4884 : {
4885 : /* It may be resolved via Koenig lookup. */
4886 130494 : *idk = CP_ID_KIND_UNQUALIFIED;
4887 130494 : return id_expression;
4888 : }
4889 : else
4890 : decl = id_expression;
4891 : }
4892 :
4893 : /* Remember that the name was used in the definition of
4894 : the current class so that we can check later to see if
4895 : the meaning would have been different after the class
4896 : was entirely defined. */
4897 732871029 : if (!scope && decl != error_mark_node && identifier_p (id_expression))
4898 655336220 : maybe_note_name_used_in_class (id_expression, decl);
4899 :
4900 : /* A use in unevaluated operand might not be instantiated appropriately
4901 : if tsubst_copy builds a dummy parm, or if we never instantiate a
4902 : generic lambda, so mark it now. */
4903 732871039 : if (processing_template_decl
4904 732871039 : && (cp_unevaluated_operand
4905 633864738 : || generic_lambda_fn_p (current_function_decl)))
4906 20400535 : mark_type_use (decl);
4907 :
4908 : /* Disallow uses of local variables from containing functions, except
4909 : within lambda-expressions. */
4910 732871039 : if (outer_automatic_var_p (decl))
4911 : {
4912 3779687 : decl = process_outer_var_ref (decl, tf_warning_or_error);
4913 3779687 : if (decl == error_mark_node)
4914 92 : return error_mark_node;
4915 : }
4916 :
4917 : /* Also disallow uses of function parameters outside the function
4918 : body, except inside an unevaluated context (i.e. decltype). */
4919 732870947 : if (TREE_CODE (decl) == PARM_DECL
4920 305944587 : && DECL_CONTEXT (decl) == NULL_TREE
4921 8266921 : && !CONSTRAINT_VAR_P (decl)
4922 4446837 : && !cp_unevaluated_operand
4923 563 : && !processing_contract_condition
4924 732871003 : && !processing_omp_trait_property_expr)
4925 : {
4926 38 : *error_msg = G_("use of parameter outside function body");
4927 38 : return error_mark_node;
4928 : }
4929 : }
4930 :
4931 : /* If we didn't find anything, or what we found was a type,
4932 : then this wasn't really an id-expression. */
4933 787716788 : if (TREE_CODE (decl) == TEMPLATE_DECL
4934 787716788 : && !DECL_FUNCTION_TEMPLATE_P (decl))
4935 : {
4936 51 : *error_msg = G_("missing template arguments");
4937 51 : return error_mark_node;
4938 : }
4939 787716737 : else if (TREE_CODE (decl) == TYPE_DECL
4940 787715816 : || TREE_CODE (decl) == NAMESPACE_DECL)
4941 : {
4942 936 : *error_msg = G_("expected primary-expression");
4943 936 : return error_mark_node;
4944 : }
4945 :
4946 : /* If the name resolved to a template parameter, there is no
4947 : need to look it up again later. */
4948 33396601 : if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
4949 801633917 : || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4950 : {
4951 19478485 : tree r;
4952 :
4953 19478485 : *idk = CP_ID_KIND_NONE;
4954 19478485 : if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
4955 0 : decl = TEMPLATE_PARM_DECL (decl);
4956 19478485 : r = DECL_INITIAL (decl);
4957 19478485 : if (CLASS_TYPE_P (TREE_TYPE (r)) && !CP_TYPE_CONST_P (TREE_TYPE (r)))
4958 : {
4959 : /* If the entity is a template parameter object for a template
4960 : parameter of type T, the type of the expression is const T. */
4961 2969 : tree ctype = TREE_TYPE (r);
4962 2969 : ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
4963 : | TYPE_QUAL_CONST));
4964 2969 : r = build1 (VIEW_CONVERT_EXPR, ctype, r);
4965 : }
4966 19478485 : r = convert_from_reference (r);
4967 19478485 : if (integral_constant_expression_p
4968 3361191 : && !dependent_type_p (TREE_TYPE (decl))
4969 22340002 : && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
4970 : {
4971 1017 : if (!allow_non_integral_constant_expression_p)
4972 6 : error ("template parameter %qD of type %qT is not allowed in "
4973 : "an integral constant expression because it is not of "
4974 6 : "integral or enumeration type", decl, TREE_TYPE (decl));
4975 1017 : *non_integral_constant_expression_p = true;
4976 : }
4977 :
4978 19478485 : if (flag_contracts && processing_contract_condition)
4979 15 : r = constify_contract_access (r);
4980 :
4981 19478485 : return r;
4982 : }
4983 768237316 : else if (TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE)
4984 : {
4985 9 : gcc_checking_assert (scope);
4986 9 : *idk = CP_ID_KIND_QUALIFIED;
4987 9 : cp_warn_deprecated_use_scopes (scope);
4988 9 : decl = finish_qualified_id_expr (scope, decl, done, address_p,
4989 : template_p, template_arg_p,
4990 : tf_warning_or_error);
4991 : }
4992 : else
4993 : {
4994 768237307 : if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4995 54844958 : && variable_template_p (TREE_OPERAND (decl, 0))
4996 780687122 : && !concept_check_p (decl))
4997 : /* Try resolving this variable TEMPLATE_ID_EXPR (which is always
4998 : considered type-dependent) now, so that the dependence test that
4999 : follows gives us the right answer: if it represents a non-dependent
5000 : variable template-id then finish_template_variable will yield the
5001 : corresponding non-dependent VAR_DECL. */
5002 12449815 : decl = finish_template_variable (decl);
5003 :
5004 768237307 : bool dependent_p = type_dependent_expression_p (decl);
5005 :
5006 : /* If the declaration was explicitly qualified indicate
5007 : that. The semantics of `A::f(3)' are different than
5008 : `f(3)' if `f' is virtual. */
5009 1536474614 : *idk = (scope
5010 768237307 : ? CP_ID_KIND_QUALIFIED
5011 668287211 : : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
5012 668287211 : ? CP_ID_KIND_TEMPLATE_ID
5013 : : (dependent_p
5014 636145142 : ? CP_ID_KIND_UNQUALIFIED_DEPENDENT
5015 : : CP_ID_KIND_UNQUALIFIED)));
5016 :
5017 768237307 : if (dependent_p
5018 768237307 : && !scope
5019 441086321 : && DECL_P (decl)
5020 1178210961 : && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
5021 : /* Dependent type attributes on the decl mean that the TREE_TYPE is
5022 : wrong, so just return the identifier. */
5023 39 : return id_expression;
5024 :
5025 768237268 : if (DECL_CLASS_TEMPLATE_P (decl))
5026 : {
5027 0 : error ("use of class template %qT as expression", decl);
5028 0 : return error_mark_node;
5029 : }
5030 :
5031 768237268 : if (TREE_CODE (decl) == TREE_LIST)
5032 : {
5033 : /* Ambiguous reference to base members. */
5034 0 : auto_diagnostic_group d;
5035 0 : error ("request for member %qD is ambiguous in "
5036 : "multiple inheritance lattice", id_expression);
5037 0 : print_candidates (input_location, decl);
5038 0 : return error_mark_node;
5039 0 : }
5040 :
5041 : /* Mark variable-like entities as used. Functions are similarly
5042 : marked either below or after overload resolution. */
5043 768237268 : if ((VAR_P (decl)
5044 557487502 : || TREE_CODE (decl) == PARM_DECL
5045 251542959 : || TREE_CODE (decl) == CONST_DECL
5046 237624843 : || TREE_CODE (decl) == RESULT_DECL)
5047 1088099927 : && !mark_used (decl))
5048 12 : return error_mark_node;
5049 :
5050 : /* Only certain kinds of names are allowed in constant
5051 : expression. Template parameters have already
5052 : been handled above. */
5053 768237253 : if (! error_operand_p (decl)
5054 768236927 : && !dependent_p
5055 768236927 : && integral_constant_expression_p
5056 77043964 : && !decl_constant_var_p (decl)
5057 62733897 : && TREE_CODE (decl) != CONST_DECL
5058 54191310 : && !builtin_valid_in_constant_expr_p (decl)
5059 822378862 : && !concept_check_p (decl))
5060 : {
5061 53574849 : if (!allow_non_integral_constant_expression_p)
5062 : {
5063 30 : error ("%qD cannot appear in a constant-expression", decl);
5064 30 : return error_mark_node;
5065 : }
5066 53574819 : *non_integral_constant_expression_p = true;
5067 : }
5068 :
5069 768237223 : if (tree wrap = maybe_get_tls_wrapper_call (decl))
5070 : /* Replace an evaluated use of the thread_local variable with
5071 : a call to its wrapper. */
5072 : decl = wrap;
5073 768236711 : else if (concept_check_p (decl))
5074 : {
5075 : /* Nothing more to do. All of the analysis for concept checks
5076 : is done by build_conept_id, called from the parser. */
5077 : }
5078 751356583 : else if (scope)
5079 : {
5080 98012361 : if (TREE_CODE (decl) == SCOPE_REF)
5081 : {
5082 89547 : gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0)));
5083 89547 : decl = TREE_OPERAND (decl, 1);
5084 : }
5085 :
5086 98012361 : decl = (adjust_result_of_qualified_name_lookup
5087 98012361 : (decl, scope, current_nonlambda_class_type()));
5088 :
5089 98012361 : cp_warn_deprecated_use_scopes (scope);
5090 :
5091 98012361 : if (TYPE_P (scope))
5092 13875418 : decl = finish_qualified_id_expr (scope,
5093 : decl,
5094 : done,
5095 : address_p,
5096 : template_p,
5097 : template_arg_p,
5098 : tf_warning_or_error);
5099 : else
5100 84136943 : decl = convert_from_reference (decl);
5101 : }
5102 653344222 : else if (TREE_CODE (decl) == FIELD_DECL)
5103 : {
5104 68135453 : if (flag_contracts && processing_contract_condition
5105 37 : && contract_class_ptr == current_class_ptr)
5106 : {
5107 6 : error ("%qD 'this' required when accessing a member within a "
5108 : "constructor precondition or destructor postcondition "
5109 : "contract check", decl);
5110 6 : return error_mark_node;
5111 : }
5112 : /* Since SCOPE is NULL here, this is an unqualified name.
5113 : Access checking has been performed during name lookup
5114 : already. Turn off checking to avoid duplicate errors. */
5115 68135447 : push_deferring_access_checks (dk_no_check);
5116 68135447 : decl = finish_non_static_data_member (decl, NULL_TREE,
5117 : /*qualifying_scope=*/NULL_TREE);
5118 68135447 : pop_deferring_access_checks ();
5119 : }
5120 585208769 : else if (is_overloaded_fn (decl))
5121 : {
5122 : /* We only need to look at the first function,
5123 : because all the fns share the attribute we're
5124 : concerned with (all member fns or all non-members). */
5125 62834116 : tree first_fn = get_first_fn (decl);
5126 62834116 : first_fn = STRIP_TEMPLATE (first_fn);
5127 :
5128 62834116 : if (!template_arg_p
5129 62834116 : && (TREE_CODE (first_fn) == USING_DECL
5130 62832230 : || (TREE_CODE (first_fn) == FUNCTION_DECL
5131 62832230 : && DECL_FUNCTION_MEMBER_P (first_fn)
5132 38382465 : && !shared_member_p (decl))))
5133 : {
5134 : /* A set of member functions. */
5135 29570935 : if (flag_contracts && processing_contract_condition
5136 24 : && contract_class_ptr == current_class_ptr)
5137 : {
5138 3 : error ("%qD 'this' required when accessing a member within a "
5139 : "constructor precondition or destructor postcondition "
5140 : "contract check", decl);
5141 3 : return error_mark_node;
5142 : }
5143 29570932 : decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
5144 29570932 : return finish_class_member_access_expr (decl, id_expression,
5145 : /*template_p=*/false,
5146 29570932 : tf_warning_or_error);
5147 : }
5148 :
5149 33263181 : decl = baselink_for_fns (decl);
5150 : }
5151 : else
5152 : {
5153 510870526 : if (DECL_P (decl) && DECL_NONLOCAL (decl)
5154 523883670 : && DECL_CLASS_SCOPE_P (decl))
5155 : {
5156 1509017 : tree context = context_for_name_lookup (decl);
5157 1509017 : if (context != current_class_type)
5158 : {
5159 789310 : tree path = currently_open_derived_class (context);
5160 789310 : if (!path)
5161 : /* PATH can be null for using an enum of an unrelated
5162 : class; we checked its access in lookup_using_decl.
5163 :
5164 : ??? Should this case make a clone instead, like
5165 : handle_using_decl? */
5166 43 : gcc_assert (TREE_CODE (decl) == CONST_DECL
5167 : /* This is for:
5168 : constexpr auto r = ^^S::i;
5169 : auto a = [:r:]; */
5170 : || flag_reflection);
5171 : else
5172 789267 : perform_or_defer_access_check (TYPE_BINFO (path),
5173 : decl, decl,
5174 : tf_warning_or_error);
5175 : }
5176 : }
5177 :
5178 522374653 : decl = convert_from_reference (decl);
5179 : }
5180 : }
5181 :
5182 738666291 : check_param_in_postcondition (decl, location);
5183 738666291 : if (flag_contracts && processing_contract_condition)
5184 2033 : decl = constify_contract_access (decl);
5185 :
5186 738666291 : return cp_expr (decl, location);
5187 : }
5188 :
5189 : /* As per finish_id_expression_1, but adding a wrapper node
5190 : around the result if needed to express LOCATION. */
5191 :
5192 : cp_expr
5193 787847788 : finish_id_expression (tree id_expression,
5194 : tree decl,
5195 : tree scope,
5196 : cp_id_kind *idk,
5197 : bool integral_constant_expression_p,
5198 : bool allow_non_integral_constant_expression_p,
5199 : bool *non_integral_constant_expression_p,
5200 : bool template_p,
5201 : bool done,
5202 : bool address_p,
5203 : bool template_arg_p,
5204 : const char **error_msg,
5205 : location_t location)
5206 : {
5207 787847788 : cp_expr result
5208 787847788 : = finish_id_expression_1 (id_expression, decl, scope, idk,
5209 : integral_constant_expression_p,
5210 : allow_non_integral_constant_expression_p,
5211 : non_integral_constant_expression_p,
5212 : template_p, done, address_p, template_arg_p,
5213 : error_msg, location);
5214 787847785 : return result.maybe_add_location_wrapper ();
5215 : }
5216 :
5217 : /* Implement the __typeof keyword: Return the type of EXPR, suitable for
5218 : use as a type-specifier. */
5219 :
5220 : tree
5221 21774374 : finish_typeof (tree expr)
5222 : {
5223 21774374 : tree type;
5224 :
5225 21774374 : if (type_dependent_expression_p (expr))
5226 : {
5227 21682067 : type = cxx_make_type (TYPEOF_TYPE);
5228 21682067 : TYPEOF_TYPE_EXPR (type) = expr;
5229 21682067 : SET_TYPE_STRUCTURAL_EQUALITY (type);
5230 :
5231 21682067 : return type;
5232 : }
5233 :
5234 92307 : expr = mark_type_use (expr);
5235 :
5236 92307 : type = unlowered_expr_type (expr);
5237 :
5238 92307 : if (!type || type == unknown_type_node)
5239 : {
5240 3 : error ("type of %qE is unknown", expr);
5241 3 : return error_mark_node;
5242 : }
5243 :
5244 : return type;
5245 : }
5246 :
5247 : /* Implement the __underlying_type keyword: Return the underlying
5248 : type of TYPE, suitable for use as a type-specifier. */
5249 :
5250 : tree
5251 48413 : finish_underlying_type (tree type)
5252 : {
5253 48413 : if (!complete_type_or_else (type, NULL_TREE))
5254 3 : return error_mark_node;
5255 :
5256 48410 : if (TREE_CODE (type) != ENUMERAL_TYPE)
5257 : {
5258 24 : error ("%qT is not an enumeration type", type);
5259 24 : return error_mark_node;
5260 : }
5261 :
5262 48386 : tree underlying_type = ENUM_UNDERLYING_TYPE (type);
5263 :
5264 : /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
5265 : includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
5266 : See finish_enum_value_list for details. */
5267 48386 : if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
5268 56 : underlying_type
5269 56 : = c_common_type_for_mode (TYPE_MODE (underlying_type),
5270 56 : TYPE_UNSIGNED (underlying_type));
5271 :
5272 : return underlying_type;
5273 : }
5274 :
5275 : /* Implement the __type_pack_element keyword: Return the type
5276 : at index IDX within TYPES. */
5277 :
5278 : static tree
5279 134640 : finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
5280 : {
5281 134640 : idx = maybe_constant_value (idx, NULL_TREE, mce_true);
5282 134640 : if (!INTEGRAL_TYPE_P (TREE_TYPE (idx)))
5283 : {
5284 6 : if (complain & tf_error)
5285 3 : error ("pack index has non-integral type %qT", TREE_TYPE (idx));
5286 6 : return error_mark_node;
5287 : }
5288 134634 : if (TREE_CODE (idx) != INTEGER_CST)
5289 : {
5290 2 : if (complain & tf_error)
5291 : {
5292 2 : error ("pack index is not an integral constant");
5293 2 : cxx_constant_value (idx);
5294 : }
5295 2 : return error_mark_node;
5296 : }
5297 134632 : if (tree_int_cst_sgn (idx) < 0)
5298 : {
5299 3 : if (complain & tf_error)
5300 3 : error ("pack index %qE is negative", idx);
5301 3 : return error_mark_node;
5302 : }
5303 134629 : if (wi::to_widest (idx) >= TREE_VEC_LENGTH (types))
5304 : {
5305 35 : if (complain & tf_error)
5306 29 : error ("pack index %qE is out of range for pack of length %qd",
5307 29 : idx, TREE_VEC_LENGTH (types));
5308 35 : return error_mark_node;
5309 : }
5310 134594 : return TREE_VEC_ELT (types, tree_to_shwi (idx));
5311 : }
5312 :
5313 : /* In a pack-index T...[N], return the element at index IDX within TYPES.
5314 : PARENTHESIZED_P is true iff the pack index was wrapped in (). */
5315 :
5316 : tree
5317 22548 : pack_index_element (tree idx, tree types, bool parenthesized_p,
5318 : tsubst_flags_t complain)
5319 : {
5320 22548 : tree r = finish_type_pack_element (idx, types, complain);
5321 22548 : if (parenthesized_p)
5322 : /* For the benefit of decltype(auto). */
5323 35 : r = force_paren_expr (r);
5324 22548 : return r;
5325 : }
5326 :
5327 : /* Implement the __direct_bases keyword: Return the direct base classes
5328 : of type. */
5329 :
5330 : tree
5331 15 : calculate_direct_bases (tree type, tsubst_flags_t complain)
5332 : {
5333 15 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5334 15 : || !NON_UNION_CLASS_TYPE_P (type))
5335 8 : return make_tree_vec (0);
5336 :
5337 7 : releasing_vec vector;
5338 7 : vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
5339 7 : tree binfo;
5340 7 : unsigned i;
5341 :
5342 : /* Virtual bases are initialized first */
5343 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5344 13 : if (BINFO_VIRTUAL_P (binfo))
5345 2 : vec_safe_push (vector, binfo);
5346 :
5347 : /* Now non-virtuals */
5348 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5349 13 : if (!BINFO_VIRTUAL_P (binfo))
5350 11 : vec_safe_push (vector, binfo);
5351 :
5352 7 : tree bases_vec = make_tree_vec (vector->length ());
5353 :
5354 27 : for (i = 0; i < vector->length (); ++i)
5355 13 : TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
5356 :
5357 7 : return bases_vec;
5358 7 : }
5359 :
5360 : /* Implement the __bases keyword: Return the base classes
5361 : of type */
5362 :
5363 : /* Find morally non-virtual base classes by walking binfo hierarchy */
5364 : /* Virtual base classes are handled separately in finish_bases */
5365 :
5366 : static tree
5367 73 : dfs_calculate_bases_pre (tree binfo, void * /*data_*/)
5368 : {
5369 : /* Don't walk bases of virtual bases */
5370 73 : return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE;
5371 : }
5372 :
5373 : static tree
5374 73 : dfs_calculate_bases_post (tree binfo, void *data_)
5375 : {
5376 73 : vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
5377 73 : if (!BINFO_VIRTUAL_P (binfo))
5378 48 : vec_safe_push (*data, BINFO_TYPE (binfo));
5379 73 : return NULL_TREE;
5380 : }
5381 :
5382 : /* Calculates the morally non-virtual base classes of a class */
5383 : static vec<tree, va_gc> *
5384 16 : calculate_bases_helper (tree type)
5385 : {
5386 16 : vec<tree, va_gc> *vector = make_tree_vector ();
5387 :
5388 : /* Now add non-virtual base classes in order of construction */
5389 16 : if (TYPE_BINFO (type))
5390 16 : dfs_walk_all (TYPE_BINFO (type),
5391 : dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector);
5392 16 : return vector;
5393 : }
5394 :
5395 : tree
5396 12 : calculate_bases (tree type, tsubst_flags_t complain)
5397 : {
5398 12 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5399 12 : || !NON_UNION_CLASS_TYPE_P (type))
5400 5 : return make_tree_vec (0);
5401 :
5402 7 : releasing_vec vector;
5403 7 : tree bases_vec = NULL_TREE;
5404 7 : unsigned i;
5405 7 : vec<tree, va_gc> *vbases;
5406 7 : tree binfo;
5407 :
5408 : /* First go through virtual base classes */
5409 7 : for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
5410 16 : vec_safe_iterate (vbases, i, &binfo); i++)
5411 : {
5412 9 : releasing_vec vbase_bases
5413 9 : = calculate_bases_helper (BINFO_TYPE (binfo));
5414 9 : vec_safe_splice (vector, vbase_bases);
5415 9 : }
5416 :
5417 : /* Now for the non-virtual bases */
5418 7 : releasing_vec nonvbases = calculate_bases_helper (type);
5419 7 : vec_safe_splice (vector, nonvbases);
5420 :
5421 : /* Note that during error recovery vector->length can even be zero. */
5422 7 : if (vector->length () > 1)
5423 : {
5424 : /* Last element is entire class, so don't copy */
5425 6 : bases_vec = make_tree_vec (vector->length () - 1);
5426 :
5427 53 : for (i = 0; i < vector->length () - 1; ++i)
5428 41 : TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
5429 : }
5430 : else
5431 1 : bases_vec = make_tree_vec (0);
5432 :
5433 7 : return bases_vec;
5434 7 : }
5435 :
5436 : tree
5437 28 : finish_bases (tree type, bool direct)
5438 : {
5439 28 : tree bases = NULL_TREE;
5440 :
5441 28 : if (!processing_template_decl)
5442 : {
5443 : /* Parameter packs can only be used in templates */
5444 0 : error ("parameter pack %<__bases%> only valid in template declaration");
5445 0 : return error_mark_node;
5446 : }
5447 :
5448 28 : bases = cxx_make_type (BASES);
5449 28 : BASES_TYPE (bases) = type;
5450 28 : BASES_DIRECT (bases) = direct;
5451 28 : SET_TYPE_STRUCTURAL_EQUALITY (bases);
5452 :
5453 28 : return bases;
5454 : }
5455 :
5456 : /* Perform C++-specific checks for __builtin_offsetof before calling
5457 : fold_offsetof. */
5458 :
5459 : tree
5460 2419 : finish_offsetof (tree object_ptr, tree expr, location_t loc)
5461 : {
5462 : /* If we're processing a template, we can't finish the semantics yet.
5463 : Otherwise we can fold the entire expression now. */
5464 2419 : if (processing_template_decl)
5465 : {
5466 60 : expr = build2 (OFFSETOF_EXPR, size_type_node, expr, object_ptr);
5467 60 : SET_EXPR_LOCATION (expr, loc);
5468 60 : return expr;
5469 : }
5470 :
5471 2359 : if (expr == error_mark_node)
5472 : return error_mark_node;
5473 :
5474 2342 : if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
5475 : {
5476 6 : error ("cannot apply %<offsetof%> to destructor %<~%T%>",
5477 6 : TREE_OPERAND (expr, 2));
5478 6 : return error_mark_node;
5479 : }
5480 4657 : if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr))
5481 4657 : || TREE_TYPE (expr) == unknown_type_node)
5482 : {
5483 30 : while (TREE_CODE (expr) == COMPONENT_REF
5484 30 : || TREE_CODE (expr) == COMPOUND_EXPR)
5485 12 : expr = TREE_OPERAND (expr, 1);
5486 :
5487 18 : if (DECL_P (expr))
5488 : {
5489 0 : auto_diagnostic_group d;
5490 0 : error ("cannot apply %<offsetof%> to member function %qD", expr);
5491 0 : inform (DECL_SOURCE_LOCATION (expr), "declared here");
5492 0 : }
5493 : else
5494 18 : error ("cannot apply %<offsetof%> to member function");
5495 18 : return error_mark_node;
5496 : }
5497 2318 : if (TREE_CODE (expr) == CONST_DECL)
5498 : {
5499 3 : error ("cannot apply %<offsetof%> to an enumerator %qD", expr);
5500 3 : return error_mark_node;
5501 : }
5502 2315 : if (REFERENCE_REF_P (expr))
5503 9 : expr = TREE_OPERAND (expr, 0);
5504 2315 : if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr))
5505 3 : return error_mark_node;
5506 2312 : if (warn_invalid_offsetof
5507 2312 : && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
5508 2312 : && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
5509 2357 : && cp_unevaluated_operand == 0)
5510 45 : warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within "
5511 : "non-standard-layout type %qT is conditionally-supported",
5512 45 : TREE_TYPE (TREE_TYPE (object_ptr)));
5513 2312 : return fold_offsetof (expr);
5514 : }
5515 :
5516 : /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
5517 : function is broken out from the above for the benefit of the tree-ssa
5518 : project. */
5519 :
5520 : void
5521 358762 : simplify_aggr_init_expr (tree *tp)
5522 : {
5523 358762 : tree aggr_init_expr = *tp;
5524 :
5525 : /* Form an appropriate CALL_EXPR. */
5526 358762 : tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
5527 358762 : tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
5528 358762 : tree type = TREE_TYPE (slot);
5529 :
5530 358762 : tree call_expr;
5531 358762 : enum style_t { ctor, arg, pcc } style;
5532 :
5533 358762 : if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
5534 : style = ctor;
5535 : #ifdef PCC_STATIC_STRUCT_RETURN
5536 : else if (1)
5537 : style = pcc;
5538 : #endif
5539 : else
5540 : {
5541 96075 : gcc_assert (TREE_ADDRESSABLE (type));
5542 : style = arg;
5543 : }
5544 :
5545 358762 : call_expr = build_call_array_loc (input_location,
5546 358762 : TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
5547 : fn,
5548 358762 : aggr_init_expr_nargs (aggr_init_expr),
5549 358762 : AGGR_INIT_EXPR_ARGP (aggr_init_expr));
5550 358762 : TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
5551 358762 : CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr);
5552 358762 : CALL_EXPR_OPERATOR_SYNTAX (call_expr)
5553 358762 : = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
5554 358762 : CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
5555 358762 : CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
5556 358762 : CALL_EXPR_MUST_TAIL_CALL (call_expr) = AGGR_INIT_EXPR_MUST_TAIL (aggr_init_expr);
5557 :
5558 358762 : if (style == ctor)
5559 : {
5560 : /* Replace the first argument to the ctor with the address of the
5561 : slot. */
5562 262687 : cxx_mark_addressable (slot);
5563 262687 : CALL_EXPR_ARG (call_expr, 0) =
5564 262687 : build1 (ADDR_EXPR, build_pointer_type (type), slot);
5565 : }
5566 96075 : else if (style == arg)
5567 : {
5568 : /* Just mark it addressable here, and leave the rest to
5569 : expand_call{,_inline}. */
5570 96075 : cxx_mark_addressable (slot);
5571 96075 : CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
5572 96075 : call_expr = cp_build_init_expr (slot, call_expr);
5573 : }
5574 : else if (style == pcc)
5575 : {
5576 : /* If we're using the non-reentrant PCC calling convention, then we
5577 : need to copy the returned value out of the static buffer into the
5578 : SLOT. */
5579 : push_deferring_access_checks (dk_no_check);
5580 : call_expr = build_aggr_init (slot, call_expr,
5581 : DIRECT_BIND | LOOKUP_ONLYCONVERTING,
5582 : tf_warning_or_error);
5583 : pop_deferring_access_checks ();
5584 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
5585 : }
5586 :
5587 358762 : if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
5588 : {
5589 4125 : tree init = build_zero_init (type, NULL_TREE,
5590 : /*static_storage_p=*/false);
5591 4125 : init = cp_build_init_expr (slot, init);
5592 4125 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
5593 : init, call_expr);
5594 : }
5595 :
5596 358762 : *tp = call_expr;
5597 358762 : }
5598 :
5599 : /* Emit all thunks to FN that should be emitted when FN is emitted. */
5600 :
5601 : void
5602 60519786 : emit_associated_thunks (tree fn)
5603 : {
5604 : /* When we use vcall offsets, we emit thunks with the virtual
5605 : functions to which they thunk. The whole point of vcall offsets
5606 : is so that you can know statically the entire set of thunks that
5607 : will ever be needed for a given virtual function, thereby
5608 : enabling you to output all the thunks with the function itself. */
5609 60519786 : if (DECL_VIRTUAL_P (fn)
5610 : /* Do not emit thunks for extern template instantiations. */
5611 1152954 : && ! DECL_REALLY_EXTERN (fn)
5612 : /* Do not emit thunks for tentative decls, those will be processed
5613 : again at_eof if really needed. */
5614 61557934 : && (DECL_INTERFACE_KNOWN (fn) || !DECL_DEFER_OUTPUT (fn)))
5615 : {
5616 1037106 : tree thunk;
5617 :
5618 2078445 : for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
5619 : {
5620 4233 : if (!THUNK_ALIAS (thunk))
5621 : {
5622 4233 : use_thunk (thunk, /*emit_p=*/1);
5623 4233 : if (DECL_RESULT_THUNK_P (thunk))
5624 : {
5625 178 : tree probe;
5626 :
5627 178 : for (probe = DECL_THUNKS (thunk);
5628 327 : probe; probe = DECL_CHAIN (probe))
5629 149 : use_thunk (probe, /*emit_p=*/1);
5630 : }
5631 : }
5632 : else
5633 0 : gcc_assert (!DECL_THUNKS (thunk));
5634 : }
5635 : }
5636 60519786 : }
5637 :
5638 : /* Generate RTL for FN. */
5639 :
5640 : bool
5641 164607426 : expand_or_defer_fn_1 (tree fn)
5642 : {
5643 : /* When the parser calls us after finishing the body of a template
5644 : function, we don't really want to expand the body. */
5645 164607426 : if (processing_template_decl)
5646 : {
5647 : /* Normally, collection only occurs in rest_of_compilation. So,
5648 : if we don't collect here, we never collect junk generated
5649 : during the processing of templates until we hit a
5650 : non-template function. It's not safe to do this inside a
5651 : nested class, though, as the parser may have local state that
5652 : is not a GC root. */
5653 95994202 : if (!function_depth)
5654 95539016 : ggc_collect ();
5655 95994202 : return false;
5656 : }
5657 :
5658 68613224 : gcc_assert (DECL_SAVED_TREE (fn));
5659 :
5660 : /* We make a decision about linkage for these functions at the end
5661 : of the compilation. Until that point, we do not want the back
5662 : end to output them -- but we do want it to see the bodies of
5663 : these functions so that it can inline them as appropriate. */
5664 68613224 : if (DECL_DECLARED_INLINE_P (fn)
5665 1936021 : || DECL_IMPLICIT_INSTANTIATION (fn)
5666 68875220 : || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
5667 : {
5668 68351255 : if (DECL_INTERFACE_KNOWN (fn))
5669 : /* We've already made a decision as to how this function will
5670 : be handled. */;
5671 48379111 : else if (!at_eof
5672 17462221 : || DECL_IMMEDIATE_FUNCTION_P (fn)
5673 65375897 : || DECL_OMP_DECLARE_REDUCTION_P (fn))
5674 31382325 : tentative_decl_linkage (fn);
5675 : else
5676 16996786 : import_export_decl (fn);
5677 :
5678 : /* If the user wants us to keep all inline functions, then mark
5679 : this function as needed so that finish_file will make sure to
5680 : output it later. Similarly, all dllexport'd functions must
5681 : be emitted; there may be callers in other DLLs. */
5682 68351255 : if (DECL_DECLARED_INLINE_P (fn)
5683 66677203 : && !DECL_REALLY_EXTERN (fn)
5684 63010378 : && !DECL_IMMEDIATE_FUNCTION_P (fn)
5685 61888006 : && !DECL_OMP_DECLARE_REDUCTION_P (fn)
5686 130239261 : && (flag_keep_inline_functions
5687 61885216 : || (flag_keep_inline_dllexport
5688 61885216 : && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))))
5689 : {
5690 2790 : mark_needed (fn);
5691 2790 : DECL_EXTERNAL (fn) = 0;
5692 : }
5693 : }
5694 :
5695 : /* If this is a constructor or destructor body, we have to clone
5696 : it. */
5697 68613224 : if (maybe_clone_body (fn))
5698 : {
5699 : /* We don't want to process FN again, so pretend we've written
5700 : it out, even though we haven't. */
5701 8065238 : TREE_ASM_WRITTEN (fn) = 1;
5702 : /* If this is a constexpr function we still need the body to be
5703 : able to evaluate it. Similarly, with modules we only stream
5704 : the maybe-in-charge cdtor and regenerate the clones from it on
5705 : demand, so we also need to keep the body. Otherwise we don't
5706 : need it anymore. */
5707 8065238 : if (!maybe_constexpr_fn (fn)
5708 8065238 : && !(module_maybe_has_cmi_p () && vague_linkage_p (fn)))
5709 3778653 : DECL_SAVED_TREE (fn) = void_node;
5710 8065238 : return false;
5711 : }
5712 :
5713 : /* There's no reason to do any of the work here if we're only doing
5714 : semantic analysis; this code just generates RTL. */
5715 60547986 : if (flag_syntax_only)
5716 : {
5717 : /* Pretend that this function has been written out so that we don't try
5718 : to expand it again. */
5719 28184 : TREE_ASM_WRITTEN (fn) = 1;
5720 28184 : return false;
5721 : }
5722 :
5723 60519802 : if (DECL_OMP_DECLARE_REDUCTION_P (fn))
5724 : return false;
5725 :
5726 : return true;
5727 : }
5728 :
5729 : void
5730 156567443 : expand_or_defer_fn (tree fn)
5731 : {
5732 156567443 : if (expand_or_defer_fn_1 (fn))
5733 : {
5734 52482294 : function_depth++;
5735 :
5736 : /* Expand or defer, at the whim of the compilation unit manager. */
5737 52482294 : cgraph_node::finalize_function (fn, function_depth > 1);
5738 52482294 : emit_associated_thunks (fn);
5739 :
5740 52482294 : function_depth--;
5741 :
5742 104964588 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
5743 : {
5744 1062078 : if (cgraph_node *node = cgraph_node::get (fn))
5745 : {
5746 1062078 : node->body_removed = true;
5747 1062078 : node->analyzed = false;
5748 1062078 : node->definition = false;
5749 1062078 : node->force_output = false;
5750 : }
5751 : }
5752 : }
5753 156567443 : }
5754 :
5755 458608 : class nrv_data
5756 : {
5757 : public:
5758 229304 : nrv_data () : visited (37) {}
5759 :
5760 : tree var;
5761 : tree result;
5762 : hash_set<tree> visited;
5763 : bool simple;
5764 : bool in_nrv_cleanup;
5765 : };
5766 :
5767 : /* Helper function for walk_tree, used by finalize_nrv below. */
5768 :
5769 : static tree
5770 20875940 : finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
5771 : {
5772 20875940 : class nrv_data *dp = (class nrv_data *)data;
5773 :
5774 : /* No need to walk into types. There wouldn't be any need to walk into
5775 : non-statements, except that we have to consider STMT_EXPRs. */
5776 20875940 : if (TYPE_P (*tp))
5777 189897 : *walk_subtrees = 0;
5778 :
5779 : /* Replace all uses of the NRV with the RESULT_DECL. */
5780 20686043 : else if (*tp == dp->var)
5781 498562 : *tp = dp->result;
5782 :
5783 : /* Avoid walking into the same tree more than once. Unfortunately, we
5784 : can't just use walk_tree_without duplicates because it would only call
5785 : us for the first occurrence of dp->var in the function body. */
5786 20187481 : else if (dp->visited.add (*tp))
5787 4432890 : *walk_subtrees = 0;
5788 :
5789 : /* If there's a label, we might need to destroy the NRV on goto (92407). */
5790 15754591 : else if (TREE_CODE (*tp) == LABEL_EXPR && !dp->in_nrv_cleanup)
5791 3 : dp->simple = false;
5792 : /* Change NRV returns to just refer to the RESULT_DECL; this is a nop,
5793 : but differs from using NULL_TREE in that it indicates that we care
5794 : about the value of the RESULT_DECL. But preserve anything appended
5795 : by check_return_expr. */
5796 15754588 : else if (TREE_CODE (*tp) == RETURN_EXPR)
5797 : {
5798 235419 : tree *p = &TREE_OPERAND (*tp, 0);
5799 603481 : while (TREE_CODE (*p) == COMPOUND_EXPR)
5800 132643 : p = &TREE_OPERAND (*p, 0);
5801 235419 : if (TREE_CODE (*p) == INIT_EXPR
5802 235419 : && INIT_EXPR_NRV_P (*p))
5803 234999 : *p = dp->result;
5804 : }
5805 : /* Change all cleanups for the NRV to only run when not returning. */
5806 15519169 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5807 15519169 : && CLEANUP_DECL (*tp) == dp->var)
5808 : {
5809 127559 : dp->in_nrv_cleanup = true;
5810 127559 : cp_walk_tree (&CLEANUP_BODY (*tp), finalize_nrv_r, data, 0);
5811 127559 : dp->in_nrv_cleanup = false;
5812 127559 : cp_walk_tree (&CLEANUP_EXPR (*tp), finalize_nrv_r, data, 0);
5813 127559 : *walk_subtrees = 0;
5814 :
5815 127559 : if (dp->simple)
5816 : /* For a simple NRV, just run it on the EH path. */
5817 126896 : CLEANUP_EH_ONLY (*tp) = true;
5818 : else
5819 : {
5820 : /* Not simple, we need to check current_retval_sentinel to decide
5821 : whether to run it. If it's set, we're returning normally and
5822 : don't want to destroy the NRV. If the sentinel is not set, we're
5823 : leaving scope some other way, either by flowing off the end of its
5824 : scope or throwing an exception. */
5825 1989 : tree cond = build3 (COND_EXPR, void_type_node,
5826 663 : current_retval_sentinel,
5827 663 : void_node, CLEANUP_EXPR (*tp));
5828 663 : CLEANUP_EXPR (*tp) = cond;
5829 : }
5830 :
5831 : /* If a cleanup might throw, we need to clear current_retval_sentinel on
5832 : the exception path, both so the check above succeeds and so an outer
5833 : cleanup added by maybe_splice_retval_cleanup doesn't run. */
5834 127559 : if (cp_function_chain->throwing_cleanup)
5835 : {
5836 174 : tree clear = build2 (MODIFY_EXPR, boolean_type_node,
5837 : current_retval_sentinel,
5838 : boolean_false_node);
5839 174 : if (dp->simple)
5840 : {
5841 : /* We're already only on the EH path, just prepend it. */
5842 164 : tree &exp = CLEANUP_EXPR (*tp);
5843 164 : exp = build2 (COMPOUND_EXPR, void_type_node, clear, exp);
5844 : }
5845 : else
5846 : {
5847 : /* The cleanup runs on both normal and EH paths, we need another
5848 : CLEANUP_STMT to clear the flag only on the EH path. */
5849 10 : tree &bod = CLEANUP_BODY (*tp);
5850 10 : bod = build_stmt (EXPR_LOCATION (*tp), CLEANUP_STMT,
5851 10 : bod, clear, current_retval_sentinel);
5852 10 : CLEANUP_EH_ONLY (bod) = true;
5853 : }
5854 : }
5855 : }
5856 : /* Disable maybe_splice_retval_cleanup within the NRV cleanup scope, we don't
5857 : want to destroy the retval before the variable goes out of scope. */
5858 15391610 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5859 4925 : && dp->in_nrv_cleanup
5860 15395118 : && CLEANUP_DECL (*tp) == dp->result)
5861 6 : CLEANUP_EXPR (*tp) = void_node;
5862 : /* Replace the DECL_EXPR for the NRV with an initialization of the
5863 : RESULT_DECL, if needed. */
5864 15391604 : else if (TREE_CODE (*tp) == DECL_EXPR
5865 15391604 : && DECL_EXPR_DECL (*tp) == dp->var)
5866 : {
5867 229306 : tree init;
5868 229306 : if (DECL_INITIAL (dp->var)
5869 229306 : && DECL_INITIAL (dp->var) != error_mark_node)
5870 94075 : init = cp_build_init_expr (dp->result,
5871 94075 : DECL_INITIAL (dp->var));
5872 : else
5873 135231 : init = build_empty_stmt (EXPR_LOCATION (*tp));
5874 229306 : DECL_INITIAL (dp->var) = NULL_TREE;
5875 229306 : SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
5876 229306 : *tp = init;
5877 : }
5878 :
5879 : /* Keep iterating. */
5880 20875940 : return NULL_TREE;
5881 : }
5882 :
5883 : /* Called from finish_function to implement the named return value
5884 : optimization by overriding all the RETURN_EXPRs and pertinent
5885 : CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
5886 : RESULT_DECL for the function. */
5887 :
5888 : void
5889 229304 : finalize_nrv (tree fndecl, tree var)
5890 : {
5891 229304 : class nrv_data data;
5892 229304 : tree result = DECL_RESULT (fndecl);
5893 :
5894 : /* Copy name from VAR to RESULT. */
5895 229304 : DECL_NAME (result) = DECL_NAME (var);
5896 : /* Don't forget that we take its address. */
5897 229304 : TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
5898 : /* Finally set DECL_VALUE_EXPR to avoid assigning
5899 : a stack slot at -O0 for the original var and debug info
5900 : uses RESULT location for VAR. */
5901 229304 : SET_DECL_VALUE_EXPR (var, result);
5902 229304 : DECL_HAS_VALUE_EXPR_P (var) = 1;
5903 :
5904 229304 : data.var = var;
5905 229304 : data.result = result;
5906 229304 : data.in_nrv_cleanup = false;
5907 :
5908 : /* This is simpler for variables declared in the outer scope of
5909 : the function so we know that their lifetime always ends with a
5910 : return; see g++.dg/opt/nrv6.C. */
5911 229304 : tree outer = outer_curly_brace_block (fndecl);
5912 229304 : data.simple = chain_member (var, BLOCK_VARS (outer));
5913 :
5914 229304 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), finalize_nrv_r, &data, 0);
5915 229304 : }
5916 :
5917 : /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */
5918 :
5919 : bool
5920 2249 : cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
5921 : bool need_copy_ctor, bool need_copy_assignment,
5922 : bool need_dtor)
5923 : {
5924 2249 : int save_errorcount = errorcount;
5925 2249 : tree info, t;
5926 :
5927 : /* Always allocate 3 elements for simplicity. These are the
5928 : function decls for the ctor, dtor, and assignment op.
5929 : This layout is known to the three lang hooks,
5930 : cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
5931 : and cxx_omp_clause_assign_op. */
5932 2249 : info = make_tree_vec (3);
5933 2249 : CP_OMP_CLAUSE_INFO (c) = info;
5934 :
5935 2249 : if (need_default_ctor || need_copy_ctor)
5936 : {
5937 1654 : if (need_default_ctor)
5938 1255 : t = get_default_ctor (type);
5939 : else
5940 399 : t = get_copy_ctor (type, tf_warning_or_error);
5941 :
5942 1654 : if (t && !trivial_fn_p (t))
5943 1400 : TREE_VEC_ELT (info, 0) = t;
5944 : }
5945 :
5946 2249 : if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
5947 1632 : TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error);
5948 :
5949 2249 : if (need_copy_assignment)
5950 : {
5951 397 : t = get_copy_assign (type);
5952 :
5953 397 : if (t && !trivial_fn_p (t))
5954 344 : TREE_VEC_ELT (info, 2) = t;
5955 : }
5956 :
5957 2249 : return errorcount != save_errorcount;
5958 : }
5959 :
5960 : /* If DECL is DECL_OMP_PRIVATIZED_MEMBER, return corresponding
5961 : FIELD_DECL, otherwise return DECL itself. */
5962 :
5963 : static tree
5964 26332 : omp_clause_decl_field (tree decl)
5965 : {
5966 26332 : if (VAR_P (decl)
5967 18479 : && DECL_HAS_VALUE_EXPR_P (decl)
5968 359 : && DECL_ARTIFICIAL (decl)
5969 359 : && DECL_LANG_SPECIFIC (decl)
5970 26667 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
5971 : {
5972 328 : tree f = DECL_VALUE_EXPR (decl);
5973 328 : if (INDIRECT_REF_P (f))
5974 0 : f = TREE_OPERAND (f, 0);
5975 328 : if (TREE_CODE (f) == COMPONENT_REF)
5976 : {
5977 328 : f = TREE_OPERAND (f, 1);
5978 328 : gcc_assert (TREE_CODE (f) == FIELD_DECL);
5979 : return f;
5980 : }
5981 : }
5982 : return NULL_TREE;
5983 : }
5984 :
5985 : /* Adjust DECL if needed for printing using %qE. */
5986 :
5987 : static tree
5988 187 : omp_clause_printable_decl (tree decl)
5989 : {
5990 0 : tree t = omp_clause_decl_field (decl);
5991 187 : if (t)
5992 45 : return t;
5993 : return decl;
5994 : }
5995 :
5996 : /* For a FIELD_DECL F and corresponding DECL_OMP_PRIVATIZED_MEMBER
5997 : VAR_DECL T that doesn't need a DECL_EXPR added, record it for
5998 : privatization. */
5999 :
6000 : static void
6001 219 : omp_note_field_privatization (tree f, tree t)
6002 : {
6003 219 : if (!omp_private_member_map)
6004 71 : omp_private_member_map = new hash_map<tree, tree>;
6005 219 : tree &v = omp_private_member_map->get_or_insert (f);
6006 219 : if (v == NULL_TREE)
6007 : {
6008 146 : v = t;
6009 146 : omp_private_member_vec.safe_push (f);
6010 : /* Signal that we don't want to create DECL_EXPR for this dummy var. */
6011 146 : omp_private_member_vec.safe_push (integer_zero_node);
6012 : }
6013 219 : }
6014 :
6015 : /* Privatize FIELD_DECL T, return corresponding DECL_OMP_PRIVATIZED_MEMBER
6016 : dummy VAR_DECL. */
6017 :
6018 : tree
6019 861 : omp_privatize_field (tree t, bool shared)
6020 : {
6021 861 : tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6022 861 : if (m == error_mark_node)
6023 : return error_mark_node;
6024 861 : if (!omp_private_member_map && !shared)
6025 365 : omp_private_member_map = new hash_map<tree, tree>;
6026 861 : if (TYPE_REF_P (TREE_TYPE (t)))
6027 : {
6028 123 : gcc_assert (INDIRECT_REF_P (m));
6029 123 : m = TREE_OPERAND (m, 0);
6030 : }
6031 861 : tree vb = NULL_TREE;
6032 861 : tree &v = shared ? vb : omp_private_member_map->get_or_insert (t);
6033 861 : if (v == NULL_TREE)
6034 : {
6035 770 : v = create_temporary_var (TREE_TYPE (m));
6036 770 : retrofit_lang_decl (v);
6037 770 : DECL_OMP_PRIVATIZED_MEMBER (v) = 1;
6038 770 : SET_DECL_VALUE_EXPR (v, m);
6039 770 : DECL_HAS_VALUE_EXPR_P (v) = 1;
6040 770 : if (!shared)
6041 690 : omp_private_member_vec.safe_push (t);
6042 : }
6043 861 : return v;
6044 : }
6045 :
6046 : /* C++ specialisation of the c_omp_address_inspector class. */
6047 :
6048 : class cp_omp_address_inspector : public c_omp_address_inspector
6049 : {
6050 : public:
6051 30924 : cp_omp_address_inspector (location_t loc, tree t)
6052 30924 : : c_omp_address_inspector (loc, t)
6053 : {
6054 : }
6055 :
6056 30924 : ~cp_omp_address_inspector ()
6057 : {
6058 22615 : }
6059 :
6060 131292 : bool processing_template_decl_p ()
6061 : {
6062 131292 : return processing_template_decl;
6063 : }
6064 :
6065 0 : void emit_unmappable_type_notes (tree t)
6066 : {
6067 0 : if (TREE_TYPE (t) != error_mark_node
6068 0 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
6069 0 : cxx_incomplete_type_inform (TREE_TYPE (t));
6070 0 : }
6071 :
6072 1062 : tree convert_from_reference (tree x)
6073 : {
6074 1062 : return ::convert_from_reference (x);
6075 : }
6076 :
6077 145 : tree build_array_ref (location_t loc, tree arr, tree idx)
6078 : {
6079 145 : return ::build_array_ref (loc, arr, idx);
6080 : }
6081 :
6082 22557 : bool check_clause (tree clause)
6083 : {
6084 22557 : if (TREE_CODE (orig) == COMPONENT_REF
6085 22557 : && invalid_nonstatic_memfn_p (EXPR_LOCATION (orig), orig,
6086 : tf_warning_or_error))
6087 : return false;
6088 22554 : if (!c_omp_address_inspector::check_clause (clause))
6089 : return false;
6090 : return true;
6091 : }
6092 : };
6093 :
6094 : /* Helper function for handle_omp_array_sections. Called recursively
6095 : to handle multiple array-section-subscripts. C is the clause,
6096 : T current expression (initially OMP_CLAUSE_DECL), which is either
6097 : a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound
6098 : expression if specified, TREE_VALUE length expression if specified,
6099 : TREE_CHAIN is what it has been specified after, or some decl.
6100 : TYPES vector is populated with array section types, MAYBE_ZERO_LEN
6101 : set to true if any of the array-section-subscript could have length
6102 : of zero (explicit or implicit), FIRST_NON_ONE is the index of the
6103 : first array-section-subscript which is known not to have length
6104 : of one. Given say:
6105 : map(a[:b][2:1][:c][:2][:d][e:f][2:5])
6106 : FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c]
6107 : all are or may have length of 1, array-section-subscript [:2] is the
6108 : first one known not to have length 1. For array-section-subscript
6109 : <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't
6110 : 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we
6111 : can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above
6112 : case though, as some lengths could be zero. */
6113 :
6114 : static tree
6115 20474 : handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
6116 : bool &maybe_zero_len, unsigned int &first_non_one,
6117 : enum c_omp_region_type ort)
6118 : {
6119 20474 : tree ret, low_bound, length, type;
6120 20474 : bool openacc = (ort & C_ORT_ACC) != 0;
6121 20474 : if (TREE_CODE (t) != OMP_ARRAY_SECTION)
6122 : {
6123 9279 : if (error_operand_p (t))
6124 6 : return error_mark_node;
6125 :
6126 9273 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6127 9273 : tree t_refto = ai.maybe_unconvert_ref (t);
6128 :
6129 9273 : if (!ai.check_clause (c))
6130 0 : return error_mark_node;
6131 9273 : else if (ai.component_access_p ()
6132 10661 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6133 64 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
6134 40 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
6135 1388 : t = ai.get_root_term (true);
6136 : else
6137 7885 : t = ai.unconverted_ref_origin ();
6138 9273 : if (t == error_mark_node)
6139 : return error_mark_node;
6140 9273 : ret = t_refto;
6141 9273 : if (TREE_CODE (t) == FIELD_DECL)
6142 33 : ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6143 9240 : else if (!VAR_P (t)
6144 2700 : && (openacc || !EXPR_P (t))
6145 2505 : && TREE_CODE (t) != PARM_DECL)
6146 : {
6147 48 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
6148 : return NULL_TREE;
6149 30 : if (DECL_P (t))
6150 30 : error_at (OMP_CLAUSE_LOCATION (c),
6151 : "%qD is not a variable in %qs clause", t,
6152 30 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6153 : else
6154 0 : error_at (OMP_CLAUSE_LOCATION (c),
6155 : "%qE is not a variable in %qs clause", t,
6156 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6157 30 : return error_mark_node;
6158 : }
6159 9192 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6160 9002 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6161 17265 : && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
6162 : {
6163 17 : error_at (OMP_CLAUSE_LOCATION (c),
6164 : "%qD is threadprivate variable in %qs clause", t,
6165 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6166 17 : return error_mark_node;
6167 : }
6168 9208 : if (type_dependent_expression_p (ret))
6169 : return NULL_TREE;
6170 8521 : ret = convert_from_reference (ret);
6171 8521 : return ret;
6172 9273 : }
6173 :
6174 11195 : if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
6175 7392 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6176 6198 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6177 4914 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6178 13801 : && TREE_CODE (TREE_OPERAND (t, 0)) == FIELD_DECL)
6179 43 : TREE_OPERAND (t, 0) = omp_privatize_field (TREE_OPERAND (t, 0), false);
6180 11195 : ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
6181 : maybe_zero_len, first_non_one, ort);
6182 11195 : if (ret == error_mark_node || ret == NULL_TREE)
6183 : return ret;
6184 :
6185 10191 : type = TREE_TYPE (ret);
6186 10191 : low_bound = TREE_OPERAND (t, 1);
6187 10191 : length = TREE_OPERAND (t, 2);
6188 8244 : if ((low_bound && type_dependent_expression_p (low_bound))
6189 18352 : || (length && type_dependent_expression_p (length)))
6190 88 : return NULL_TREE;
6191 :
6192 10103 : if (low_bound == error_mark_node || length == error_mark_node)
6193 : return error_mark_node;
6194 :
6195 10103 : if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound)))
6196 : {
6197 69 : error_at (OMP_CLAUSE_LOCATION (c),
6198 : "low bound %qE of array section does not have integral type",
6199 : low_bound);
6200 69 : return error_mark_node;
6201 : }
6202 10034 : if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length)))
6203 : {
6204 63 : error_at (OMP_CLAUSE_LOCATION (c),
6205 : "length %qE of array section does not have integral type",
6206 : length);
6207 63 : return error_mark_node;
6208 : }
6209 9971 : if (low_bound)
6210 8078 : low_bound = mark_rvalue_use (low_bound);
6211 9971 : if (length)
6212 9025 : length = mark_rvalue_use (length);
6213 : /* We need to reduce to real constant-values for checks below. */
6214 9025 : if (length)
6215 9025 : length = fold_simple (length);
6216 9971 : if (low_bound)
6217 8078 : low_bound = fold_simple (low_bound);
6218 8078 : if (low_bound
6219 8078 : && TREE_CODE (low_bound) == INTEGER_CST
6220 15231 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6221 7153 : > TYPE_PRECISION (sizetype))
6222 0 : low_bound = fold_convert (sizetype, low_bound);
6223 9971 : if (length
6224 9025 : && TREE_CODE (length) == INTEGER_CST
6225 16985 : && TYPE_PRECISION (TREE_TYPE (length))
6226 7014 : > TYPE_PRECISION (sizetype))
6227 0 : length = fold_convert (sizetype, length);
6228 9971 : if (low_bound == NULL_TREE)
6229 1893 : low_bound = integer_zero_node;
6230 :
6231 9971 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6232 9971 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
6233 5086 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
6234 : {
6235 60 : if (length != integer_one_node)
6236 : {
6237 36 : error_at (OMP_CLAUSE_LOCATION (c),
6238 : "expected single pointer in %qs clause",
6239 : user_omp_clause_code_name (c, openacc));
6240 36 : return error_mark_node;
6241 : }
6242 : }
6243 9935 : if (length != NULL_TREE)
6244 : {
6245 9013 : if (!integer_nonzerop (length))
6246 : {
6247 2058 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6248 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6249 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6250 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6251 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6252 : {
6253 459 : if (integer_zerop (length))
6254 : {
6255 28 : error_at (OMP_CLAUSE_LOCATION (c),
6256 : "zero length array section in %qs clause",
6257 28 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6258 28 : return error_mark_node;
6259 : }
6260 : }
6261 : else
6262 1599 : maybe_zero_len = true;
6263 : }
6264 8985 : if (first_non_one == types.length ()
6265 8985 : && (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
6266 3928 : first_non_one++;
6267 : }
6268 9907 : if (TREE_CODE (type) == ARRAY_TYPE)
6269 : {
6270 5461 : if (length == NULL_TREE
6271 5461 : && (TYPE_DOMAIN (type) == NULL_TREE
6272 850 : || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE))
6273 : {
6274 30 : error_at (OMP_CLAUSE_LOCATION (c),
6275 : "for unknown bound array type length expression must "
6276 : "be specified");
6277 30 : return error_mark_node;
6278 : }
6279 5431 : if (TREE_CODE (low_bound) == INTEGER_CST
6280 5431 : && tree_int_cst_sgn (low_bound) == -1)
6281 : {
6282 153 : error_at (OMP_CLAUSE_LOCATION (c),
6283 : "negative low bound in array section in %qs clause",
6284 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6285 153 : return error_mark_node;
6286 : }
6287 5278 : if (length != NULL_TREE
6288 4476 : && TREE_CODE (length) == INTEGER_CST
6289 8836 : && tree_int_cst_sgn (length) == -1)
6290 : {
6291 153 : error_at (OMP_CLAUSE_LOCATION (c),
6292 : "negative length in array section in %qs clause",
6293 153 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6294 153 : return error_mark_node;
6295 : }
6296 5125 : if (TYPE_DOMAIN (type)
6297 5031 : && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
6298 10156 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
6299 : == INTEGER_CST)
6300 : {
6301 4635 : tree size
6302 4635 : = fold_convert (sizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
6303 4635 : size = size_binop (PLUS_EXPR, size, size_one_node);
6304 4635 : if (TREE_CODE (low_bound) == INTEGER_CST)
6305 : {
6306 3868 : if (tree_int_cst_lt (size, low_bound))
6307 : {
6308 54 : error_at (OMP_CLAUSE_LOCATION (c),
6309 : "low bound %qE above array section size "
6310 : "in %qs clause", low_bound,
6311 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6312 54 : return error_mark_node;
6313 : }
6314 3814 : if (tree_int_cst_equal (size, low_bound))
6315 : {
6316 17 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6317 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6318 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6319 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6320 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6321 : {
6322 17 : error_at (OMP_CLAUSE_LOCATION (c),
6323 : "zero length array section in %qs clause",
6324 17 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6325 17 : return error_mark_node;
6326 : }
6327 0 : maybe_zero_len = true;
6328 : }
6329 3797 : else if (length == NULL_TREE
6330 1420 : && first_non_one == types.length ()
6331 4095 : && tree_int_cst_equal
6332 298 : (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
6333 : low_bound))
6334 195 : first_non_one++;
6335 : }
6336 767 : else if (length == NULL_TREE)
6337 : {
6338 20 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6339 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6340 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6341 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6342 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6343 13 : maybe_zero_len = true;
6344 40 : if (first_non_one == types.length ())
6345 17 : first_non_one++;
6346 : }
6347 4564 : if (length && TREE_CODE (length) == INTEGER_CST)
6348 : {
6349 3290 : if (tree_int_cst_lt (size, length))
6350 : {
6351 57 : error_at (OMP_CLAUSE_LOCATION (c),
6352 : "length %qE above array section size "
6353 : "in %qs clause", length,
6354 57 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6355 57 : return error_mark_node;
6356 : }
6357 3233 : if (TREE_CODE (low_bound) == INTEGER_CST)
6358 : {
6359 2899 : tree lbpluslen
6360 2899 : = size_binop (PLUS_EXPR,
6361 : fold_convert (sizetype, low_bound),
6362 : fold_convert (sizetype, length));
6363 2899 : if (TREE_CODE (lbpluslen) == INTEGER_CST
6364 2899 : && tree_int_cst_lt (size, lbpluslen))
6365 : {
6366 54 : error_at (OMP_CLAUSE_LOCATION (c),
6367 : "high bound %qE above array section size "
6368 : "in %qs clause", lbpluslen,
6369 54 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6370 54 : return error_mark_node;
6371 : }
6372 : }
6373 : }
6374 : }
6375 490 : else if (length == NULL_TREE)
6376 : {
6377 1 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6378 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6379 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6380 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6381 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6382 0 : maybe_zero_len = true;
6383 2 : if (first_non_one == types.length ())
6384 1 : first_non_one++;
6385 : }
6386 :
6387 : /* For [lb:] we will need to evaluate lb more than once. */
6388 3911 : if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6389 : {
6390 650 : tree lb = cp_save_expr (low_bound);
6391 650 : if (lb != low_bound)
6392 : {
6393 9 : TREE_OPERAND (t, 1) = lb;
6394 9 : low_bound = lb;
6395 : }
6396 : }
6397 : }
6398 4446 : else if (TYPE_PTR_P (type))
6399 : {
6400 4389 : if (length == NULL_TREE)
6401 : {
6402 42 : if (TREE_CODE (ret) == PARM_DECL && DECL_ARRAY_PARAMETER_P (ret))
6403 36 : error_at (OMP_CLAUSE_LOCATION (c),
6404 : "for array function parameter length expression "
6405 : "must be specified");
6406 : else
6407 6 : error_at (OMP_CLAUSE_LOCATION (c),
6408 : "for pointer type length expression must be specified");
6409 42 : return error_mark_node;
6410 : }
6411 4347 : if (length != NULL_TREE
6412 4347 : && TREE_CODE (length) == INTEGER_CST
6413 3254 : && tree_int_cst_sgn (length) == -1)
6414 : {
6415 84 : error_at (OMP_CLAUSE_LOCATION (c),
6416 : "negative length in array section in %qs clause",
6417 84 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6418 84 : return error_mark_node;
6419 : }
6420 : /* If there is a pointer type anywhere but in the very first
6421 : array-section-subscript, the array section could be non-contiguous. */
6422 4263 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6423 4221 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6424 7999 : && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION)
6425 : {
6426 : /* If any prior dimension has a non-one length, then deem this
6427 : array section as non-contiguous. */
6428 158 : for (tree d = TREE_OPERAND (t, 0); TREE_CODE (d) == OMP_ARRAY_SECTION;
6429 69 : d = TREE_OPERAND (d, 0))
6430 : {
6431 89 : tree d_length = TREE_OPERAND (d, 2);
6432 89 : if (d_length == NULL_TREE || !integer_onep (d_length))
6433 : {
6434 20 : error_at (OMP_CLAUSE_LOCATION (c),
6435 : "array section is not contiguous in %qs clause",
6436 20 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6437 20 : return error_mark_node;
6438 : }
6439 : }
6440 : }
6441 : }
6442 : else
6443 : {
6444 57 : error_at (OMP_CLAUSE_LOCATION (c),
6445 : "%qE does not have pointer or array type", ret);
6446 57 : return error_mark_node;
6447 : }
6448 9186 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6449 8281 : types.safe_push (TREE_TYPE (ret));
6450 : /* We will need to evaluate lb more than once. */
6451 9186 : tree lb = cp_save_expr (low_bound);
6452 9186 : if (lb != low_bound)
6453 : {
6454 716 : TREE_OPERAND (t, 1) = lb;
6455 716 : low_bound = lb;
6456 : }
6457 : /* Temporarily disable -fstrong-eval-order for array reductions.
6458 : The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects
6459 : is something the middle-end can't cope with and more importantly,
6460 : it needs to be the actual base variable that is privatized, not some
6461 : temporary assigned previous value of it. That, together with OpenMP
6462 : saying how many times the side-effects are evaluated is unspecified,
6463 : makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified. */
6464 9186 : warning_sentinel s (flag_strong_eval_order,
6465 9186 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6466 8173 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6467 18491 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION);
6468 9186 : ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, NULL,
6469 : tf_warning_or_error);
6470 9186 : return ret;
6471 9186 : }
6472 :
6473 : /* Handle array sections for clause C. */
6474 :
6475 : static bool
6476 9279 : handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
6477 : {
6478 9279 : bool maybe_zero_len = false;
6479 9279 : unsigned int first_non_one = 0;
6480 9279 : auto_vec<tree, 10> types;
6481 9279 : tree *tp = &OMP_CLAUSE_DECL (c);
6482 9279 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6483 8320 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6484 9485 : && OMP_ITERATOR_DECL_P (*tp))
6485 258 : tp = &TREE_VALUE (*tp);
6486 9279 : tree first = handle_omp_array_sections_1 (c, *tp, types,
6487 : maybe_zero_len, first_non_one,
6488 : ort);
6489 9279 : if (first == error_mark_node)
6490 : return true;
6491 8309 : if (first == NULL_TREE)
6492 : return false;
6493 7516 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6494 7516 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6495 : {
6496 851 : tree t = *tp;
6497 851 : tree tem = NULL_TREE;
6498 851 : if (processing_template_decl)
6499 : return false;
6500 : /* Need to evaluate side effects in the length expressions
6501 : if any. */
6502 752 : while (TREE_CODE (t) == TREE_LIST)
6503 : {
6504 0 : if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t)))
6505 : {
6506 0 : if (tem == NULL_TREE)
6507 : tem = TREE_VALUE (t);
6508 : else
6509 0 : tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem),
6510 0 : TREE_VALUE (t), tem);
6511 : }
6512 0 : t = TREE_CHAIN (t);
6513 : }
6514 752 : if (tem)
6515 0 : first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
6516 752 : *tp = first;
6517 : }
6518 : else
6519 : {
6520 6665 : unsigned int num = types.length (), i;
6521 6665 : tree t, side_effects = NULL_TREE, size = NULL_TREE;
6522 6665 : tree condition = NULL_TREE;
6523 :
6524 6665 : if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
6525 3 : maybe_zero_len = true;
6526 6665 : if (processing_template_decl && maybe_zero_len)
6527 : return false;
6528 :
6529 14020 : for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
6530 7433 : t = TREE_OPERAND (t, 0))
6531 : {
6532 7504 : gcc_assert (TREE_CODE (t) == OMP_ARRAY_SECTION);
6533 :
6534 7504 : tree low_bound = TREE_OPERAND (t, 1);
6535 7504 : tree length = TREE_OPERAND (t, 2);
6536 :
6537 7504 : i--;
6538 7504 : if (low_bound
6539 6121 : && TREE_CODE (low_bound) == INTEGER_CST
6540 13014 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6541 5510 : > TYPE_PRECISION (sizetype))
6542 0 : low_bound = fold_convert (sizetype, low_bound);
6543 7504 : if (length
6544 6985 : && TREE_CODE (length) == INTEGER_CST
6545 12597 : && TYPE_PRECISION (TREE_TYPE (length))
6546 5093 : > TYPE_PRECISION (sizetype))
6547 0 : length = fold_convert (sizetype, length);
6548 7504 : if (low_bound == NULL_TREE)
6549 1383 : low_bound = integer_zero_node;
6550 7504 : if (!maybe_zero_len && i > first_non_one)
6551 : {
6552 629 : if (integer_nonzerop (low_bound))
6553 34 : goto do_warn_noncontiguous;
6554 595 : if (length != NULL_TREE
6555 273 : && TREE_CODE (length) == INTEGER_CST
6556 273 : && TYPE_DOMAIN (types[i])
6557 273 : && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))
6558 868 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])))
6559 : == INTEGER_CST)
6560 : {
6561 273 : tree size;
6562 273 : size = size_binop (PLUS_EXPR,
6563 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6564 : size_one_node);
6565 273 : if (!tree_int_cst_equal (length, size))
6566 : {
6567 37 : do_warn_noncontiguous:
6568 142 : error_at (OMP_CLAUSE_LOCATION (c),
6569 : "array section is not contiguous in %qs "
6570 : "clause",
6571 71 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6572 71 : return true;
6573 : }
6574 : }
6575 558 : if (!processing_template_decl
6576 390 : && length != NULL_TREE
6577 723 : && TREE_SIDE_EFFECTS (length))
6578 : {
6579 0 : if (side_effects == NULL_TREE)
6580 : side_effects = length;
6581 : else
6582 0 : side_effects = build2 (COMPOUND_EXPR,
6583 0 : TREE_TYPE (side_effects),
6584 : length, side_effects);
6585 : }
6586 : }
6587 6875 : else if (processing_template_decl)
6588 698 : continue;
6589 : else
6590 : {
6591 6177 : tree l;
6592 :
6593 6177 : if (i > first_non_one
6594 6177 : && ((length && integer_nonzerop (length))
6595 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6596 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6597 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION))
6598 0 : continue;
6599 6177 : if (length)
6600 6060 : l = fold_convert (sizetype, length);
6601 : else
6602 : {
6603 117 : l = size_binop (PLUS_EXPR,
6604 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6605 : size_one_node);
6606 117 : l = size_binop (MINUS_EXPR, l,
6607 : fold_convert (sizetype, low_bound));
6608 : }
6609 6177 : if (i > first_non_one)
6610 : {
6611 0 : l = fold_build2 (NE_EXPR, boolean_type_node, l,
6612 : size_zero_node);
6613 0 : if (condition == NULL_TREE)
6614 : condition = l;
6615 : else
6616 0 : condition = fold_build2 (BIT_AND_EXPR, boolean_type_node,
6617 : l, condition);
6618 : }
6619 6177 : else if (size == NULL_TREE)
6620 : {
6621 5899 : size = size_in_bytes (TREE_TYPE (types[i]));
6622 5899 : tree eltype = TREE_TYPE (types[num - 1]);
6623 5968 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6624 69 : eltype = TREE_TYPE (eltype);
6625 5899 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6626 5149 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6627 10295 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6628 1599 : size = size_binop (EXACT_DIV_EXPR, size,
6629 : size_in_bytes (eltype));
6630 5899 : size = size_binop (MULT_EXPR, size, l);
6631 5899 : if (condition)
6632 0 : size = fold_build3 (COND_EXPR, sizetype, condition,
6633 : size, size_zero_node);
6634 : }
6635 : else
6636 278 : size = size_binop (MULT_EXPR, size, l);
6637 : }
6638 : }
6639 6516 : if (!processing_template_decl)
6640 : {
6641 5899 : if (side_effects)
6642 0 : size = build2 (COMPOUND_EXPR, sizetype, side_effects, size);
6643 5899 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6644 5149 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6645 10295 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6646 : {
6647 1599 : size = size_binop (MINUS_EXPR, size, size_one_node);
6648 1599 : size = save_expr (size);
6649 1599 : tree index_type = build_index_type (size);
6650 1599 : tree eltype = TREE_TYPE (first);
6651 1628 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6652 29 : eltype = TREE_TYPE (eltype);
6653 1599 : tree type = build_array_type (eltype, index_type);
6654 1599 : tree ptype = build_pointer_type (eltype);
6655 1599 : if (TYPE_REF_P (TREE_TYPE (t))
6656 1599 : && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
6657 152 : t = convert_from_reference (t);
6658 1447 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6659 629 : t = build_fold_addr_expr (t);
6660 1599 : tree t2 = build_fold_addr_expr (first);
6661 1599 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6662 : ptrdiff_type_node, t2);
6663 1599 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
6664 : ptrdiff_type_node, t2,
6665 1599 : fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6666 : ptrdiff_type_node, t));
6667 1599 : if (tree_fits_shwi_p (t2))
6668 1261 : t = build2 (MEM_REF, type, t,
6669 1261 : build_int_cst (ptype, tree_to_shwi (t2)));
6670 : else
6671 : {
6672 338 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6673 : sizetype, t2);
6674 338 : t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR,
6675 338 : TREE_TYPE (t), t, t2);
6676 338 : t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
6677 : }
6678 1599 : OMP_CLAUSE_DECL (c) = t;
6679 7498 : return false;
6680 : }
6681 4300 : OMP_CLAUSE_DECL (c) = first;
6682 4300 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
6683 : return false;
6684 4274 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
6685 4274 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
6686 3734 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
6687 3722 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH))
6688 4250 : OMP_CLAUSE_SIZE (c) = size;
6689 4274 : if (TREE_CODE (t) == FIELD_DECL)
6690 3 : t = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6691 :
6692 4274 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
6693 : return false;
6694 :
6695 3746 : if (TREE_CODE (first) == INDIRECT_REF)
6696 : {
6697 : /* Detect and skip adding extra nodes for pointer-to-member
6698 : mappings. These are unsupported for now. */
6699 2411 : tree tmp = TREE_OPERAND (first, 0);
6700 :
6701 2411 : if (TREE_CODE (tmp) == NON_LVALUE_EXPR)
6702 1915 : tmp = TREE_OPERAND (tmp, 0);
6703 :
6704 2411 : if (TREE_CODE (tmp) == INDIRECT_REF)
6705 158 : tmp = TREE_OPERAND (tmp, 0);
6706 :
6707 2411 : if (TREE_CODE (tmp) == POINTER_PLUS_EXPR)
6708 : {
6709 466 : tree offset = TREE_OPERAND (tmp, 1);
6710 466 : STRIP_NOPS (offset);
6711 466 : if (TYPE_PTRMEM_P (TREE_TYPE (offset)))
6712 : {
6713 36 : sorry_at (OMP_CLAUSE_LOCATION (c),
6714 : "pointer-to-member mapping %qE not supported",
6715 18 : OMP_CLAUSE_DECL (c));
6716 18 : return true;
6717 : }
6718 : }
6719 : }
6720 :
6721 : /* FIRST represents the first item of data that we are mapping.
6722 : E.g. if we're mapping an array, FIRST might resemble
6723 : "foo.bar.myarray[0]". */
6724 :
6725 3728 : auto_vec<omp_addr_token *, 10> addr_tokens;
6726 :
6727 3728 : if (!omp_parse_expr (addr_tokens, first))
6728 : return true;
6729 :
6730 3728 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6731 :
6732 3728 : tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
6733 3728 : if (nc != error_mark_node)
6734 : {
6735 3728 : using namespace omp_addr_tokenizer;
6736 :
6737 3728 : if (ai.maybe_zero_length_array_section (c))
6738 3704 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
6739 :
6740 : /* !!! If we're accessing a base decl via chained access
6741 : methods (e.g. multiple indirections), duplicate clause
6742 : detection won't work properly. Skip it in that case. */
6743 3728 : if ((addr_tokens[0]->type == STRUCTURE_BASE
6744 2711 : || addr_tokens[0]->type == ARRAY_BASE)
6745 3728 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
6746 3717 : && addr_tokens[1]->type == ACCESS_METHOD
6747 7445 : && omp_access_chain_p (addr_tokens, 1))
6748 216 : c = nc;
6749 :
6750 3728 : return false;
6751 : }
6752 7456 : }
6753 : }
6754 : return false;
6755 9279 : }
6756 :
6757 : /* Return identifier to look up for omp declare reduction. */
6758 :
6759 : tree
6760 7113 : omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type)
6761 : {
6762 7113 : const char *p = NULL;
6763 7113 : const char *m = NULL;
6764 7113 : switch (reduction_code)
6765 : {
6766 4200 : case PLUS_EXPR:
6767 4200 : case MULT_EXPR:
6768 4200 : case MINUS_EXPR:
6769 4200 : case BIT_AND_EXPR:
6770 4200 : case BIT_XOR_EXPR:
6771 4200 : case BIT_IOR_EXPR:
6772 4200 : case TRUTH_ANDIF_EXPR:
6773 4200 : case TRUTH_ORIF_EXPR:
6774 4200 : reduction_id = ovl_op_identifier (false, reduction_code);
6775 4200 : break;
6776 : case MIN_EXPR:
6777 : p = "min";
6778 : break;
6779 : case MAX_EXPR:
6780 : p = "max";
6781 : break;
6782 : default:
6783 : break;
6784 : }
6785 :
6786 4200 : if (p == NULL)
6787 : {
6788 6949 : if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
6789 0 : return error_mark_node;
6790 6949 : p = IDENTIFIER_POINTER (reduction_id);
6791 : }
6792 :
6793 7113 : if (type != NULL_TREE)
6794 2047 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6795 :
6796 7113 : const char prefix[] = "omp declare reduction ";
6797 7113 : size_t lenp = sizeof (prefix);
6798 7113 : if (strncmp (p, prefix, lenp - 1) == 0)
6799 2047 : lenp = 1;
6800 7113 : size_t len = strlen (p);
6801 7113 : size_t lenm = m ? strlen (m) + 1 : 0;
6802 7113 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6803 7113 : if (lenp > 1)
6804 5066 : memcpy (name, prefix, lenp - 1);
6805 7113 : memcpy (name + lenp - 1, p, len + 1);
6806 7113 : if (m)
6807 : {
6808 2047 : name[lenp + len - 1] = '~';
6809 2047 : memcpy (name + lenp + len, m, lenm);
6810 : }
6811 7113 : return get_identifier (name);
6812 : }
6813 :
6814 : /* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial
6815 : FUNCTION_DECL or NULL_TREE if not found. */
6816 :
6817 : static tree
6818 1298 : omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
6819 : vec<tree> *ambiguousp)
6820 : {
6821 1298 : tree orig_id = id;
6822 1298 : tree baselink = NULL_TREE;
6823 1298 : if (identifier_p (id))
6824 : {
6825 1270 : cp_id_kind idk;
6826 1270 : bool nonint_cst_expression_p;
6827 1270 : const char *error_msg;
6828 1270 : id = omp_reduction_id (ERROR_MARK, id, type);
6829 1270 : tree decl = lookup_name (id);
6830 1270 : if (decl == NULL_TREE)
6831 80 : decl = error_mark_node;
6832 1270 : id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
6833 : &nonint_cst_expression_p, false, true, false,
6834 : false, &error_msg, loc);
6835 1270 : if (idk == CP_ID_KIND_UNQUALIFIED
6836 1350 : && identifier_p (id))
6837 : {
6838 80 : vec<tree, va_gc> *args = NULL;
6839 80 : vec_safe_push (args, build_reference_type (type));
6840 80 : id = perform_koenig_lookup (id, args, tf_none);
6841 : }
6842 : }
6843 28 : else if (TREE_CODE (id) == SCOPE_REF)
6844 28 : id = lookup_qualified_name (TREE_OPERAND (id, 0),
6845 : omp_reduction_id (ERROR_MARK,
6846 28 : TREE_OPERAND (id, 1),
6847 : type),
6848 : LOOK_want::NORMAL, false);
6849 1298 : tree fns = id;
6850 1298 : id = NULL_TREE;
6851 1298 : if (fns && is_overloaded_fn (fns))
6852 : {
6853 1224 : for (lkp_iterator iter (get_fns (fns)); iter; ++iter)
6854 : {
6855 1224 : tree fndecl = *iter;
6856 1224 : if (TREE_CODE (fndecl) == FUNCTION_DECL)
6857 : {
6858 1224 : tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
6859 1224 : if (same_type_p (TREE_TYPE (argtype), type))
6860 : {
6861 1224 : id = fndecl;
6862 1224 : break;
6863 : }
6864 : }
6865 : }
6866 :
6867 1224 : if (id && BASELINK_P (fns))
6868 : {
6869 74 : if (baselinkp)
6870 0 : *baselinkp = fns;
6871 : else
6872 74 : baselink = fns;
6873 : }
6874 : }
6875 :
6876 1298 : if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type))
6877 : {
6878 35 : auto_vec<tree> ambiguous;
6879 35 : tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
6880 35 : unsigned int ix;
6881 35 : if (ambiguousp == NULL)
6882 19 : ambiguousp = &ambiguous;
6883 73 : for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
6884 : {
6885 52 : id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo),
6886 : baselinkp ? baselinkp : &baselink,
6887 : ambiguousp);
6888 38 : if (id == NULL_TREE)
6889 14 : continue;
6890 24 : if (!ambiguousp->is_empty ())
6891 3 : ambiguousp->safe_push (id);
6892 21 : else if (ret != NULL_TREE)
6893 : {
6894 6 : ambiguousp->safe_push (ret);
6895 6 : ambiguousp->safe_push (id);
6896 6 : ret = NULL_TREE;
6897 : }
6898 : else
6899 15 : ret = id;
6900 : }
6901 35 : if (ambiguousp != &ambiguous)
6902 16 : return ret;
6903 19 : if (!ambiguous.is_empty ())
6904 : {
6905 6 : auto_diagnostic_group d;
6906 6 : const char *str = _("candidates are:");
6907 6 : unsigned int idx;
6908 6 : tree udr;
6909 6 : error_at (loc, "user defined reduction lookup is ambiguous");
6910 27 : FOR_EACH_VEC_ELT (ambiguous, idx, udr)
6911 : {
6912 15 : inform (DECL_SOURCE_LOCATION (udr), "%s %#qD", str, udr);
6913 15 : if (idx == 0)
6914 6 : str = get_spaces (str);
6915 : }
6916 6 : ret = error_mark_node;
6917 6 : baselink = NULL_TREE;
6918 6 : }
6919 19 : id = ret;
6920 35 : }
6921 1282 : if (id && baselink)
6922 74 : perform_or_defer_access_check (BASELINK_BINFO (baselink),
6923 : id, id, tf_warning_or_error);
6924 : return id;
6925 : }
6926 :
6927 : /* Return identifier to look up for omp declare mapper. */
6928 :
6929 : tree
6930 4067 : omp_mapper_id (tree mapper_id, tree type)
6931 : {
6932 4067 : const char *p = NULL;
6933 4067 : const char *m = NULL;
6934 :
6935 4067 : if (mapper_id == NULL_TREE)
6936 : p = "";
6937 91 : else if (TREE_CODE (mapper_id) == IDENTIFIER_NODE)
6938 91 : p = IDENTIFIER_POINTER (mapper_id);
6939 : else
6940 0 : return error_mark_node;
6941 :
6942 4067 : if (type != NULL_TREE)
6943 4059 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6944 :
6945 4067 : const char prefix[] = "omp declare mapper ";
6946 4067 : size_t lenp = sizeof (prefix);
6947 4067 : if (strncmp (p, prefix, lenp - 1) == 0)
6948 8 : lenp = 1;
6949 4067 : size_t len = strlen (p);
6950 4067 : size_t lenm = m ? strlen (m) + 1 : 0;
6951 4067 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6952 4067 : memcpy (name, prefix, lenp - 1);
6953 4067 : memcpy (name + lenp - 1, p, len + 1);
6954 4067 : if (m)
6955 : {
6956 4059 : name[lenp + len - 1] = '~';
6957 4059 : memcpy (name + lenp + len, m, lenm);
6958 : }
6959 4067 : return get_identifier (name);
6960 : }
6961 :
6962 : tree
6963 11967 : cxx_omp_mapper_lookup (tree id, tree type)
6964 : {
6965 11967 : if (!RECORD_OR_UNION_TYPE_P (type))
6966 : return NULL_TREE;
6967 3826 : id = omp_mapper_id (id, type);
6968 3826 : return lookup_name (id);
6969 : }
6970 :
6971 : tree
6972 375 : cxx_omp_extract_mapper_directive (tree vardecl)
6973 : {
6974 375 : gcc_assert (TREE_CODE (vardecl) == VAR_DECL);
6975 :
6976 : /* Instantiate the decl if we haven't already. */
6977 375 : mark_used (vardecl);
6978 375 : tree body = DECL_INITIAL (vardecl);
6979 :
6980 375 : if (TREE_CODE (body) == STATEMENT_LIST)
6981 : {
6982 0 : tree_stmt_iterator tsi = tsi_start (body);
6983 0 : gcc_assert (TREE_CODE (tsi_stmt (tsi)) == DECL_EXPR);
6984 0 : tsi_next (&tsi);
6985 0 : body = tsi_stmt (tsi);
6986 : }
6987 :
6988 375 : gcc_assert (TREE_CODE (body) == OMP_DECLARE_MAPPER);
6989 :
6990 375 : return body;
6991 : }
6992 :
6993 : /* For now we can handle singleton OMP_ARRAY_SECTIONs with custom mappers, but
6994 : nothing more complicated. */
6995 :
6996 : tree
6997 1910 : cxx_omp_map_array_section (location_t loc, tree t)
6998 : {
6999 1910 : tree low = TREE_OPERAND (t, 1);
7000 1910 : tree len = TREE_OPERAND (t, 2);
7001 :
7002 1910 : if (len && integer_onep (len))
7003 : {
7004 300 : t = TREE_OPERAND (t, 0);
7005 :
7006 300 : if (!low)
7007 17 : low = integer_zero_node;
7008 :
7009 300 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
7010 6 : t = convert_from_reference (t);
7011 :
7012 300 : if (TYPE_PTR_P (TREE_TYPE (t))
7013 300 : || TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7014 300 : t = build_array_ref (loc, t, low);
7015 : else
7016 : /* handle_omp_array_sections_1 has already diagnosed the error. */
7017 0 : t = error_mark_node;
7018 : }
7019 :
7020 1910 : return t;
7021 : }
7022 :
7023 : /* Helper function for cp_parser_omp_declare_reduction_exprs
7024 : and tsubst_omp_udr.
7025 : Remove CLEANUP_STMT for data (omp_priv variable).
7026 : Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
7027 : DECL_EXPR. */
7028 :
7029 : tree
7030 4449 : cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data)
7031 : {
7032 4449 : if (TYPE_P (*tp))
7033 230 : *walk_subtrees = 0;
7034 4219 : else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data)
7035 52 : *tp = CLEANUP_BODY (*tp);
7036 4167 : else if (TREE_CODE (*tp) == DECL_EXPR)
7037 : {
7038 310 : tree decl = DECL_EXPR_DECL (*tp);
7039 310 : if (!processing_template_decl
7040 261 : && decl == (tree) data
7041 261 : && DECL_INITIAL (decl)
7042 402 : && DECL_INITIAL (decl) != error_mark_node)
7043 : {
7044 92 : tree list = NULL_TREE;
7045 92 : append_to_statement_list_force (*tp, &list);
7046 92 : tree init_expr = build2 (INIT_EXPR, void_type_node,
7047 92 : decl, DECL_INITIAL (decl));
7048 92 : DECL_INITIAL (decl) = NULL_TREE;
7049 92 : append_to_statement_list_force (init_expr, &list);
7050 92 : *tp = list;
7051 : }
7052 : }
7053 4449 : return NULL_TREE;
7054 : }
7055 :
7056 : /* Data passed from cp_check_omp_declare_reduction to
7057 : cp_check_omp_declare_reduction_r. */
7058 :
7059 : struct cp_check_omp_declare_reduction_data
7060 : {
7061 : location_t loc;
7062 : tree stmts[7];
7063 : bool combiner_p;
7064 : };
7065 :
7066 : /* Helper function for cp_check_omp_declare_reduction, called via
7067 : cp_walk_tree. */
7068 :
7069 : static tree
7070 15042 : cp_check_omp_declare_reduction_r (tree *tp, int *, void *data)
7071 : {
7072 15042 : struct cp_check_omp_declare_reduction_data *udr_data
7073 : = (struct cp_check_omp_declare_reduction_data *) data;
7074 15042 : if (SSA_VAR_P (*tp)
7075 2702 : && !DECL_ARTIFICIAL (*tp)
7076 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3])
7077 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4]))
7078 : {
7079 135 : location_t loc = udr_data->loc;
7080 135 : if (udr_data->combiner_p)
7081 45 : error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
7082 : "variable %qD which is not %<omp_out%> nor %<omp_in%>",
7083 : *tp);
7084 : else
7085 90 : error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
7086 : "to variable %qD which is not %<omp_priv%> nor "
7087 : "%<omp_orig%>",
7088 : *tp);
7089 135 : return *tp;
7090 : }
7091 : return NULL_TREE;
7092 : }
7093 :
7094 : /* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */
7095 :
7096 : bool
7097 1104 : cp_check_omp_declare_reduction (tree udr)
7098 : {
7099 1104 : tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
7100 1104 : gcc_assert (TYPE_REF_P (type));
7101 1104 : type = TREE_TYPE (type);
7102 1104 : int i;
7103 1104 : location_t loc = DECL_SOURCE_LOCATION (udr);
7104 :
7105 1104 : if (type == error_mark_node)
7106 : return false;
7107 1104 : if (ARITHMETIC_TYPE_P (type))
7108 : {
7109 : static enum tree_code predef_codes[]
7110 : = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR,
7111 : BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR };
7112 3276 : for (i = 0; i < 8; i++)
7113 : {
7114 2918 : tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE);
7115 2918 : const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr));
7116 2918 : const char *n2 = IDENTIFIER_POINTER (id);
7117 2918 : if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0
7118 2918 : && (n1[IDENTIFIER_LENGTH (id)] == '~'
7119 0 : || n1[IDENTIFIER_LENGTH (id)] == '\0'))
7120 : break;
7121 : }
7122 :
7123 376 : if (i == 8
7124 358 : && TREE_CODE (type) != COMPLEX_EXPR)
7125 : {
7126 358 : const char prefix_minmax[] = "omp declare reduction m";
7127 358 : size_t prefix_size = sizeof (prefix_minmax) - 1;
7128 358 : const char *n = IDENTIFIER_POINTER (DECL_NAME (udr));
7129 358 : if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)),
7130 : prefix_minmax, prefix_size) == 0
7131 10 : && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n')
7132 4 : || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x'))
7133 368 : && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0'))
7134 6 : i = 0;
7135 : }
7136 376 : if (i < 8)
7137 : {
7138 24 : error_at (loc, "predeclared arithmetic type %qT in "
7139 : "%<#pragma omp declare reduction%>", type);
7140 24 : return false;
7141 : }
7142 : }
7143 : else if (FUNC_OR_METHOD_TYPE_P (type)
7144 : || TREE_CODE (type) == ARRAY_TYPE)
7145 : {
7146 24 : error_at (loc, "function or array type %qT in "
7147 : "%<#pragma omp declare reduction%>", type);
7148 24 : return false;
7149 : }
7150 : else if (TYPE_REF_P (type))
7151 : {
7152 0 : error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
7153 : type);
7154 0 : return false;
7155 : }
7156 704 : else if (TYPE_QUALS_NO_ADDR_SPACE (type))
7157 : {
7158 24 : error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
7159 : "type %qT in %<#pragma omp declare reduction%>", type);
7160 24 : return false;
7161 : }
7162 :
7163 1032 : tree body = DECL_SAVED_TREE (udr);
7164 1032 : if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST)
7165 : return true;
7166 :
7167 846 : tree_stmt_iterator tsi;
7168 846 : struct cp_check_omp_declare_reduction_data data;
7169 846 : memset (data.stmts, 0, sizeof data.stmts);
7170 846 : for (i = 0, tsi = tsi_start (body);
7171 4707 : i < 7 && !tsi_end_p (tsi);
7172 3861 : i++, tsi_next (&tsi))
7173 3861 : data.stmts[i] = tsi_stmt (tsi);
7174 846 : data.loc = loc;
7175 846 : gcc_assert (tsi_end_p (tsi));
7176 846 : if (i >= 3)
7177 : {
7178 846 : gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
7179 : && TREE_CODE (data.stmts[1]) == DECL_EXPR);
7180 846 : if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */))
7181 : return true;
7182 801 : data.combiner_p = true;
7183 801 : if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
7184 : &data, NULL))
7185 45 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */);
7186 : }
7187 801 : if (i >= 6)
7188 : {
7189 339 : gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR
7190 : && TREE_CODE (data.stmts[4]) == DECL_EXPR);
7191 339 : data.combiner_p = false;
7192 339 : if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r,
7193 : &data, NULL)
7194 339 : || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
7195 : cp_check_omp_declare_reduction_r, &data, NULL))
7196 90 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */);
7197 339 : if (i == 7)
7198 201 : gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
7199 : }
7200 : return true;
7201 : }
7202 :
7203 : /* Helper function of finish_omp_clauses. Clone STMT as if we were making
7204 : an inline call. But, remap
7205 : the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER
7206 : and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */
7207 :
7208 : static tree
7209 2217 : clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
7210 : tree decl, tree placeholder)
7211 : {
7212 2217 : copy_body_data id;
7213 2217 : hash_map<tree, tree> decl_map;
7214 :
7215 2217 : decl_map.put (omp_decl1, placeholder);
7216 2217 : decl_map.put (omp_decl2, decl);
7217 2217 : memset (&id, 0, sizeof (id));
7218 2217 : id.src_fn = DECL_CONTEXT (omp_decl1);
7219 2217 : id.dst_fn = current_function_decl;
7220 2217 : id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
7221 2217 : id.decl_map = &decl_map;
7222 :
7223 2217 : id.copy_decl = copy_decl_no_change;
7224 2217 : id.transform_call_graph_edges = CB_CGE_DUPLICATE;
7225 2217 : id.transform_new_cfg = true;
7226 2217 : id.transform_return_to_modify = false;
7227 2217 : id.eh_lp_nr = 0;
7228 2217 : walk_tree (&stmt, copy_tree_body_r, &id, NULL);
7229 2217 : return stmt;
7230 2217 : }
7231 :
7232 : /* Helper function of finish_omp_clauses, called via cp_walk_tree.
7233 : Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */
7234 :
7235 : static tree
7236 15573 : find_omp_placeholder_r (tree *tp, int *, void *data)
7237 : {
7238 15573 : if (*tp == (tree) data)
7239 274 : return *tp;
7240 : return NULL_TREE;
7241 : }
7242 :
7243 : /* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C.
7244 : Return true if there is some error and the clause should be removed. */
7245 :
7246 : static bool
7247 8904 : finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
7248 : {
7249 8904 : tree t = OMP_CLAUSE_DECL (c);
7250 8904 : bool predefined = false;
7251 8904 : if (TREE_CODE (t) == TREE_LIST)
7252 : {
7253 0 : gcc_assert (processing_template_decl);
7254 : return false;
7255 : }
7256 8904 : tree type = TREE_TYPE (t);
7257 8904 : if (TREE_CODE (t) == MEM_REF)
7258 1596 : type = TREE_TYPE (type);
7259 8904 : if (TYPE_REF_P (type))
7260 527 : type = TREE_TYPE (type);
7261 8904 : if (TREE_CODE (type) == ARRAY_TYPE)
7262 : {
7263 350 : tree oatype = type;
7264 350 : gcc_assert (TREE_CODE (t) != MEM_REF);
7265 703 : while (TREE_CODE (type) == ARRAY_TYPE)
7266 353 : type = TREE_TYPE (type);
7267 350 : if (!processing_template_decl)
7268 : {
7269 255 : t = require_complete_type (t);
7270 255 : if (t == error_mark_node
7271 255 : || !complete_type_or_else (oatype, NULL_TREE))
7272 9 : return true;
7273 246 : tree size = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (oatype),
7274 : TYPE_SIZE_UNIT (type));
7275 246 : if (integer_zerop (size))
7276 : {
7277 6 : error_at (OMP_CLAUSE_LOCATION (c),
7278 : "%qE in %<reduction%> clause is a zero size array",
7279 : omp_clause_printable_decl (t));
7280 3 : return true;
7281 : }
7282 243 : size = size_binop (MINUS_EXPR, size, size_one_node);
7283 243 : size = save_expr (size);
7284 243 : tree index_type = build_index_type (size);
7285 243 : tree atype = build_array_type (type, index_type);
7286 243 : tree ptype = build_pointer_type (type);
7287 243 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7288 146 : t = build_fold_addr_expr (t);
7289 243 : t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0));
7290 243 : OMP_CLAUSE_DECL (c) = t;
7291 : }
7292 : }
7293 8892 : if (type == error_mark_node)
7294 : return true;
7295 8889 : else if (ARITHMETIC_TYPE_P (type))
7296 7629 : switch (OMP_CLAUSE_REDUCTION_CODE (c))
7297 : {
7298 : case PLUS_EXPR:
7299 : case MULT_EXPR:
7300 : case MINUS_EXPR:
7301 : case TRUTH_ANDIF_EXPR:
7302 : case TRUTH_ORIF_EXPR:
7303 : predefined = true;
7304 : break;
7305 246 : case MIN_EXPR:
7306 246 : case MAX_EXPR:
7307 246 : if (TREE_CODE (type) == COMPLEX_TYPE)
7308 : break;
7309 : predefined = true;
7310 : break;
7311 111 : case BIT_AND_EXPR:
7312 111 : case BIT_IOR_EXPR:
7313 111 : case BIT_XOR_EXPR:
7314 111 : if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
7315 : break;
7316 : predefined = true;
7317 : break;
7318 : default:
7319 : break;
7320 : }
7321 1260 : else if (TYPE_READONLY (type))
7322 : {
7323 18 : error_at (OMP_CLAUSE_LOCATION (c),
7324 : "%qE has const type for %<reduction%>",
7325 : omp_clause_printable_decl (t));
7326 9 : return true;
7327 : }
7328 1251 : else if (!processing_template_decl)
7329 : {
7330 1047 : t = require_complete_type (t);
7331 1047 : if (t == error_mark_node)
7332 : return true;
7333 1047 : OMP_CLAUSE_DECL (c) = t;
7334 : }
7335 :
7336 1047 : if (predefined)
7337 : {
7338 7407 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7339 7407 : return false;
7340 : }
7341 1473 : else if (processing_template_decl)
7342 : {
7343 213 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
7344 : return true;
7345 : return false;
7346 : }
7347 :
7348 1260 : tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
7349 :
7350 1260 : type = TYPE_MAIN_VARIANT (type);
7351 1260 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7352 1260 : if (id == NULL_TREE)
7353 933 : id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c),
7354 : NULL_TREE, NULL_TREE);
7355 1260 : id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL);
7356 1260 : if (id)
7357 : {
7358 1215 : if (id == error_mark_node)
7359 : return true;
7360 1209 : mark_used (id);
7361 1209 : tree body = DECL_SAVED_TREE (id);
7362 1209 : if (!body)
7363 : return true;
7364 1206 : if (TREE_CODE (body) == STATEMENT_LIST)
7365 : {
7366 1206 : tree_stmt_iterator tsi;
7367 1206 : tree placeholder = NULL_TREE, decl_placeholder = NULL_TREE;
7368 1206 : int i;
7369 1206 : tree stmts[7];
7370 1206 : tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id)));
7371 1206 : atype = TREE_TYPE (atype);
7372 1206 : bool need_static_cast = !same_type_p (type, atype);
7373 1206 : memset (stmts, 0, sizeof stmts);
7374 1206 : for (i = 0, tsi = tsi_start (body);
7375 8594 : i < 7 && !tsi_end_p (tsi);
7376 7388 : i++, tsi_next (&tsi))
7377 7388 : stmts[i] = tsi_stmt (tsi);
7378 1206 : gcc_assert (tsi_end_p (tsi));
7379 :
7380 1206 : if (i >= 3)
7381 : {
7382 1206 : gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
7383 : && TREE_CODE (stmts[1]) == DECL_EXPR);
7384 1206 : placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type);
7385 1206 : DECL_ARTIFICIAL (placeholder) = 1;
7386 1206 : DECL_IGNORED_P (placeholder) = 1;
7387 1206 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder;
7388 1206 : if (TREE_CODE (t) == MEM_REF)
7389 : {
7390 600 : decl_placeholder = build_lang_decl (VAR_DECL, NULL_TREE,
7391 : type);
7392 600 : DECL_ARTIFICIAL (decl_placeholder) = 1;
7393 600 : DECL_IGNORED_P (decl_placeholder) = 1;
7394 600 : OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = decl_placeholder;
7395 : }
7396 1206 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
7397 294 : cxx_mark_addressable (placeholder);
7398 1206 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
7399 1206 : && (decl_placeholder
7400 158 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7401 390 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7402 127 : : OMP_CLAUSE_DECL (c));
7403 1206 : tree omp_out = placeholder;
7404 1206 : tree omp_in = decl_placeholder ? decl_placeholder
7405 606 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7406 1206 : if (need_static_cast)
7407 : {
7408 7 : tree rtype = build_reference_type (atype);
7409 7 : omp_out = build_static_cast (input_location,
7410 : rtype, omp_out,
7411 : tf_warning_or_error);
7412 7 : omp_in = build_static_cast (input_location,
7413 : rtype, omp_in,
7414 : tf_warning_or_error);
7415 7 : if (omp_out == error_mark_node || omp_in == error_mark_node)
7416 3 : return true;
7417 7 : omp_out = convert_from_reference (omp_out);
7418 7 : omp_in = convert_from_reference (omp_in);
7419 : }
7420 1206 : OMP_CLAUSE_REDUCTION_MERGE (c)
7421 1206 : = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]),
7422 1206 : DECL_EXPR_DECL (stmts[1]), omp_in, omp_out);
7423 : }
7424 1206 : if (i >= 6)
7425 : {
7426 1014 : gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
7427 : && TREE_CODE (stmts[4]) == DECL_EXPR);
7428 1014 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3]))
7429 1014 : && (decl_placeholder
7430 232 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7431 844 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7432 170 : : OMP_CLAUSE_DECL (c));
7433 1014 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
7434 225 : cxx_mark_addressable (placeholder);
7435 1014 : tree omp_priv = decl_placeholder ? decl_placeholder
7436 438 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7437 1014 : tree omp_orig = placeholder;
7438 1014 : if (need_static_cast)
7439 : {
7440 5 : if (i == 7)
7441 : {
7442 3 : error_at (OMP_CLAUSE_LOCATION (c),
7443 : "user defined reduction with constructor "
7444 : "initializer for base class %qT", atype);
7445 3 : return true;
7446 : }
7447 2 : tree rtype = build_reference_type (atype);
7448 2 : omp_priv = build_static_cast (input_location,
7449 : rtype, omp_priv,
7450 : tf_warning_or_error);
7451 2 : omp_orig = build_static_cast (input_location,
7452 : rtype, omp_orig,
7453 : tf_warning_or_error);
7454 2 : if (omp_priv == error_mark_node
7455 2 : || omp_orig == error_mark_node)
7456 : return true;
7457 2 : omp_priv = convert_from_reference (omp_priv);
7458 2 : omp_orig = convert_from_reference (omp_orig);
7459 : }
7460 1011 : if (i == 6)
7461 286 : *need_default_ctor = true;
7462 1011 : OMP_CLAUSE_REDUCTION_INIT (c)
7463 1011 : = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]),
7464 1011 : DECL_EXPR_DECL (stmts[3]),
7465 : omp_priv, omp_orig);
7466 1011 : if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7467 : find_omp_placeholder_r, placeholder, NULL))
7468 247 : OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
7469 : }
7470 192 : else if (i >= 3)
7471 : {
7472 192 : if (CLASS_TYPE_P (type) && !pod_type_p (type))
7473 175 : *need_default_ctor = true;
7474 : else
7475 : {
7476 17 : tree init;
7477 17 : tree v = decl_placeholder ? decl_placeholder
7478 17 : : convert_from_reference (t);
7479 17 : if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
7480 8 : init = build_constructor (TREE_TYPE (v), NULL);
7481 : else
7482 9 : init = fold_convert (TREE_TYPE (v), integer_zero_node);
7483 34 : OMP_CLAUSE_REDUCTION_INIT (c)
7484 34 : = cp_build_init_expr (v, init);
7485 : }
7486 : }
7487 : }
7488 : }
7489 1248 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7490 1203 : *need_dtor = true;
7491 : else
7492 : {
7493 90 : error_at (OMP_CLAUSE_LOCATION (c),
7494 : "user defined reduction not found for %qE",
7495 : omp_clause_printable_decl (t));
7496 45 : return true;
7497 : }
7498 1203 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
7499 600 : gcc_assert (TYPE_SIZE_UNIT (type)
7500 : && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
7501 : return false;
7502 : }
7503 :
7504 : /* Check an instance of an "omp declare mapper" function. */
7505 :
7506 : bool
7507 208 : cp_check_omp_declare_mapper (tree udm)
7508 : {
7509 208 : tree var = OMP_DECLARE_MAPPER_DECL (udm);
7510 208 : tree type = TREE_TYPE (var);
7511 208 : location_t loc = DECL_SOURCE_LOCATION (var);
7512 :
7513 208 : if (type == error_mark_node)
7514 : return false;
7515 :
7516 208 : if (processing_template_decl)
7517 : return true;
7518 :
7519 197 : if (!RECORD_OR_UNION_TYPE_P (type))
7520 : {
7521 17 : error_at (loc, "%qT is not a struct, union or class type in "
7522 : "%<#pragma omp declare mapper%>", type);
7523 17 : return false;
7524 : }
7525 180 : if (CLASSTYPE_VBASECLASSES (type))
7526 : {
7527 3 : error_at (loc, "%qT must not be a virtual base class in "
7528 : "%<#pragma omp declare mapper%>", type);
7529 3 : return false;
7530 : }
7531 :
7532 177 : tree c = OMP_DECLARE_MAPPER_CLAUSES (udm);
7533 215 : for ( ; c; c = OMP_CLAUSE_CHAIN (c))
7534 : {
7535 187 : tree dvar = OMP_CLAUSE_DECL (c);
7536 400 : while (!DECL_P (dvar) && TREE_OPERAND_LENGTH (dvar))
7537 213 : dvar = TREE_OPERAND (dvar, 0);
7538 187 : if (dvar == var)
7539 : break;
7540 : }
7541 177 : if (!c)
7542 : {
7543 : // After template handling, the var is mangled, demangle it
7544 28 : const char *name = IDENTIFIER_POINTER (DECL_NAME (var));
7545 28 : char *n = NULL;
7546 28 : if (startswith (name, "omp declare mapper "))
7547 : {
7548 3 : name += strlen ("omp declare mapper ");
7549 3 : n = xstrdup (name);
7550 3 : n[strchr (n, '~')-n] = '\0';
7551 3 : name = n;
7552 : }
7553 28 : error_at (loc, "at least one %<map%> clause must map %qs or an "
7554 : "element of it", name);
7555 28 : if (n)
7556 3 : free (n);
7557 28 : return false;
7558 : }
7559 :
7560 : /* FIXME: The vardecl created for the mapper_id uses DECL_DECLARED_CONSTEXPR_P
7561 : = 1, which is set to false in finalize_literal_type_property for C++ < 11,
7562 : leading to an error in ensure_literal_type_for_constexpr_object.
7563 : Examples (compile with -std=c++98): gcc.dg/gomp/declare-mapper-13.c and
7564 : libgomp.c++/declare-mapper-{5,6,8}.C. */
7565 149 : if (cxx_dialect < cxx11)
7566 : {
7567 0 : sorry_at (loc, "%<#pragma omp declare mapper%> with %<-std=%> set to "
7568 : "before C++11");
7569 0 : return false;
7570 : }
7571 :
7572 : return true;
7573 : }
7574 :
7575 : /* Called from finish_struct_1. linear(this) or linear(this:step)
7576 : clauses might not be finalized yet because the class has been incomplete
7577 : when parsing #pragma omp declare simd methods. Fix those up now. */
7578 :
7579 : void
7580 118327 : finish_omp_declare_simd_methods (tree t)
7581 : {
7582 118327 : if (processing_template_decl)
7583 : return;
7584 :
7585 808438 : for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
7586 : {
7587 1142174 : if (TREE_CODE (x) == USING_DECL
7588 690111 : || !DECL_IOBJ_MEMBER_FUNCTION_P (x))
7589 452063 : continue;
7590 238048 : tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x));
7591 238156 : if (!ods || !TREE_VALUE (ods))
7592 237940 : continue;
7593 366 : for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c))
7594 258 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7595 66 : && integer_zerop (OMP_CLAUSE_DECL (c))
7596 18 : && OMP_CLAUSE_LINEAR_STEP (c)
7597 276 : && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c))))
7598 : {
7599 18 : tree s = OMP_CLAUSE_LINEAR_STEP (c);
7600 18 : s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
7601 18 : s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
7602 18 : sizetype, s, TYPE_SIZE_UNIT (t));
7603 18 : OMP_CLAUSE_LINEAR_STEP (c) = s;
7604 : }
7605 : }
7606 : }
7607 :
7608 : /* Adjust sink depend/doacross clause to take into account pointer offsets.
7609 :
7610 : Return TRUE if there was a problem processing the offset, and the
7611 : whole clause should be removed. */
7612 :
7613 : static bool
7614 298 : cp_finish_omp_clause_doacross_sink (tree sink_clause)
7615 : {
7616 298 : tree t = OMP_CLAUSE_DECL (sink_clause);
7617 298 : gcc_assert (TREE_CODE (t) == TREE_LIST);
7618 :
7619 : /* Make sure we don't adjust things twice for templates. */
7620 298 : if (processing_template_decl)
7621 : return false;
7622 :
7623 671 : for (; t; t = TREE_CHAIN (t))
7624 : {
7625 391 : tree decl = TREE_VALUE (t);
7626 391 : if (TYPE_PTR_P (TREE_TYPE (decl)))
7627 : {
7628 6 : tree offset = TREE_PURPOSE (t);
7629 6 : bool neg = wi::neg_p (wi::to_wide (offset));
7630 6 : offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset);
7631 6 : decl = mark_rvalue_use (decl);
7632 6 : decl = convert_from_reference (decl);
7633 12 : tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause),
7634 : neg ? MINUS_EXPR : PLUS_EXPR,
7635 : decl, offset);
7636 6 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
7637 : MINUS_EXPR, sizetype,
7638 : fold_convert (sizetype, t2),
7639 : fold_convert (sizetype, decl));
7640 6 : if (t2 == error_mark_node)
7641 : return true;
7642 6 : TREE_PURPOSE (t) = t2;
7643 : }
7644 : }
7645 : return false;
7646 : }
7647 :
7648 : /* Finish OpenMP iterators ITER. Return true if they are erroneous
7649 : and clauses containing them should be removed. */
7650 :
7651 : static bool
7652 615 : cp_omp_finish_iterators (tree iter)
7653 : {
7654 615 : bool ret = false;
7655 1395 : for (tree it = iter; it; it = TREE_CHAIN (it))
7656 : {
7657 780 : tree var = OMP_ITERATOR_VAR (it);
7658 780 : tree begin = OMP_ITERATOR_BEGIN (it);
7659 780 : tree end = OMP_ITERATOR_END (it);
7660 780 : tree step = OMP_ITERATOR_STEP (it);
7661 780 : tree orig_step;
7662 780 : tree type = TREE_TYPE (var);
7663 780 : location_t loc = DECL_SOURCE_LOCATION (var);
7664 780 : if (type == error_mark_node)
7665 : {
7666 0 : ret = true;
7667 218 : continue;
7668 : }
7669 780 : if (type_dependent_expression_p (var))
7670 59 : continue;
7671 721 : if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
7672 : {
7673 27 : error_at (loc, "iterator %qD has neither integral nor pointer type",
7674 : var);
7675 27 : ret = true;
7676 27 : continue;
7677 : }
7678 694 : else if (TYPE_READONLY (type))
7679 : {
7680 24 : error_at (loc, "iterator %qD has const qualified type", var);
7681 24 : ret = true;
7682 24 : continue;
7683 : }
7684 670 : if (type_dependent_expression_p (begin)
7685 661 : || type_dependent_expression_p (end)
7686 1331 : || type_dependent_expression_p (step))
7687 15 : continue;
7688 655 : else if (error_operand_p (step))
7689 : {
7690 0 : ret = true;
7691 0 : continue;
7692 : }
7693 655 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
7694 : {
7695 33 : error_at (EXPR_LOC_OR_LOC (step, loc),
7696 : "iterator step with non-integral type");
7697 21 : ret = true;
7698 21 : continue;
7699 : }
7700 :
7701 634 : begin = mark_rvalue_use (begin);
7702 634 : end = mark_rvalue_use (end);
7703 634 : step = mark_rvalue_use (step);
7704 634 : begin = cp_build_c_cast (input_location, type, begin,
7705 : tf_warning_or_error);
7706 634 : end = cp_build_c_cast (input_location, type, end,
7707 : tf_warning_or_error);
7708 634 : orig_step = step;
7709 634 : if (!processing_template_decl)
7710 557 : step = orig_step = save_expr (step);
7711 634 : tree stype = POINTER_TYPE_P (type) ? sizetype : type;
7712 634 : step = cp_build_c_cast (input_location, stype, step,
7713 : tf_warning_or_error);
7714 634 : if (POINTER_TYPE_P (type) && !processing_template_decl)
7715 : {
7716 66 : begin = save_expr (begin);
7717 66 : step = pointer_int_sum (loc, PLUS_EXPR, begin, step);
7718 66 : step = fold_build2_loc (loc, MINUS_EXPR, sizetype,
7719 : fold_convert (sizetype, step),
7720 : fold_convert (sizetype, begin));
7721 66 : step = fold_convert (ssizetype, step);
7722 : }
7723 634 : if (!processing_template_decl)
7724 : {
7725 557 : begin = maybe_constant_value (begin);
7726 557 : end = maybe_constant_value (end);
7727 557 : step = maybe_constant_value (step);
7728 557 : orig_step = maybe_constant_value (orig_step);
7729 : }
7730 634 : if (integer_zerop (step))
7731 : {
7732 27 : error_at (loc, "iterator %qD has zero step", var);
7733 27 : ret = true;
7734 27 : continue;
7735 : }
7736 :
7737 607 : if (begin == error_mark_node
7738 598 : || end == error_mark_node
7739 589 : || step == error_mark_node
7740 589 : || orig_step == error_mark_node)
7741 : {
7742 18 : ret = true;
7743 18 : continue;
7744 : }
7745 :
7746 589 : if (!processing_template_decl)
7747 : {
7748 512 : begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin);
7749 512 : end = fold_build_cleanup_point_expr (TREE_TYPE (end), end);
7750 512 : step = fold_build_cleanup_point_expr (TREE_TYPE (step), step);
7751 512 : orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step),
7752 : orig_step);
7753 : }
7754 589 : hash_set<tree> pset;
7755 589 : tree it2;
7756 745 : for (it2 = TREE_CHAIN (it); it2; it2 = TREE_CHAIN (it2))
7757 : {
7758 183 : tree var2 = OMP_ITERATOR_VAR (it2);
7759 183 : tree begin2 = OMP_ITERATOR_BEGIN (it2);
7760 183 : tree end2 = OMP_ITERATOR_END (it2);
7761 183 : tree step2 = OMP_ITERATOR_STEP (it2);
7762 183 : location_t loc2 = DECL_SOURCE_LOCATION (var2);
7763 183 : if (cp_walk_tree (&begin2, find_omp_placeholder_r, var, &pset))
7764 : {
7765 9 : error_at (EXPR_LOC_OR_LOC (begin2, loc2),
7766 : "begin expression refers to outer iterator %qD", var);
7767 36 : break;
7768 : }
7769 174 : else if (cp_walk_tree (&end2, find_omp_placeholder_r, var, &pset))
7770 : {
7771 9 : error_at (EXPR_LOC_OR_LOC (end2, loc2),
7772 : "end expression refers to outer iterator %qD", var);
7773 9 : break;
7774 : }
7775 165 : else if (cp_walk_tree (&step2, find_omp_placeholder_r, var, &pset))
7776 : {
7777 9 : error_at (EXPR_LOC_OR_LOC (step2, loc2),
7778 : "step expression refers to outer iterator %qD", var);
7779 9 : break;
7780 : }
7781 : }
7782 589 : if (it2)
7783 : {
7784 27 : ret = true;
7785 27 : continue;
7786 : }
7787 562 : OMP_ITERATOR_BEGIN (it) = begin;
7788 562 : OMP_ITERATOR_END (it) = end;
7789 562 : if (processing_template_decl)
7790 71 : OMP_ITERATOR_STEP (it) = orig_step;
7791 : else
7792 : {
7793 491 : OMP_ITERATOR_STEP (it) = step;
7794 491 : OMP_ITERATOR_ORIG_STEP (it) = orig_step;
7795 : }
7796 589 : }
7797 615 : return ret;
7798 : }
7799 :
7800 : /* Ensure that pointers are used in OpenACC attach and detach clauses.
7801 : Return true if an error has been detected. */
7802 :
7803 : static bool
7804 18655 : cp_oacc_check_attachments (tree c)
7805 : {
7806 18655 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
7807 : return false;
7808 :
7809 : /* OpenACC attach / detach clauses must be pointers. */
7810 14676 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
7811 14676 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
7812 : {
7813 196 : tree t = OMP_CLAUSE_DECL (c);
7814 196 : tree type;
7815 :
7816 232 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7817 36 : t = TREE_OPERAND (t, 0);
7818 :
7819 196 : type = TREE_TYPE (t);
7820 :
7821 196 : if (TREE_CODE (type) == REFERENCE_TYPE)
7822 36 : type = TREE_TYPE (type);
7823 :
7824 196 : if (TREE_CODE (type) != POINTER_TYPE)
7825 : {
7826 36 : error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause",
7827 : user_omp_clause_code_name (c, true));
7828 36 : return true;
7829 : }
7830 : }
7831 :
7832 : return false;
7833 : }
7834 :
7835 : /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution
7836 : happened. */
7837 :
7838 : tree
7839 813 : cp_finish_omp_init_prefer_type (tree pref_type)
7840 : {
7841 813 : if (processing_template_decl
7842 741 : || pref_type == NULL_TREE
7843 356 : || TREE_CODE (pref_type) != TREE_LIST)
7844 : return pref_type;
7845 :
7846 81 : tree t = TREE_PURPOSE (pref_type);
7847 81 : char *str = const_cast<char *> (TREE_STRING_POINTER (t));
7848 81 : tree fr_list = TREE_VALUE (pref_type);
7849 81 : int len = TREE_VEC_LENGTH (fr_list);
7850 81 : int cnt = 0;
7851 :
7852 270 : while (str[0] == (char) GOMP_INTEROP_IFR_SEPARATOR)
7853 : {
7854 270 : str++;
7855 270 : if (str[0] == (char) GOMP_INTEROP_IFR_UNKNOWN)
7856 : {
7857 : /* Assume a no or a single 'fr'. */
7858 150 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7859 150 : location_t loc = UNKNOWN_LOCATION;
7860 150 : tree value = TREE_VEC_ELT (fr_list, cnt);
7861 150 : if (value != NULL_TREE && value != error_mark_node)
7862 : {
7863 126 : loc = EXPR_LOCATION (value);
7864 126 : if (value && TREE_CODE (value) == NOP_EXPR)
7865 39 : value = TREE_OPERAND (value, 0);
7866 126 : value = cp_fully_fold (value);
7867 : }
7868 126 : if (value != NULL_TREE && value != error_mark_node)
7869 : {
7870 126 : if (TREE_CODE (value) != INTEGER_CST
7871 126 : || !tree_fits_shwi_p (value))
7872 0 : error_at (loc,
7873 : "expected string literal or "
7874 : "constant integer expression instead of %qE", value);
7875 : else
7876 : {
7877 126 : HOST_WIDE_INT n = tree_to_shwi (value);
7878 126 : if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
7879 : {
7880 48 : warning_at (loc, OPT_Wopenmp,
7881 : "unknown foreign runtime identifier %qwd", n);
7882 48 : n = GOMP_INTEROP_IFR_UNKNOWN;
7883 : }
7884 126 : str[0] = (char) n;
7885 : }
7886 : }
7887 150 : str++;
7888 : }
7889 120 : else if (str[0] != (char) GOMP_INTEROP_IFR_SEPARATOR)
7890 : {
7891 : /* Assume a no or a single 'fr'. */
7892 120 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7893 120 : str++;
7894 : }
7895 270 : str++;
7896 294 : while (str[0] != '\0')
7897 24 : str += strlen (str) + 1;
7898 270 : str++;
7899 270 : cnt++;
7900 270 : if (cnt >= len)
7901 : break;
7902 : }
7903 : return t;
7904 : }
7905 :
7906 : /* For all elements of CLAUSES, validate them vs OpenMP constraints.
7907 : Remove any elements from the list that are invalid. */
7908 :
7909 : tree
7910 62789 : finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
7911 : {
7912 62789 : bitmap_head generic_head, firstprivate_head, lastprivate_head;
7913 62789 : bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head;
7914 62789 : bitmap_head oacc_reduction_head, is_on_device_head;
7915 62789 : tree c, t, *pc;
7916 62789 : tree safelen = NULL_TREE;
7917 62789 : bool openacc = (ort & C_ORT_ACC) != 0;
7918 62789 : bool branch_seen = false;
7919 62789 : bool copyprivate_seen = false;
7920 62789 : bool ordered_seen = false;
7921 62789 : bool order_seen = false;
7922 62789 : bool schedule_seen = false;
7923 62789 : bool oacc_async = false;
7924 62789 : bool indir_component_ref_p = false;
7925 62789 : tree last_iterators = NULL_TREE;
7926 62789 : bool last_iterators_remove = false;
7927 : /* 1 if normal/task reduction has been seen, -1 if inscan reduction
7928 : has been seen, -2 if mixed inscan/normal reduction diagnosed. */
7929 62789 : int reduction_seen = 0;
7930 62789 : bool allocate_seen = false;
7931 62789 : tree detach_seen = NULL_TREE;
7932 62789 : bool mergeable_seen = false;
7933 62789 : bool implicit_moved = false;
7934 62789 : bool target_in_reduction_seen = false;
7935 62789 : bool num_tasks_seen = false;
7936 62789 : bool partial_seen = false;
7937 62789 : bool init_seen = false;
7938 62789 : bool init_use_destroy_seen = false;
7939 62789 : tree init_no_targetsync_clause = NULL_TREE;
7940 62789 : tree depend_clause = NULL_TREE;
7941 :
7942 62789 : if (!openacc)
7943 50054 : clauses = omp_remove_duplicate_maps (clauses, true);
7944 :
7945 62789 : bitmap_obstack_initialize (NULL);
7946 62789 : bitmap_initialize (&generic_head, &bitmap_default_obstack);
7947 62789 : bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
7948 62789 : bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
7949 62789 : bitmap_initialize (&aligned_head, &bitmap_default_obstack);
7950 : /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
7951 62789 : bitmap_initialize (&map_head, &bitmap_default_obstack);
7952 62789 : bitmap_initialize (&map_field_head, &bitmap_default_obstack);
7953 62789 : bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack);
7954 : /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
7955 : instead and for ort == C_ORT_OMP_TARGET used as in_reduction_head. */
7956 62789 : bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
7957 62789 : bitmap_initialize (&is_on_device_head, &bitmap_default_obstack);
7958 :
7959 62789 : if (openacc)
7960 28283 : for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
7961 15936 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
7962 : {
7963 : oacc_async = true;
7964 : break;
7965 : }
7966 :
7967 62789 : tree *grp_start_p = NULL, grp_sentinel = NULL_TREE;
7968 :
7969 160828 : for (pc = &clauses, c = clauses; c ; c = *pc)
7970 : {
7971 98039 : bool remove = false;
7972 98039 : bool field_ok = false;
7973 :
7974 : /* We've reached the end of a list of expanded nodes. Reset the group
7975 : start pointer. */
7976 98039 : if (c == grp_sentinel)
7977 : {
7978 5671 : if (grp_start_p
7979 5671 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
7980 96 : for (tree gc = *grp_start_p; gc != grp_sentinel;
7981 66 : gc = OMP_CLAUSE_CHAIN (gc))
7982 66 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
7983 : grp_start_p = NULL;
7984 : }
7985 :
7986 98039 : switch (OMP_CLAUSE_CODE (c))
7987 : {
7988 2100 : case OMP_CLAUSE_SHARED:
7989 2100 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7990 2100 : goto check_dup_generic;
7991 2584 : case OMP_CLAUSE_PRIVATE:
7992 2584 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
7993 2584 : goto check_dup_generic;
7994 7386 : case OMP_CLAUSE_REDUCTION:
7995 7386 : if (reduction_seen == 0)
7996 6267 : reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
7997 1119 : else if (reduction_seen != -2
7998 2238 : && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
7999 1119 : ? -1 : 1))
8000 : {
8001 6 : error_at (OMP_CLAUSE_LOCATION (c),
8002 : "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
8003 : "on the same construct");
8004 6 : reduction_seen = -2;
8005 : }
8006 : /* FALLTHRU */
8007 9531 : case OMP_CLAUSE_IN_REDUCTION:
8008 9531 : case OMP_CLAUSE_TASK_REDUCTION:
8009 9531 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8010 9531 : t = OMP_CLAUSE_DECL (c);
8011 9531 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
8012 : {
8013 2207 : if (handle_omp_array_sections (c, ort))
8014 : {
8015 : remove = true;
8016 : break;
8017 : }
8018 2165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8019 2165 : && OMP_CLAUSE_REDUCTION_INSCAN (c))
8020 : {
8021 3 : error_at (OMP_CLAUSE_LOCATION (c),
8022 : "%<inscan%> %<reduction%> clause with array "
8023 : "section");
8024 3 : remove = true;
8025 3 : break;
8026 : }
8027 2162 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
8028 : {
8029 4672 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
8030 2510 : t = TREE_OPERAND (t, 0);
8031 : }
8032 : else
8033 : {
8034 0 : gcc_assert (TREE_CODE (t) == MEM_REF);
8035 0 : t = TREE_OPERAND (t, 0);
8036 0 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
8037 0 : t = TREE_OPERAND (t, 0);
8038 0 : if (TREE_CODE (t) == ADDR_EXPR
8039 0 : || INDIRECT_REF_P (t))
8040 0 : t = TREE_OPERAND (t, 0);
8041 : }
8042 2162 : tree n = omp_clause_decl_field (t);
8043 2162 : if (n)
8044 59 : t = n;
8045 2162 : goto check_dup_generic_t;
8046 : }
8047 7324 : if (oacc_async)
8048 7 : cxx_mark_addressable (t);
8049 7324 : goto check_dup_generic;
8050 98 : case OMP_CLAUSE_COPYPRIVATE:
8051 98 : copyprivate_seen = true;
8052 98 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8053 98 : goto check_dup_generic;
8054 280 : case OMP_CLAUSE_COPYIN:
8055 280 : goto check_dup_generic;
8056 1631 : case OMP_CLAUSE_LINEAR:
8057 1631 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8058 1631 : t = OMP_CLAUSE_DECL (c);
8059 1631 : if (ort != C_ORT_OMP_DECLARE_SIMD
8060 1631 : && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
8061 : {
8062 84 : if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
8063 : {
8064 42 : error_at (OMP_CLAUSE_LOCATION (c),
8065 : "modifier should not be specified in %<linear%> "
8066 : "clause on %<simd%> or %<for%> constructs when "
8067 : "not using OpenMP 5.2 modifiers");
8068 42 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
8069 : }
8070 42 : else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_VAL)
8071 : {
8072 18 : error_at (OMP_CLAUSE_LOCATION (c),
8073 : "modifier other than %<val%> specified in "
8074 : "%<linear%> clause on %<simd%> or %<for%> "
8075 : "constructs when using OpenMP 5.2 modifiers");
8076 18 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
8077 : }
8078 : }
8079 1011 : if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
8080 2571 : && !type_dependent_expression_p (t))
8081 : {
8082 1529 : tree type = TREE_TYPE (t);
8083 1529 : if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
8084 1448 : || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL)
8085 1598 : && !TYPE_REF_P (type))
8086 : {
8087 12 : error_at (OMP_CLAUSE_LOCATION (c),
8088 : "linear clause with %qs modifier applied to "
8089 : "non-reference variable with %qT type",
8090 12 : OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
8091 12 : ? "ref" : "uval", TREE_TYPE (t));
8092 12 : remove = true;
8093 12 : break;
8094 : }
8095 1517 : if (TYPE_REF_P (type))
8096 281 : type = TREE_TYPE (type);
8097 1517 : if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
8098 : {
8099 1442 : if (!INTEGRAL_TYPE_P (type)
8100 85 : && !TYPE_PTR_P (type))
8101 : {
8102 18 : error_at (OMP_CLAUSE_LOCATION (c),
8103 : "linear clause applied to non-integral "
8104 : "non-pointer variable with %qT type",
8105 18 : TREE_TYPE (t));
8106 18 : remove = true;
8107 18 : break;
8108 : }
8109 : }
8110 : }
8111 1601 : t = OMP_CLAUSE_LINEAR_STEP (c);
8112 1601 : if (t == NULL_TREE)
8113 6 : t = integer_one_node;
8114 1601 : if (t == error_mark_node)
8115 : {
8116 : remove = true;
8117 : break;
8118 : }
8119 1601 : else if (!type_dependent_expression_p (t)
8120 1599 : && !INTEGRAL_TYPE_P (TREE_TYPE (t))
8121 1613 : && (ort != C_ORT_OMP_DECLARE_SIMD
8122 9 : || TREE_CODE (t) != PARM_DECL
8123 6 : || !TYPE_REF_P (TREE_TYPE (t))
8124 6 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
8125 : {
8126 6 : error_at (OMP_CLAUSE_LOCATION (c),
8127 : "linear step expression must be integral");
8128 6 : remove = true;
8129 6 : break;
8130 : }
8131 : else
8132 : {
8133 1595 : t = mark_rvalue_use (t);
8134 1595 : if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL)
8135 : {
8136 42 : OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
8137 42 : goto check_dup_generic;
8138 : }
8139 1553 : if (!processing_template_decl
8140 1553 : && (VAR_P (OMP_CLAUSE_DECL (c))
8141 835 : || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
8142 : {
8143 1372 : if (ort == C_ORT_OMP_DECLARE_SIMD)
8144 : {
8145 589 : t = maybe_constant_value (t);
8146 589 : if (TREE_CODE (t) != INTEGER_CST)
8147 : {
8148 6 : error_at (OMP_CLAUSE_LOCATION (c),
8149 : "%<linear%> clause step %qE is neither "
8150 : "constant nor a parameter", t);
8151 6 : remove = true;
8152 6 : break;
8153 : }
8154 : }
8155 1366 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8156 1366 : tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
8157 1366 : if (TYPE_REF_P (type))
8158 257 : type = TREE_TYPE (type);
8159 1366 : if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
8160 : {
8161 66 : type = build_pointer_type (type);
8162 66 : tree d = fold_convert (type, OMP_CLAUSE_DECL (c));
8163 66 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8164 : d, t);
8165 66 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8166 : MINUS_EXPR, sizetype,
8167 : fold_convert (sizetype, t),
8168 : fold_convert (sizetype, d));
8169 66 : if (t == error_mark_node)
8170 : {
8171 : remove = true;
8172 : break;
8173 : }
8174 : }
8175 1300 : else if (TYPE_PTR_P (type)
8176 : /* Can't multiply the step yet if *this
8177 : is still incomplete type. */
8178 1300 : && (ort != C_ORT_OMP_DECLARE_SIMD
8179 45 : || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
8180 45 : || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
8181 30 : || DECL_NAME (OMP_CLAUSE_DECL (c))
8182 30 : != this_identifier
8183 30 : || !TYPE_BEING_DEFINED (TREE_TYPE (type))))
8184 : {
8185 37 : tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
8186 37 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8187 : d, t);
8188 37 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8189 : MINUS_EXPR, sizetype,
8190 : fold_convert (sizetype, t),
8191 : fold_convert (sizetype, d));
8192 37 : if (t == error_mark_node)
8193 : {
8194 : remove = true;
8195 : break;
8196 : }
8197 : }
8198 : else
8199 1263 : t = fold_convert (type, t);
8200 : }
8201 1547 : OMP_CLAUSE_LINEAR_STEP (c) = t;
8202 : }
8203 1547 : goto check_dup_generic;
8204 14941 : check_dup_generic:
8205 14941 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8206 14941 : if (t)
8207 : {
8208 101 : if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED)
8209 101 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8210 : }
8211 : else
8212 14840 : t = OMP_CLAUSE_DECL (c);
8213 17370 : check_dup_generic_t:
8214 17370 : if (t == current_class_ptr
8215 17370 : && ((ort != C_ORT_OMP_DECLARE_SIMD && !openacc)
8216 102 : || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
8217 72 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
8218 : {
8219 24 : error_at (OMP_CLAUSE_LOCATION (c),
8220 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8221 : " clauses");
8222 24 : remove = true;
8223 24 : break;
8224 : }
8225 17346 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8226 586 : && (!field_ok || TREE_CODE (t) != FIELD_DECL))
8227 : {
8228 59 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8229 : break;
8230 39 : if (DECL_P (t))
8231 30 : error_at (OMP_CLAUSE_LOCATION (c),
8232 : "%qD is not a variable in clause %qs", t,
8233 15 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8234 : else
8235 48 : error_at (OMP_CLAUSE_LOCATION (c),
8236 : "%qE is not a variable in clause %qs", t,
8237 24 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8238 : remove = true;
8239 : }
8240 17287 : else if ((openacc
8241 2707 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
8242 14818 : || (ort == C_ORT_OMP
8243 12485 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
8244 12454 : || (OMP_CLAUSE_CODE (c)
8245 : == OMP_CLAUSE_USE_DEVICE_ADDR)))
8246 31998 : || (ort == C_ORT_OMP_TARGET
8247 938 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION))
8248 : {
8249 2854 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8250 2854 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8251 275 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))))
8252 : {
8253 6 : error_at (OMP_CLAUSE_LOCATION (c),
8254 : "%qD appears more than once in data-sharing "
8255 : "clauses", t);
8256 6 : remove = true;
8257 6 : break;
8258 : }
8259 2848 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
8260 272 : target_in_reduction_seen = true;
8261 2848 : if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8262 : {
8263 12 : error_at (OMP_CLAUSE_LOCATION (c),
8264 : openacc
8265 : ? "%qD appears more than once in reduction clauses"
8266 : : "%qD appears more than once in data clauses",
8267 : t);
8268 6 : remove = true;
8269 : }
8270 : else
8271 2842 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8272 : }
8273 14433 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8274 14360 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8275 14357 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t))
8276 28790 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8277 : {
8278 76 : error_at (OMP_CLAUSE_LOCATION (c),
8279 : "%qD appears more than once in data clauses", t);
8280 76 : remove = true;
8281 : }
8282 14357 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
8283 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
8284 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
8285 3125 : && bitmap_bit_p (&map_head, DECL_UID (t)))
8286 : {
8287 9 : if (openacc)
8288 0 : error_at (OMP_CLAUSE_LOCATION (c),
8289 : "%qD appears more than once in data clauses", t);
8290 : else
8291 9 : error_at (OMP_CLAUSE_LOCATION (c),
8292 : "%qD appears both in data and map clauses", t);
8293 : remove = true;
8294 : }
8295 : else
8296 14348 : bitmap_set_bit (&generic_head, DECL_UID (t));
8297 17320 : if (!field_ok)
8298 : break;
8299 12909 : handle_field_decl:
8300 21449 : if (!remove
8301 21254 : && TREE_CODE (t) == FIELD_DECL
8302 16567 : && t == OMP_CLAUSE_DECL (c))
8303 : {
8304 795 : OMP_CLAUSE_DECL (c)
8305 795 : = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
8306 : == OMP_CLAUSE_SHARED));
8307 795 : if (OMP_CLAUSE_DECL (c) == error_mark_node)
8308 97570 : remove = true;
8309 : }
8310 : break;
8311 :
8312 3480 : case OMP_CLAUSE_FIRSTPRIVATE:
8313 3480 : if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved)
8314 : {
8315 414 : move_implicit:
8316 414 : implicit_moved = true;
8317 : /* Move firstprivate and map clauses with
8318 : OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of
8319 : clauses chain. */
8320 414 : tree cl1 = NULL_TREE, cl2 = NULL_TREE;
8321 414 : tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2;
8322 2704 : while (*pc1)
8323 2290 : if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE
8324 2290 : && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1))
8325 : {
8326 275 : *pc3 = *pc1;
8327 275 : pc3 = &OMP_CLAUSE_CHAIN (*pc3);
8328 275 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8329 : }
8330 2015 : else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP
8331 2015 : && OMP_CLAUSE_MAP_IMPLICIT (*pc1))
8332 : {
8333 370 : *pc2 = *pc1;
8334 370 : pc2 = &OMP_CLAUSE_CHAIN (*pc2);
8335 370 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8336 : }
8337 : else
8338 1645 : pc1 = &OMP_CLAUSE_CHAIN (*pc1);
8339 414 : *pc3 = NULL;
8340 414 : *pc2 = cl2;
8341 414 : *pc1 = cl1;
8342 414 : continue;
8343 414 : }
8344 3223 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8345 3223 : if (t)
8346 69 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8347 : else
8348 3154 : t = OMP_CLAUSE_DECL (c);
8349 3223 : if (!openacc && t == current_class_ptr)
8350 : {
8351 6 : error_at (OMP_CLAUSE_LOCATION (c),
8352 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8353 : " clauses");
8354 6 : remove = true;
8355 6 : break;
8356 : }
8357 3217 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8358 333 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8359 333 : || TREE_CODE (t) != FIELD_DECL))
8360 : {
8361 41 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8362 : break;
8363 18 : if (DECL_P (t))
8364 12 : error_at (OMP_CLAUSE_LOCATION (c),
8365 : "%qD is not a variable in clause %<firstprivate%>",
8366 : t);
8367 : else
8368 6 : error_at (OMP_CLAUSE_LOCATION (c),
8369 : "%qE is not a variable in clause %<firstprivate%>",
8370 : t);
8371 18 : remove = true;
8372 : }
8373 3176 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8374 275 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c)
8375 3430 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8376 : remove = true;
8377 3176 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8378 3167 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8379 6340 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8380 : {
8381 15 : error_at (OMP_CLAUSE_LOCATION (c),
8382 : "%qD appears more than once in data clauses", t);
8383 15 : remove = true;
8384 : }
8385 3161 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
8386 3161 : || bitmap_bit_p (&map_field_head, DECL_UID (t)))
8387 : {
8388 21 : if (openacc)
8389 0 : error_at (OMP_CLAUSE_LOCATION (c),
8390 : "%qD appears more than once in data clauses", t);
8391 21 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8392 21 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c))
8393 : /* Silently drop the clause. */;
8394 : else
8395 18 : error_at (OMP_CLAUSE_LOCATION (c),
8396 : "%qD appears both in data and map clauses", t);
8397 21 : remove = true;
8398 : }
8399 : else
8400 3140 : bitmap_set_bit (&firstprivate_head, DECL_UID (t));
8401 3194 : goto handle_field_decl;
8402 :
8403 2793 : case OMP_CLAUSE_LASTPRIVATE:
8404 2793 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8405 2793 : if (t)
8406 35 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8407 : else
8408 2758 : t = OMP_CLAUSE_DECL (c);
8409 2793 : if (!openacc && t == current_class_ptr)
8410 : {
8411 6 : error_at (OMP_CLAUSE_LOCATION (c),
8412 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8413 : " clauses");
8414 6 : remove = true;
8415 6 : break;
8416 : }
8417 2787 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8418 259 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8419 259 : || TREE_CODE (t) != FIELD_DECL))
8420 : {
8421 35 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8422 : break;
8423 9 : if (DECL_P (t))
8424 3 : error_at (OMP_CLAUSE_LOCATION (c),
8425 : "%qD is not a variable in clause %<lastprivate%>",
8426 : t);
8427 : else
8428 6 : error_at (OMP_CLAUSE_LOCATION (c),
8429 : "%qE is not a variable in clause %<lastprivate%>",
8430 : t);
8431 9 : remove = true;
8432 : }
8433 2752 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8434 2752 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8435 : {
8436 12 : error_at (OMP_CLAUSE_LOCATION (c),
8437 : "%qD appears more than once in data clauses", t);
8438 12 : remove = true;
8439 : }
8440 : else
8441 2740 : bitmap_set_bit (&lastprivate_head, DECL_UID (t));
8442 2761 : goto handle_field_decl;
8443 :
8444 2221 : case OMP_CLAUSE_IF:
8445 2221 : case OMP_CLAUSE_SELF:
8446 2221 : t = OMP_CLAUSE_OPERAND (c, 0);
8447 2221 : t = maybe_convert_cond (t);
8448 2221 : if (t == error_mark_node)
8449 : remove = true;
8450 2206 : else if (!processing_template_decl)
8451 2145 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8452 2221 : OMP_CLAUSE_OPERAND (c, 0) = t;
8453 2221 : break;
8454 :
8455 289 : case OMP_CLAUSE_FINAL:
8456 289 : t = OMP_CLAUSE_FINAL_EXPR (c);
8457 289 : t = maybe_convert_cond (t);
8458 289 : if (t == error_mark_node)
8459 : remove = true;
8460 289 : else if (!processing_template_decl)
8461 283 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8462 289 : OMP_CLAUSE_FINAL_EXPR (c) = t;
8463 289 : break;
8464 :
8465 92 : case OMP_CLAUSE_NOCONTEXT:
8466 92 : t = OMP_CLAUSE_NOCONTEXT_EXPR (c);
8467 92 : t = maybe_convert_cond (t);
8468 92 : if (t == error_mark_node)
8469 : remove = true;
8470 89 : else if (!processing_template_decl)
8471 83 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8472 92 : OMP_CLAUSE_NOCONTEXT_EXPR (c) = t;
8473 92 : break;
8474 :
8475 80 : case OMP_CLAUSE_NOVARIANTS:
8476 80 : t = OMP_CLAUSE_NOVARIANTS_EXPR (c);
8477 80 : t = maybe_convert_cond (t);
8478 80 : if (t == error_mark_node)
8479 : remove = true;
8480 77 : else if (!processing_template_decl)
8481 71 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8482 80 : OMP_CLAUSE_NOVARIANTS_EXPR (c) = t;
8483 80 : break;
8484 :
8485 1249 : case OMP_CLAUSE_GANG:
8486 : /* Operand 1 is the gang static: argument. */
8487 1249 : t = OMP_CLAUSE_OPERAND (c, 1);
8488 1249 : if (t != NULL_TREE)
8489 : {
8490 129 : if (t == error_mark_node)
8491 : remove = true;
8492 129 : else if (!type_dependent_expression_p (t)
8493 129 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8494 : {
8495 6 : error_at (OMP_CLAUSE_LOCATION (c),
8496 : "%<gang%> static expression must be integral");
8497 6 : remove = true;
8498 : }
8499 : else
8500 : {
8501 123 : t = mark_rvalue_use (t);
8502 123 : if (!processing_template_decl)
8503 : {
8504 123 : t = maybe_constant_value (t);
8505 123 : if (TREE_CODE (t) == INTEGER_CST
8506 109 : && tree_int_cst_sgn (t) != 1
8507 176 : && t != integer_minus_one_node)
8508 : {
8509 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8510 : "%<gang%> static value must be "
8511 : "positive");
8512 0 : t = integer_one_node;
8513 : }
8514 123 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8515 : }
8516 : }
8517 129 : OMP_CLAUSE_OPERAND (c, 1) = t;
8518 : }
8519 : /* Check operand 0, the num argument. */
8520 : /* FALLTHRU */
8521 :
8522 3480 : case OMP_CLAUSE_WORKER:
8523 3480 : case OMP_CLAUSE_VECTOR:
8524 3480 : if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
8525 : break;
8526 : /* FALLTHRU */
8527 :
8528 484 : case OMP_CLAUSE_NUM_TASKS:
8529 484 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TASKS)
8530 136 : num_tasks_seen = true;
8531 : /* FALLTHRU */
8532 :
8533 3034 : case OMP_CLAUSE_NUM_TEAMS:
8534 3034 : case OMP_CLAUSE_NUM_THREADS:
8535 3034 : case OMP_CLAUSE_NUM_GANGS:
8536 3034 : case OMP_CLAUSE_NUM_WORKERS:
8537 3034 : case OMP_CLAUSE_DYN_GROUPPRIVATE:
8538 3034 : case OMP_CLAUSE_VECTOR_LENGTH:
8539 3034 : t = OMP_CLAUSE_OPERAND (c, 0);
8540 3034 : if (t == error_mark_node)
8541 : remove = true;
8542 3034 : else if (!type_dependent_expression_p (t)
8543 3034 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8544 : {
8545 99 : switch (OMP_CLAUSE_CODE (c))
8546 : {
8547 12 : case OMP_CLAUSE_GANG:
8548 12 : error_at (OMP_CLAUSE_LOCATION (c),
8549 12 : "%<gang%> num expression must be integral"); break;
8550 12 : case OMP_CLAUSE_VECTOR:
8551 12 : error_at (OMP_CLAUSE_LOCATION (c),
8552 : "%<vector%> length expression must be integral");
8553 12 : break;
8554 12 : case OMP_CLAUSE_WORKER:
8555 12 : error_at (OMP_CLAUSE_LOCATION (c),
8556 : "%<worker%> num expression must be integral");
8557 12 : break;
8558 63 : default:
8559 63 : error_at (OMP_CLAUSE_LOCATION (c),
8560 : "%qs expression must be integral",
8561 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8562 : }
8563 : remove = true;
8564 : }
8565 : else
8566 : {
8567 2935 : t = mark_rvalue_use (t);
8568 2935 : if (!processing_template_decl)
8569 : {
8570 2687 : t = maybe_constant_value (t);
8571 2687 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
8572 2652 : && TREE_CODE (t) == INTEGER_CST
8573 4142 : && tree_int_cst_sgn (t) != 1)
8574 : {
8575 85 : switch (OMP_CLAUSE_CODE (c))
8576 : {
8577 3 : case OMP_CLAUSE_GANG:
8578 3 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8579 : "%<gang%> num value must be positive");
8580 3 : break;
8581 0 : case OMP_CLAUSE_VECTOR:
8582 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8583 : "%<vector%> length value must be "
8584 : "positive");
8585 0 : break;
8586 0 : case OMP_CLAUSE_WORKER:
8587 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8588 : "%<worker%> num value must be "
8589 : "positive");
8590 0 : break;
8591 82 : default:
8592 82 : warning_at (OMP_CLAUSE_LOCATION (c),
8593 46 : (flag_openmp || flag_openmp_simd)
8594 82 : ? OPT_Wopenmp : 0,
8595 : "%qs value must be positive",
8596 : omp_clause_code_name
8597 82 : [OMP_CLAUSE_CODE (c)]);
8598 : }
8599 85 : t = integer_one_node;
8600 : }
8601 2602 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
8602 35 : && TREE_CODE (t) == INTEGER_CST
8603 2625 : && tree_int_cst_sgn (t) < 0)
8604 : {
8605 8 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8606 : "%<dyn_groupprivate%> value must be "
8607 : "non-negative");
8608 8 : t = integer_zero_node;
8609 : }
8610 2687 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8611 : }
8612 2935 : OMP_CLAUSE_OPERAND (c, 0) = t;
8613 : }
8614 3034 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
8615 752 : && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
8616 3313 : && !remove)
8617 : {
8618 279 : t = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
8619 279 : if (t == error_mark_node)
8620 : remove = true;
8621 279 : else if (!type_dependent_expression_p (t)
8622 279 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8623 : {
8624 0 : error_at (OMP_CLAUSE_LOCATION (c),
8625 : "%qs expression must be integral",
8626 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8627 0 : remove = true;
8628 : }
8629 : else
8630 : {
8631 279 : t = mark_rvalue_use (t);
8632 279 : if (!processing_template_decl)
8633 : {
8634 213 : t = maybe_constant_value (t);
8635 213 : if (TREE_CODE (t) == INTEGER_CST
8636 213 : && tree_int_cst_sgn (t) != 1)
8637 : {
8638 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8639 : "%qs value must be positive",
8640 : omp_clause_code_name
8641 18 : [OMP_CLAUSE_CODE (c)]);
8642 18 : t = NULL_TREE;
8643 : }
8644 : else
8645 195 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8646 213 : tree upper = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
8647 213 : if (t
8648 195 : && TREE_CODE (t) == INTEGER_CST
8649 43 : && TREE_CODE (upper) == INTEGER_CST
8650 250 : && tree_int_cst_lt (upper, t))
8651 : {
8652 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8653 : "%<num_teams%> lower bound %qE bigger "
8654 : "than upper bound %qE", t, upper);
8655 18 : t = NULL_TREE;
8656 : }
8657 : }
8658 279 : OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = t;
8659 : }
8660 : }
8661 : break;
8662 :
8663 3886 : case OMP_CLAUSE_SCHEDULE:
8664 3886 : t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
8665 3886 : if (t == NULL)
8666 : ;
8667 2090 : else if (t == error_mark_node)
8668 : remove = true;
8669 2090 : else if (!type_dependent_expression_p (t)
8670 2090 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8671 : {
8672 9 : error_at (OMP_CLAUSE_LOCATION (c),
8673 : "schedule chunk size expression must be integral");
8674 9 : remove = true;
8675 : }
8676 : else
8677 : {
8678 2081 : t = mark_rvalue_use (t);
8679 2081 : if (!processing_template_decl)
8680 : {
8681 2041 : t = maybe_constant_value (t);
8682 2041 : if (TREE_CODE (t) == INTEGER_CST
8683 2041 : && tree_int_cst_sgn (t) != 1)
8684 : {
8685 6 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8686 : "chunk size value must be positive");
8687 6 : t = integer_one_node;
8688 : }
8689 2041 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8690 : }
8691 2081 : OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
8692 : }
8693 2090 : if (!remove)
8694 : schedule_seen = true;
8695 : break;
8696 :
8697 1268 : case OMP_CLAUSE_SIMDLEN:
8698 1268 : case OMP_CLAUSE_SAFELEN:
8699 1268 : t = OMP_CLAUSE_OPERAND (c, 0);
8700 1268 : if (t == error_mark_node)
8701 : remove = true;
8702 1268 : else if (!type_dependent_expression_p (t)
8703 1268 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8704 : {
8705 0 : error_at (OMP_CLAUSE_LOCATION (c),
8706 : "%qs length expression must be integral",
8707 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8708 0 : remove = true;
8709 : }
8710 : else
8711 : {
8712 1268 : t = mark_rvalue_use (t);
8713 1268 : if (!processing_template_decl)
8714 : {
8715 1219 : t = maybe_constant_value (t);
8716 1219 : if (TREE_CODE (t) != INTEGER_CST
8717 1219 : || tree_int_cst_sgn (t) != 1)
8718 : {
8719 0 : error_at (OMP_CLAUSE_LOCATION (c),
8720 : "%qs length expression must be positive "
8721 : "constant integer expression",
8722 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8723 0 : remove = true;
8724 : }
8725 : }
8726 1268 : OMP_CLAUSE_OPERAND (c, 0) = t;
8727 1268 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN)
8728 470 : safelen = c;
8729 : }
8730 : break;
8731 :
8732 388 : case OMP_CLAUSE_ASYNC:
8733 388 : t = OMP_CLAUSE_ASYNC_EXPR (c);
8734 388 : if (t == error_mark_node)
8735 : remove = true;
8736 373 : else if (!type_dependent_expression_p (t)
8737 373 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8738 : {
8739 12 : error_at (OMP_CLAUSE_LOCATION (c),
8740 : "%<async%> expression must be integral");
8741 12 : remove = true;
8742 : }
8743 : else
8744 : {
8745 361 : t = mark_rvalue_use (t);
8746 361 : if (!processing_template_decl)
8747 352 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8748 361 : OMP_CLAUSE_ASYNC_EXPR (c) = t;
8749 : }
8750 : break;
8751 :
8752 204 : case OMP_CLAUSE_WAIT:
8753 204 : t = OMP_CLAUSE_WAIT_EXPR (c);
8754 204 : if (t == error_mark_node)
8755 : remove = true;
8756 204 : else if (!processing_template_decl)
8757 196 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8758 204 : OMP_CLAUSE_WAIT_EXPR (c) = t;
8759 204 : break;
8760 :
8761 637 : case OMP_CLAUSE_THREAD_LIMIT:
8762 637 : t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
8763 637 : if (t == error_mark_node)
8764 : remove = true;
8765 637 : else if (!type_dependent_expression_p (t)
8766 637 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8767 : {
8768 0 : error_at (OMP_CLAUSE_LOCATION (c),
8769 : "%<thread_limit%> expression must be integral");
8770 0 : remove = true;
8771 : }
8772 : else
8773 : {
8774 637 : t = mark_rvalue_use (t);
8775 637 : if (!processing_template_decl)
8776 : {
8777 583 : t = maybe_constant_value (t);
8778 583 : if (TREE_CODE (t) == INTEGER_CST
8779 583 : && tree_int_cst_sgn (t) != 1)
8780 : {
8781 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8782 : "%<thread_limit%> value must be positive");
8783 0 : t = integer_one_node;
8784 : }
8785 583 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8786 : }
8787 637 : OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
8788 : }
8789 : break;
8790 :
8791 770 : case OMP_CLAUSE_DEVICE:
8792 770 : t = OMP_CLAUSE_DEVICE_ID (c);
8793 770 : if (t == error_mark_node)
8794 : remove = true;
8795 770 : else if (!type_dependent_expression_p (t)
8796 770 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8797 : {
8798 6 : error_at (OMP_CLAUSE_LOCATION (c),
8799 : "%<device%> id must be integral");
8800 6 : remove = true;
8801 : }
8802 764 : else if (OMP_CLAUSE_DEVICE_ANCESTOR (c)
8803 66 : && TREE_CODE (t) == INTEGER_CST
8804 824 : && !integer_onep (t))
8805 : {
8806 3 : error_at (OMP_CLAUSE_LOCATION (c),
8807 : "the %<device%> clause expression must evaluate to "
8808 : "%<1%>");
8809 3 : remove = true;
8810 : }
8811 : else
8812 : {
8813 761 : t = mark_rvalue_use (t);
8814 761 : if (!processing_template_decl)
8815 750 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8816 761 : OMP_CLAUSE_DEVICE_ID (c) = t;
8817 : }
8818 : break;
8819 :
8820 1845 : case OMP_CLAUSE_DIST_SCHEDULE:
8821 1845 : t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c);
8822 1845 : if (t == NULL)
8823 : ;
8824 1824 : else if (t == error_mark_node)
8825 : remove = true;
8826 1824 : else if (!type_dependent_expression_p (t)
8827 1824 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8828 : {
8829 0 : error_at (OMP_CLAUSE_LOCATION (c),
8830 : "%<dist_schedule%> chunk size expression must be "
8831 : "integral");
8832 0 : remove = true;
8833 : }
8834 : else
8835 : {
8836 1824 : t = mark_rvalue_use (t);
8837 1824 : if (!processing_template_decl)
8838 1824 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8839 1824 : OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
8840 : }
8841 : break;
8842 :
8843 807 : case OMP_CLAUSE_ALIGNED:
8844 807 : t = OMP_CLAUSE_DECL (c);
8845 807 : if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD)
8846 : {
8847 0 : error_at (OMP_CLAUSE_LOCATION (c),
8848 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8849 : " clauses");
8850 0 : remove = true;
8851 0 : break;
8852 : }
8853 807 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8854 : {
8855 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8856 : break;
8857 0 : if (DECL_P (t))
8858 0 : error_at (OMP_CLAUSE_LOCATION (c),
8859 : "%qD is not a variable in %<aligned%> clause", t);
8860 : else
8861 0 : error_at (OMP_CLAUSE_LOCATION (c),
8862 : "%qE is not a variable in %<aligned%> clause", t);
8863 : remove = true;
8864 : }
8865 807 : else if (!type_dependent_expression_p (t)
8866 789 : && !TYPE_PTR_P (TREE_TYPE (t))
8867 111 : && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
8868 864 : && (!TYPE_REF_P (TREE_TYPE (t))
8869 39 : || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
8870 30 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
8871 : != ARRAY_TYPE))))
8872 : {
8873 33 : error_at (OMP_CLAUSE_LOCATION (c),
8874 : "%qE in %<aligned%> clause is neither a pointer nor "
8875 : "an array nor a reference to pointer or array", t);
8876 33 : remove = true;
8877 : }
8878 774 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8879 : {
8880 0 : error_at (OMP_CLAUSE_LOCATION (c),
8881 : "%qD appears more than once in %<aligned%> clauses",
8882 : t);
8883 0 : remove = true;
8884 : }
8885 : else
8886 774 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8887 807 : t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c);
8888 807 : if (t == error_mark_node)
8889 : remove = true;
8890 807 : else if (t == NULL_TREE)
8891 : break;
8892 744 : else if (!type_dependent_expression_p (t)
8893 744 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8894 : {
8895 0 : error_at (OMP_CLAUSE_LOCATION (c),
8896 : "%<aligned%> clause alignment expression must "
8897 : "be integral");
8898 0 : remove = true;
8899 : }
8900 : else
8901 : {
8902 744 : t = mark_rvalue_use (t);
8903 744 : if (!processing_template_decl)
8904 : {
8905 690 : t = maybe_constant_value (t);
8906 690 : if (TREE_CODE (t) != INTEGER_CST
8907 690 : || tree_int_cst_sgn (t) != 1)
8908 : {
8909 0 : error_at (OMP_CLAUSE_LOCATION (c),
8910 : "%<aligned%> clause alignment expression must "
8911 : "be positive constant integer expression");
8912 0 : remove = true;
8913 : }
8914 : }
8915 744 : OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t;
8916 : }
8917 : break;
8918 :
8919 369 : case OMP_CLAUSE_NONTEMPORAL:
8920 369 : t = OMP_CLAUSE_DECL (c);
8921 369 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8922 : {
8923 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8924 : break;
8925 0 : if (DECL_P (t))
8926 0 : error_at (OMP_CLAUSE_LOCATION (c),
8927 : "%qD is not a variable in %<nontemporal%> clause",
8928 : t);
8929 : else
8930 0 : error_at (OMP_CLAUSE_LOCATION (c),
8931 : "%qE is not a variable in %<nontemporal%> clause",
8932 : t);
8933 : remove = true;
8934 : }
8935 369 : else if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8936 : {
8937 6 : error_at (OMP_CLAUSE_LOCATION (c),
8938 : "%qD appears more than once in %<nontemporal%> "
8939 : "clauses", t);
8940 6 : remove = true;
8941 : }
8942 : else
8943 363 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8944 : break;
8945 :
8946 2601 : case OMP_CLAUSE_ALLOCATE:
8947 2601 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8948 2601 : if (t)
8949 14 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8950 : else
8951 2587 : t = OMP_CLAUSE_DECL (c);
8952 2601 : if (t == current_class_ptr)
8953 : {
8954 0 : error_at (OMP_CLAUSE_LOCATION (c),
8955 : "%<this%> not allowed in %<allocate%> clause");
8956 0 : remove = true;
8957 0 : break;
8958 : }
8959 2601 : if (!VAR_P (t)
8960 558 : && TREE_CODE (t) != PARM_DECL
8961 45 : && TREE_CODE (t) != FIELD_DECL)
8962 : {
8963 3 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8964 : break;
8965 3 : if (DECL_P (t))
8966 3 : error_at (OMP_CLAUSE_LOCATION (c),
8967 : "%qD is not a variable in %<allocate%> clause", t);
8968 : else
8969 0 : error_at (OMP_CLAUSE_LOCATION (c),
8970 : "%qE is not a variable in %<allocate%> clause", t);
8971 : remove = true;
8972 : }
8973 2598 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8974 : {
8975 12 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8976 : "%qD appears more than once in %<allocate%> clauses",
8977 : t);
8978 12 : remove = true;
8979 : }
8980 : else
8981 : {
8982 2586 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8983 2586 : allocate_seen = true;
8984 : }
8985 2601 : tree allocator, align;
8986 2601 : align = OMP_CLAUSE_ALLOCATE_ALIGN (c);
8987 2601 : if (error_operand_p (align))
8988 : {
8989 : remove = true;
8990 : break;
8991 : }
8992 2601 : if (align)
8993 : {
8994 211 : if (!type_dependent_expression_p (align)
8995 211 : && !INTEGRAL_TYPE_P (TREE_TYPE (align)))
8996 : {
8997 4 : error_at (OMP_CLAUSE_LOCATION (c),
8998 : "%<allocate%> clause %<align%> modifier "
8999 : "argument needs to be positive constant "
9000 : "power of two integer expression");
9001 4 : remove = true;
9002 : }
9003 : else
9004 : {
9005 207 : align = mark_rvalue_use (align);
9006 207 : if (!processing_template_decl)
9007 : {
9008 192 : align = maybe_constant_value (align);
9009 192 : if (TREE_CODE (align) != INTEGER_CST
9010 189 : || !tree_fits_uhwi_p (align)
9011 381 : || !integer_pow2p (align))
9012 : {
9013 10 : error_at (OMP_CLAUSE_LOCATION (c),
9014 : "%<allocate%> clause %<align%> modifier "
9015 : "argument needs to be positive constant "
9016 : "power of two integer expression");
9017 10 : remove = true;
9018 : }
9019 : }
9020 : }
9021 211 : OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
9022 : }
9023 2601 : allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
9024 2601 : if (error_operand_p (allocator))
9025 : {
9026 : remove = true;
9027 : break;
9028 : }
9029 2601 : if (allocator == NULL_TREE)
9030 1543 : goto handle_field_decl;
9031 1058 : tree allocatort;
9032 1058 : allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator));
9033 1058 : if (!type_dependent_expression_p (allocator)
9034 1058 : && (TREE_CODE (allocatort) != ENUMERAL_TYPE
9035 1039 : || TYPE_NAME (allocatort) == NULL_TREE
9036 1039 : || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL
9037 2078 : || (DECL_NAME (TYPE_NAME (allocatort))
9038 1039 : != get_identifier ("omp_allocator_handle_t"))
9039 1039 : || (TYPE_CONTEXT (allocatort)
9040 1039 : != DECL_CONTEXT (global_namespace))))
9041 : {
9042 16 : error_at (OMP_CLAUSE_LOCATION (c),
9043 : "%<allocate%> clause allocator expression has "
9044 : "type %qT rather than %<omp_allocator_handle_t%>",
9045 16 : TREE_TYPE (allocator));
9046 16 : remove = true;
9047 16 : break;
9048 : }
9049 : else
9050 : {
9051 1042 : allocator = mark_rvalue_use (allocator);
9052 1042 : if (!processing_template_decl)
9053 1023 : allocator = maybe_constant_value (allocator);
9054 1042 : OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
9055 : }
9056 1042 : goto handle_field_decl;
9057 :
9058 654 : case OMP_CLAUSE_DOACROSS:
9059 654 : t = OMP_CLAUSE_DECL (c);
9060 654 : if (t == NULL_TREE)
9061 : break;
9062 298 : if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
9063 : {
9064 298 : if (cp_finish_omp_clause_doacross_sink (c))
9065 7 : remove = true;
9066 : break;
9067 : }
9068 0 : gcc_unreachable ();
9069 89 : case OMP_CLAUSE_USES_ALLOCATORS:
9070 89 : t = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
9071 89 : t = convert_from_reference (t);
9072 89 : if (t == error_mark_node)
9073 : {
9074 : remove = true;
9075 : break;
9076 : }
9077 82 : if (DECL_P (t)
9078 82 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
9079 79 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9080 78 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
9081 : {
9082 1 : error_at (OMP_CLAUSE_LOCATION (c),
9083 : "%qE appears more than once in data clauses", t);
9084 1 : remove = true;
9085 : }
9086 81 : else if (DECL_P (t))
9087 78 : bitmap_set_bit (&generic_head, DECL_UID (t));
9088 82 : if (type_dependent_expression_p (t))
9089 : break;
9090 77 : if (TREE_CODE (t) == FIELD_DECL)
9091 : {
9092 0 : sorry_at (OMP_CLAUSE_LOCATION (c), "class member %qE not yet "
9093 : "supported in %<uses_allocators%> clause", t);
9094 0 : remove = true;
9095 0 : break;
9096 : }
9097 77 : if (TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9098 151 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9099 : "omp_allocator_handle_t") != 0)
9100 : {
9101 3 : error_at (OMP_CLAUSE_LOCATION (c),
9102 : "allocator %qE must be of %<omp_allocator_handle_t%> "
9103 : "type", t);
9104 3 : remove = true;
9105 3 : break;
9106 : }
9107 74 : tree init;
9108 74 : if (TREE_CODE (t) == CONST_DECL)
9109 7 : init = DECL_INITIAL(t);
9110 : else
9111 : init = t;
9112 74 : if (!DECL_P (t)
9113 74 : && (init == NULL_TREE
9114 3 : || TREE_CODE (init) != INTEGER_CST
9115 3 : || ((wi::to_widest (init) < 0
9116 3 : || wi::to_widest (init) > GOMP_OMP_PREDEF_ALLOC_MAX)
9117 1 : && (wi::to_widest (init) < GOMP_OMPX_PREDEF_ALLOC_MIN
9118 1 : || (wi::to_widest (init)
9119 2 : > GOMP_OMPX_PREDEF_ALLOC_MAX)))))
9120 : {
9121 1 : remove = true;
9122 1 : error_at (OMP_CLAUSE_LOCATION (c),
9123 : "allocator %qE must be either a variable or a "
9124 : "predefined allocator", t);
9125 1 : break;
9126 : }
9127 73 : else if (TREE_CODE (t) == CONST_DECL)
9128 : {
9129 : /* omp_null_allocator is ignored and for predefined allocators,
9130 : not special handling is required; thus, remove them removed. */
9131 7 : remove = true;
9132 :
9133 7 : if (OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c)
9134 7 : || OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c))
9135 : {
9136 0 : error_at (OMP_CLAUSE_LOCATION (c),
9137 : "modifiers cannot be used with predefined "
9138 : "allocators");
9139 0 : break;
9140 : }
9141 : }
9142 73 : t = OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c);
9143 73 : if (t == error_mark_node)
9144 : {
9145 : remove = true;
9146 : break;
9147 : }
9148 72 : if (t != NULL_TREE
9149 16 : && !type_dependent_expression_p (t)
9150 88 : && ((TREE_CODE (t) != CONST_DECL && TREE_CODE (t) != INTEGER_CST)
9151 15 : || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9152 28 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9153 : "omp_memspace_handle_t") != 0))
9154 : {
9155 2 : error_at (OMP_CLAUSE_LOCATION (c), "memspace modifier %qE must be"
9156 : " constant enum of %<omp_memspace_handle_t%> type", t);
9157 2 : remove = true;
9158 2 : break;
9159 : }
9160 70 : t = OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c);
9161 70 : if (t == error_mark_node)
9162 : {
9163 : remove = true;
9164 : break;
9165 : }
9166 69 : if (type_dependent_expression_p (t))
9167 : break;
9168 69 : if (t != NULL_TREE
9169 41 : && t != error_mark_node
9170 41 : && !type_dependent_expression_p (t)
9171 110 : && (!DECL_P (t)
9172 41 : || DECL_EXTERNAL (t)
9173 39 : || TREE_CODE (t) == PARM_DECL))
9174 : {
9175 4 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must be "
9176 : "defined in same scope as the construct on which the "
9177 : "clause appears", t);
9178 4 : remove = true;
9179 : }
9180 69 : if (t != NULL_TREE)
9181 : {
9182 41 : bool type_err = false;
9183 :
9184 41 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
9185 39 : || DECL_SIZE (t) == NULL_TREE
9186 79 : || !COMPLETE_TYPE_P (TREE_TYPE (t)))
9187 : type_err = true;
9188 : else
9189 : {
9190 38 : tree elem_t = TREE_TYPE (TREE_TYPE (t));
9191 38 : if (TREE_CODE (elem_t) != RECORD_TYPE
9192 76 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (elem_t)),
9193 : "omp_alloctrait_t") != 0
9194 76 : || !TYPE_READONLY (elem_t))
9195 : type_err = true;
9196 : }
9197 37 : if (type_err)
9198 : {
9199 4 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must "
9200 : "be of %<const omp_alloctrait_t []%> type", t);
9201 4 : remove = true;
9202 : }
9203 37 : else if (TREE_CODE (array_type_nelts_top (TREE_TYPE (t)))
9204 : != INTEGER_CST)
9205 : {
9206 1 : error_at (OMP_CLAUSE_LOCATION (c), "variable length traits "
9207 : "arrays are not supported");
9208 1 : remove = true;
9209 : }
9210 : else
9211 : {
9212 36 : tree cst_val = decl_constant_value (t);
9213 36 : if (cst_val == t)
9214 : {
9215 1 : error_at (OMP_CLAUSE_LOCATION (c), "traits array must be "
9216 : "initialized with constants");
9217 1 : remove = true;
9218 : }
9219 : }
9220 : }
9221 69 : if (remove)
9222 : break;
9223 55 : pc = &OMP_CLAUSE_CHAIN (c);
9224 55 : continue;
9225 1807 : case OMP_CLAUSE_DEPEND:
9226 1807 : depend_clause = c;
9227 : /* FALLTHRU */
9228 2173 : case OMP_CLAUSE_AFFINITY:
9229 2173 : t = OMP_CLAUSE_DECL (c);
9230 2173 : if (OMP_ITERATOR_DECL_P (t))
9231 : {
9232 623 : if (TREE_PURPOSE (t) != last_iterators)
9233 525 : last_iterators_remove
9234 525 : = cp_omp_finish_iterators (TREE_PURPOSE (t));
9235 623 : last_iterators = TREE_PURPOSE (t);
9236 623 : t = TREE_VALUE (t);
9237 623 : if (last_iterators_remove)
9238 144 : t = error_mark_node;
9239 : }
9240 : else
9241 : last_iterators = NULL_TREE;
9242 :
9243 2173 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9244 : {
9245 1165 : if (handle_omp_array_sections (c, ort))
9246 : remove = true;
9247 914 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9248 914 : && (OMP_CLAUSE_DEPEND_KIND (c)
9249 : == OMP_CLAUSE_DEPEND_DEPOBJ))
9250 : {
9251 6 : error_at (OMP_CLAUSE_LOCATION (c),
9252 : "%<depend%> clause with %<depobj%> dependence "
9253 : "type on array section");
9254 6 : remove = true;
9255 : }
9256 : break;
9257 : }
9258 1008 : if (t == error_mark_node)
9259 : remove = true;
9260 846 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9261 846 : && t == ridpointers[RID_OMP_ALL_MEMORY])
9262 : {
9263 33 : if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_OUT
9264 33 : && OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_INOUT)
9265 : {
9266 9 : error_at (OMP_CLAUSE_LOCATION (c),
9267 : "%<omp_all_memory%> used with %<depend%> kind "
9268 : "other than %<out%> or %<inout%>");
9269 9 : remove = true;
9270 : }
9271 33 : if (processing_template_decl)
9272 : break;
9273 : }
9274 813 : else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9275 : break;
9276 621 : else if (!lvalue_p (t))
9277 : {
9278 19 : if (DECL_P (t))
9279 24 : error_at (OMP_CLAUSE_LOCATION (c),
9280 : "%qD is not lvalue expression nor array section "
9281 : "in %qs clause", t,
9282 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9283 : else
9284 14 : error_at (OMP_CLAUSE_LOCATION (c),
9285 : "%qE is not lvalue expression nor array section "
9286 : "in %qs clause", t,
9287 7 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9288 : remove = true;
9289 : }
9290 602 : else if (TREE_CODE (t) == COMPONENT_REF
9291 24 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
9292 626 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
9293 : {
9294 8 : error_at (OMP_CLAUSE_LOCATION (c),
9295 : "bit-field %qE in %qs clause", t,
9296 4 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9297 4 : remove = true;
9298 : }
9299 598 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9300 598 : && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ)
9301 : {
9302 130 : if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9303 8 : ? TREE_TYPE (TREE_TYPE (t))
9304 57 : : TREE_TYPE (t)))
9305 : {
9306 12 : error_at (OMP_CLAUSE_LOCATION (c),
9307 : "%qE does not have %<omp_depend_t%> type in "
9308 : "%<depend%> clause with %<depobj%> dependence "
9309 : "type", t);
9310 12 : remove = true;
9311 : }
9312 : }
9313 533 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9314 974 : && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9315 4 : ? TREE_TYPE (TREE_TYPE (t))
9316 437 : : TREE_TYPE (t)))
9317 : {
9318 15 : error_at (OMP_CLAUSE_LOCATION (c),
9319 : "%qE should not have %<omp_depend_t%> type in "
9320 : "%<depend%> clause with dependence type other than "
9321 : "%<depobj%>", t);
9322 15 : remove = true;
9323 : }
9324 64 : if (!remove)
9325 : {
9326 595 : if (t == ridpointers[RID_OMP_ALL_MEMORY])
9327 24 : t = null_pointer_node;
9328 : else
9329 : {
9330 571 : tree addr = cp_build_addr_expr (t, tf_warning_or_error);
9331 571 : if (addr == error_mark_node)
9332 : {
9333 : remove = true;
9334 : break;
9335 : }
9336 571 : t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c),
9337 : addr, RO_UNARY_STAR,
9338 : tf_warning_or_error);
9339 571 : if (t == error_mark_node)
9340 : {
9341 : remove = true;
9342 : break;
9343 : }
9344 : }
9345 595 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST
9346 137 : && TREE_PURPOSE (OMP_CLAUSE_DECL (c))
9347 732 : && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c)))
9348 : == TREE_VEC))
9349 137 : TREE_VALUE (OMP_CLAUSE_DECL (c)) = t;
9350 : else
9351 458 : OMP_CLAUSE_DECL (c) = t;
9352 : }
9353 : break;
9354 69 : case OMP_CLAUSE_DETACH:
9355 69 : t = OMP_CLAUSE_DECL (c);
9356 69 : if (detach_seen)
9357 : {
9358 3 : error_at (OMP_CLAUSE_LOCATION (c),
9359 : "too many %qs clauses on a task construct",
9360 : "detach");
9361 3 : remove = true;
9362 3 : break;
9363 : }
9364 66 : else if (error_operand_p (t))
9365 : {
9366 : remove = true;
9367 : break;
9368 : }
9369 : else
9370 : {
9371 63 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
9372 63 : if (!type_dependent_expression_p (t)
9373 63 : && (!INTEGRAL_TYPE_P (type)
9374 : || TREE_CODE (type) != ENUMERAL_TYPE
9375 51 : || TYPE_NAME (type) == NULL_TREE
9376 102 : || (DECL_NAME (TYPE_NAME (type))
9377 51 : != get_identifier ("omp_event_handle_t"))))
9378 : {
9379 6 : error_at (OMP_CLAUSE_LOCATION (c),
9380 : "%<detach%> clause event handle "
9381 : "has type %qT rather than "
9382 : "%<omp_event_handle_t%>",
9383 : type);
9384 6 : remove = true;
9385 : }
9386 63 : detach_seen = c;
9387 63 : cxx_mark_addressable (t);
9388 : }
9389 63 : break;
9390 :
9391 16207 : case OMP_CLAUSE_MAP:
9392 16207 : if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved)
9393 157 : goto move_implicit;
9394 16050 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME
9395 16050 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POP_MAPPER_NAME)
9396 : {
9397 : remove = true;
9398 : break;
9399 : }
9400 : /* FALLTHRU */
9401 19228 : case OMP_CLAUSE_TO:
9402 19228 : case OMP_CLAUSE_FROM:
9403 19228 : if (OMP_CLAUSE_ITERATORS (c)
9404 19228 : && cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
9405 : {
9406 97570 : t = error_mark_node;
9407 : break;
9408 : }
9409 : /* FALLTHRU */
9410 20064 : case OMP_CLAUSE__CACHE_:
9411 20064 : {
9412 20064 : using namespace omp_addr_tokenizer;
9413 20064 : auto_vec<omp_addr_token *, 10> addr_tokens;
9414 :
9415 20064 : t = OMP_CLAUSE_DECL (c);
9416 20064 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9417 : {
9418 5879 : grp_start_p = pc;
9419 5879 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9420 :
9421 5879 : if (handle_omp_array_sections (c, ort))
9422 : remove = true;
9423 : else
9424 : {
9425 5113 : t = OMP_CLAUSE_DECL (c);
9426 5113 : if (TREE_CODE (t) != OMP_ARRAY_SECTION
9427 4256 : && !type_dependent_expression_p (t)
9428 9369 : && !omp_mappable_type (TREE_TYPE (t)))
9429 : {
9430 3 : auto_diagnostic_group d;
9431 6 : error_at (OMP_CLAUSE_LOCATION (c),
9432 : "array section does not have mappable type "
9433 : "in %qs clause",
9434 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9435 3 : if (TREE_TYPE (t) != error_mark_node
9436 3 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9437 3 : cxx_incomplete_type_inform (TREE_TYPE (t));
9438 3 : remove = true;
9439 3 : }
9440 6963 : while (TREE_CODE (t) == ARRAY_REF)
9441 1850 : t = TREE_OPERAND (t, 0);
9442 :
9443 5113 : if (type_dependent_expression_p (t))
9444 : break;
9445 :
9446 4639 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9447 :
9448 4639 : if (!ai.map_supported_p ()
9449 4639 : || !omp_parse_expr (addr_tokens, t))
9450 : {
9451 18 : sorry_at (OMP_CLAUSE_LOCATION (c),
9452 : "unsupported map expression %qE",
9453 9 : OMP_CLAUSE_DECL (c));
9454 9 : remove = true;
9455 9 : break;
9456 : }
9457 :
9458 : /* This check is to determine if this will be the only map
9459 : node created for this clause. Otherwise, we'll check
9460 : the following FIRSTPRIVATE_POINTER,
9461 : FIRSTPRIVATE_REFERENCE or ATTACH_DETACH node on the next
9462 : iteration(s) of the loop. */
9463 9211 : if (addr_tokens.length () >= 4
9464 1063 : && addr_tokens[0]->type == STRUCTURE_BASE
9465 1057 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
9466 1057 : && addr_tokens[1]->type == ACCESS_METHOD
9467 1057 : && addr_tokens[2]->type == COMPONENT_SELECTOR
9468 977 : && addr_tokens[3]->type == ACCESS_METHOD
9469 5344 : && (addr_tokens[3]->u.access_kind == ACCESS_DIRECT
9470 551 : || (addr_tokens[3]->u.access_kind
9471 : == ACCESS_INDEXED_ARRAY)))
9472 : {
9473 165 : tree rt = addr_tokens[1]->expr;
9474 :
9475 165 : gcc_assert (DECL_P (rt));
9476 :
9477 165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9478 154 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9479 165 : && (bitmap_bit_p (&map_head, DECL_UID (rt))
9480 0 : || bitmap_bit_p (&map_field_head, DECL_UID (rt))
9481 0 : || bitmap_bit_p (&map_firstprivate_head,
9482 0 : DECL_UID (rt))))
9483 : {
9484 : remove = true;
9485 : break;
9486 : }
9487 165 : if (bitmap_bit_p (&map_field_head, DECL_UID (rt)))
9488 : break;
9489 116 : if (bitmap_bit_p (&map_head, DECL_UID (rt)))
9490 : {
9491 0 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9492 0 : error_at (OMP_CLAUSE_LOCATION (c),
9493 : "%qD appears more than once in motion"
9494 : " clauses", rt);
9495 0 : else if (openacc)
9496 0 : error_at (OMP_CLAUSE_LOCATION (c),
9497 : "%qD appears more than once in data"
9498 : " clauses", rt);
9499 : else
9500 0 : error_at (OMP_CLAUSE_LOCATION (c),
9501 : "%qD appears more than once in map"
9502 : " clauses", rt);
9503 : remove = true;
9504 : }
9505 : else
9506 : {
9507 116 : bitmap_set_bit (&map_head, DECL_UID (rt));
9508 116 : bitmap_set_bit (&map_field_head, DECL_UID (rt));
9509 : }
9510 : }
9511 4639 : }
9512 5347 : if (cp_oacc_check_attachments (c))
9513 12 : remove = true;
9514 5347 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9515 4413 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9516 4349 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9517 5445 : && !OMP_CLAUSE_SIZE (c))
9518 : /* In this case, we have a single array element which is a
9519 : pointer, and we already set OMP_CLAUSE_SIZE in
9520 : handle_omp_array_sections above. For attach/detach
9521 : clauses, reset the OMP_CLAUSE_SIZE (representing a bias)
9522 : to zero here. */
9523 60 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9524 : break;
9525 : }
9526 14185 : else if (type_dependent_expression_p (t))
9527 : break;
9528 13402 : else if (!omp_parse_expr (addr_tokens, t))
9529 : {
9530 0 : sorry_at (OMP_CLAUSE_LOCATION (c),
9531 : "unsupported map expression %qE",
9532 0 : OMP_CLAUSE_DECL (c));
9533 0 : remove = true;
9534 0 : break;
9535 : }
9536 13402 : if (t == error_mark_node)
9537 : {
9538 : remove = true;
9539 : break;
9540 : }
9541 : /* OpenACC attach / detach clauses must be pointers. */
9542 13308 : if (cp_oacc_check_attachments (c))
9543 : {
9544 : remove = true;
9545 : break;
9546 : }
9547 13284 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9548 10239 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9549 10190 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9550 13358 : && !OMP_CLAUSE_SIZE (c))
9551 : /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a
9552 : bias) to zero here, so it is not set erroneously to the
9553 : pointer size later on in gimplify.cc. */
9554 66 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9555 :
9556 13284 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9557 :
9558 13284 : if (!ai.check_clause (c))
9559 : {
9560 : remove = true;
9561 : break;
9562 : }
9563 :
9564 13263 : if (!ai.map_supported_p ())
9565 : {
9566 88 : sorry_at (OMP_CLAUSE_LOCATION (c),
9567 : "unsupported map expression %qE",
9568 44 : OMP_CLAUSE_DECL (c));
9569 44 : remove = true;
9570 44 : break;
9571 : }
9572 :
9573 26438 : gcc_assert ((addr_tokens[0]->type == ARRAY_BASE
9574 : || addr_tokens[0]->type == STRUCTURE_BASE)
9575 : && addr_tokens[1]->type == ACCESS_METHOD);
9576 :
9577 13219 : t = addr_tokens[1]->expr;
9578 :
9579 : /* This is used to prevent cxx_mark_addressable from being called
9580 : on 'this' for expressions like 'this->a', i.e. typical member
9581 : accesses. */
9582 13219 : indir_component_ref_p
9583 26438 : = (addr_tokens[0]->type == STRUCTURE_BASE
9584 13219 : && addr_tokens[1]->u.access_kind != ACCESS_DIRECT);
9585 :
9586 13219 : if (addr_tokens[0]->u.structure_base_kind != BASE_DECL)
9587 1 : goto skip_decl_checks;
9588 :
9589 : /* For OpenMP, we can access a struct "t" and "t.d" on the same
9590 : mapping. OpenACC allows multiple fields of the same structure
9591 : to be written. */
9592 13218 : if (addr_tokens[0]->type == STRUCTURE_BASE
9593 13218 : && (bitmap_bit_p (&map_field_head, DECL_UID (t))
9594 1263 : || (!openacc && bitmap_bit_p (&map_head, DECL_UID (t)))))
9595 1351 : goto skip_decl_checks;
9596 :
9597 11867 : if (!processing_template_decl && TREE_CODE (t) == FIELD_DECL)
9598 : {
9599 0 : OMP_CLAUSE_DECL (c)
9600 0 : = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
9601 0 : break;
9602 : }
9603 11867 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
9604 : {
9605 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9606 : break;
9607 0 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9608 0 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9609 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9610 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9611 0 : || (!openacc && EXPR_P (t))))
9612 : break;
9613 0 : if (DECL_P (t))
9614 0 : error_at (OMP_CLAUSE_LOCATION (c),
9615 : "%qD is not a variable in %qs clause", t,
9616 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9617 : else
9618 0 : error_at (OMP_CLAUSE_LOCATION (c),
9619 : "%qE is not a variable in %qs clause", t,
9620 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9621 : remove = true;
9622 : }
9623 11867 : else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
9624 : {
9625 0 : error_at (OMP_CLAUSE_LOCATION (c),
9626 : "%qD is threadprivate variable in %qs clause", t,
9627 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9628 0 : remove = true;
9629 : }
9630 11867 : else if (!processing_template_decl
9631 11688 : && !TYPE_REF_P (TREE_TYPE (t))
9632 11011 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9633 8076 : || (OMP_CLAUSE_MAP_KIND (c)
9634 : != GOMP_MAP_FIRSTPRIVATE_POINTER))
9635 9054 : && !indir_component_ref_p
9636 8690 : && (t != current_class_ptr
9637 18 : || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9638 6 : || OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
9639 20557 : && !cxx_mark_addressable (t))
9640 : remove = true;
9641 11867 : else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9642 8914 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9643 8914 : || (OMP_CLAUSE_MAP_KIND (c)
9644 : == GOMP_MAP_FIRSTPRIVATE_POINTER)
9645 6957 : || (OMP_CLAUSE_MAP_KIND (c)
9646 : == GOMP_MAP_ATTACH_DETACH)))
9647 9250 : && t == OMP_CLAUSE_DECL (c)
9648 8552 : && !type_dependent_expression_p (t)
9649 28971 : && !omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
9650 278 : ? TREE_TYPE (TREE_TYPE (t))
9651 8274 : : TREE_TYPE (t)))
9652 : {
9653 42 : auto_diagnostic_group d;
9654 84 : error_at (OMP_CLAUSE_LOCATION (c),
9655 : "%qD does not have a mappable type in %qs clause", t,
9656 42 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9657 42 : if (TREE_TYPE (t) != error_mark_node
9658 42 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9659 39 : cxx_incomplete_type_inform (TREE_TYPE (t));
9660 42 : remove = true;
9661 42 : }
9662 11825 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9663 8878 : && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR
9664 93 : && !type_dependent_expression_p (t)
9665 11918 : && !INDIRECT_TYPE_P (TREE_TYPE (t)))
9666 : {
9667 6 : error_at (OMP_CLAUSE_LOCATION (c),
9668 : "%qD is not a pointer variable", t);
9669 6 : remove = true;
9670 : }
9671 11819 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9672 8872 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9673 12189 : && (bitmap_bit_p (&map_head, DECL_UID (t))
9674 367 : || bitmap_bit_p (&map_field_head, DECL_UID (t))
9675 367 : || bitmap_bit_p (&map_firstprivate_head,
9676 367 : DECL_UID (t))))
9677 : remove = true;
9678 11813 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9679 11813 : && (OMP_CLAUSE_MAP_KIND (c)
9680 : == GOMP_MAP_FIRSTPRIVATE_POINTER))
9681 : {
9682 1951 : if (bitmap_bit_p (&generic_head, DECL_UID (t))
9683 1951 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9684 3899 : || (openacc
9685 1362 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
9686 : {
9687 12 : error_at (OMP_CLAUSE_LOCATION (c),
9688 : "%qD appears more than once in data clauses", t);
9689 12 : remove = true;
9690 : }
9691 1939 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9692 12 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9693 1947 : && openacc)
9694 : {
9695 3 : error_at (OMP_CLAUSE_LOCATION (c),
9696 : "%qD appears more than once in data clauses", t);
9697 3 : remove = true;
9698 : }
9699 : else
9700 1936 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9701 : }
9702 9862 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9703 9862 : && (OMP_CLAUSE_MAP_KIND (c)
9704 : == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9705 115 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9706 9747 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9707 181 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9708 38 : && ort != C_ORT_OMP
9709 38 : && ort != C_ORT_OMP_TARGET
9710 9763 : && ort != C_ORT_OMP_EXIT_DATA)
9711 : {
9712 9 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9713 0 : error_at (OMP_CLAUSE_LOCATION (c),
9714 : "%qD appears more than once in motion clauses", t);
9715 9 : else if (openacc)
9716 9 : error_at (OMP_CLAUSE_LOCATION (c),
9717 : "%qD appears more than once in data clauses", t);
9718 : else
9719 0 : error_at (OMP_CLAUSE_LOCATION (c),
9720 : "%qD appears more than once in map clauses", t);
9721 : remove = true;
9722 : }
9723 9738 : else if (openacc && bitmap_bit_p (&generic_head, DECL_UID (t)))
9724 : {
9725 0 : error_at (OMP_CLAUSE_LOCATION (c),
9726 : "%qD appears more than once in data clauses", t);
9727 0 : remove = true;
9728 : }
9729 9738 : else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9730 9738 : || bitmap_bit_p (&is_on_device_head, DECL_UID (t)))
9731 : {
9732 27 : if (openacc)
9733 0 : error_at (OMP_CLAUSE_LOCATION (c),
9734 : "%qD appears more than once in data clauses", t);
9735 : else
9736 27 : error_at (OMP_CLAUSE_LOCATION (c),
9737 : "%qD appears both in data and map clauses", t);
9738 : remove = true;
9739 : }
9740 9711 : else if (!omp_access_chain_p (addr_tokens, 1))
9741 : {
9742 9631 : bitmap_set_bit (&map_head, DECL_UID (t));
9743 :
9744 9631 : tree decl = OMP_CLAUSE_DECL (c);
9745 9631 : if (t != decl
9746 9631 : && (TREE_CODE (decl) == COMPONENT_REF
9747 162 : || (INDIRECT_REF_P (decl)
9748 162 : && (TREE_CODE (TREE_OPERAND (decl, 0))
9749 : == COMPONENT_REF)
9750 150 : && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (decl,
9751 : 0))))))
9752 1165 : bitmap_set_bit (&map_field_head, DECL_UID (t));
9753 : }
9754 :
9755 4631 : skip_decl_checks:
9756 : /* If we call ai.expand_map_clause in handle_omp_array_sections,
9757 : the containing loop (here) iterates through the new nodes
9758 : created by that expansion. Avoid expanding those again (just
9759 : by checking the node type). */
9760 4631 : if (!remove
9761 13114 : && !processing_template_decl
9762 12938 : && ort != C_ORT_DECLARE_SIMD
9763 12938 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9764 9911 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9765 7975 : && (OMP_CLAUSE_MAP_KIND (c)
9766 : != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9767 7860 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9768 7860 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9769 6861 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9770 6812 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)))
9771 : {
9772 9814 : grp_start_p = pc;
9773 9814 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9774 9814 : tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
9775 : addr_tokens, ort);
9776 9814 : if (nc != error_mark_node)
9777 9814 : c = nc;
9778 : }
9779 20129 : }
9780 13219 : break;
9781 :
9782 596 : case OMP_CLAUSE_ENTER:
9783 596 : case OMP_CLAUSE_LINK:
9784 596 : t = OMP_CLAUSE_DECL (c);
9785 596 : const char *cname;
9786 596 : cname = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9787 596 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER
9788 596 : && OMP_CLAUSE_ENTER_TO (c))
9789 : cname = "to";
9790 596 : if (TREE_CODE (t) == FUNCTION_DECL
9791 596 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9792 : ;
9793 379 : else if (!VAR_P (t))
9794 : {
9795 12 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9796 : {
9797 9 : if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
9798 6 : error_at (OMP_CLAUSE_LOCATION (c),
9799 : "template %qE in clause %qs", t, cname);
9800 3 : else if (really_overloaded_fn (t))
9801 3 : error_at (OMP_CLAUSE_LOCATION (c),
9802 : "overloaded function name %qE in clause %qs", t,
9803 : cname);
9804 : else
9805 0 : error_at (OMP_CLAUSE_LOCATION (c),
9806 : "%qE is neither a variable nor a function name "
9807 : "in clause %qs", t, cname);
9808 : }
9809 : else
9810 3 : error_at (OMP_CLAUSE_LOCATION (c),
9811 : "%qE is not a variable in clause %qs", t, cname);
9812 : remove = true;
9813 : }
9814 367 : else if (DECL_THREAD_LOCAL_P (t))
9815 : {
9816 6 : error_at (OMP_CLAUSE_LOCATION (c),
9817 : "%qD is threadprivate variable in %qs clause", t,
9818 : cname);
9819 6 : remove = true;
9820 : }
9821 361 : else if (!omp_mappable_type (TREE_TYPE (t)))
9822 : {
9823 18 : auto_diagnostic_group d;
9824 18 : error_at (OMP_CLAUSE_LOCATION (c),
9825 : "%qD does not have a mappable type in %qs clause", t,
9826 : cname);
9827 18 : if (TREE_TYPE (t) != error_mark_node
9828 18 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9829 18 : cxx_incomplete_type_inform (TREE_TYPE (t));
9830 18 : remove = true;
9831 18 : }
9832 24 : if (remove)
9833 : break;
9834 560 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
9835 : {
9836 24 : error_at (OMP_CLAUSE_LOCATION (c),
9837 : "%qE appears more than once on the same "
9838 : "%<declare target%> directive", t);
9839 24 : remove = true;
9840 : }
9841 : else
9842 536 : bitmap_set_bit (&generic_head, DECL_UID (t));
9843 : break;
9844 :
9845 457 : case OMP_CLAUSE_UNIFORM:
9846 457 : t = OMP_CLAUSE_DECL (c);
9847 457 : if (TREE_CODE (t) != PARM_DECL)
9848 : {
9849 0 : if (processing_template_decl)
9850 : break;
9851 0 : if (DECL_P (t))
9852 0 : error_at (OMP_CLAUSE_LOCATION (c),
9853 : "%qD is not an argument in %<uniform%> clause", t);
9854 : else
9855 0 : error_at (OMP_CLAUSE_LOCATION (c),
9856 : "%qE is not an argument in %<uniform%> clause", t);
9857 : remove = true;
9858 : break;
9859 : }
9860 : /* map_head bitmap is used as uniform_head if declare_simd. */
9861 457 : bitmap_set_bit (&map_head, DECL_UID (t));
9862 457 : goto check_dup_generic;
9863 :
9864 165 : case OMP_CLAUSE_GRAINSIZE:
9865 165 : t = OMP_CLAUSE_GRAINSIZE_EXPR (c);
9866 165 : if (t == error_mark_node)
9867 : remove = true;
9868 165 : else if (!type_dependent_expression_p (t)
9869 165 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9870 : {
9871 0 : error_at (OMP_CLAUSE_LOCATION (c),
9872 : "%<grainsize%> expression must be integral");
9873 0 : remove = true;
9874 : }
9875 : else
9876 : {
9877 165 : t = mark_rvalue_use (t);
9878 165 : if (!processing_template_decl)
9879 : {
9880 164 : t = maybe_constant_value (t);
9881 164 : if (TREE_CODE (t) == INTEGER_CST
9882 164 : && tree_int_cst_sgn (t) != 1)
9883 : {
9884 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9885 : "%<grainsize%> value must be positive");
9886 0 : t = integer_one_node;
9887 : }
9888 164 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9889 : }
9890 165 : OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
9891 : }
9892 : break;
9893 :
9894 276 : case OMP_CLAUSE_PRIORITY:
9895 276 : t = OMP_CLAUSE_PRIORITY_EXPR (c);
9896 276 : if (t == error_mark_node)
9897 : remove = true;
9898 276 : else if (!type_dependent_expression_p (t)
9899 276 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9900 : {
9901 0 : error_at (OMP_CLAUSE_LOCATION (c),
9902 : "%<priority%> expression must be integral");
9903 0 : remove = true;
9904 : }
9905 : else
9906 : {
9907 276 : t = mark_rvalue_use (t);
9908 276 : if (!processing_template_decl)
9909 : {
9910 276 : t = maybe_constant_value (t);
9911 276 : if (TREE_CODE (t) == INTEGER_CST
9912 276 : && tree_int_cst_sgn (t) == -1)
9913 : {
9914 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9915 : "%<priority%> value must be non-negative");
9916 0 : t = integer_one_node;
9917 : }
9918 276 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9919 : }
9920 276 : OMP_CLAUSE_PRIORITY_EXPR (c) = t;
9921 : }
9922 : break;
9923 :
9924 228 : case OMP_CLAUSE_HINT:
9925 228 : t = OMP_CLAUSE_HINT_EXPR (c);
9926 228 : if (t == error_mark_node)
9927 : remove = true;
9928 228 : else if (!type_dependent_expression_p (t)
9929 228 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9930 : {
9931 9 : error_at (OMP_CLAUSE_LOCATION (c),
9932 : "%<hint%> expression must be integral");
9933 9 : remove = true;
9934 : }
9935 : else
9936 : {
9937 219 : t = mark_rvalue_use (t);
9938 219 : if (!processing_template_decl)
9939 : {
9940 171 : t = maybe_constant_value (t);
9941 171 : if (TREE_CODE (t) != INTEGER_CST)
9942 : {
9943 16 : error_at (OMP_CLAUSE_LOCATION (c),
9944 : "%<hint%> expression must be constant integer "
9945 : "expression");
9946 16 : remove = true;
9947 : }
9948 : }
9949 219 : OMP_CLAUSE_HINT_EXPR (c) = t;
9950 : }
9951 : break;
9952 :
9953 186 : case OMP_CLAUSE_FILTER:
9954 186 : t = OMP_CLAUSE_FILTER_EXPR (c);
9955 186 : if (t == error_mark_node)
9956 : remove = true;
9957 186 : else if (!type_dependent_expression_p (t)
9958 186 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9959 : {
9960 6 : error_at (OMP_CLAUSE_LOCATION (c),
9961 : "%<filter%> expression must be integral");
9962 6 : remove = true;
9963 : }
9964 : else
9965 : {
9966 180 : t = mark_rvalue_use (t);
9967 180 : if (!processing_template_decl)
9968 : {
9969 177 : t = maybe_constant_value (t);
9970 177 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9971 : }
9972 180 : OMP_CLAUSE_FILTER_EXPR (c) = t;
9973 : }
9974 : break;
9975 :
9976 433 : case OMP_CLAUSE_IS_DEVICE_PTR:
9977 433 : case OMP_CLAUSE_USE_DEVICE_PTR:
9978 433 : field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
9979 433 : t = OMP_CLAUSE_DECL (c);
9980 433 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
9981 329 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
9982 433 : if (!type_dependent_expression_p (t))
9983 : {
9984 431 : tree type = TREE_TYPE (t);
9985 431 : if (!TYPE_PTR_P (type)
9986 431 : && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
9987 : {
9988 57 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
9989 57 : && ort == C_ORT_OMP)
9990 : {
9991 3 : error_at (OMP_CLAUSE_LOCATION (c),
9992 : "%qs variable is neither a pointer "
9993 : "nor reference to pointer",
9994 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9995 3 : remove = true;
9996 : }
9997 54 : else if (TREE_CODE (type) != ARRAY_TYPE
9998 54 : && (!TYPE_REF_P (type)
9999 2 : || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
10000 : {
10001 12 : error_at (OMP_CLAUSE_LOCATION (c),
10002 : "%qs variable is neither a pointer, nor an "
10003 : "array nor reference to pointer or array",
10004 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10005 12 : remove = true;
10006 : }
10007 : }
10008 : }
10009 433 : goto check_dup_generic;
10010 :
10011 267 : case OMP_CLAUSE_HAS_DEVICE_ADDR:
10012 267 : t = OMP_CLAUSE_DECL (c);
10013 267 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10014 : {
10015 28 : if (handle_omp_array_sections (c, ort))
10016 : remove = true;
10017 : else
10018 : {
10019 28 : t = OMP_CLAUSE_DECL (c);
10020 30 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10021 2 : t = TREE_OPERAND (t, 0);
10022 64 : while (INDIRECT_REF_P (t)
10023 64 : || TREE_CODE (t) == ARRAY_REF)
10024 36 : t = TREE_OPERAND (t, 0);
10025 : }
10026 : }
10027 267 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
10028 : {
10029 267 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
10030 267 : if (!processing_template_decl
10031 267 : && !cxx_mark_addressable (t))
10032 : remove = true;
10033 : }
10034 267 : goto check_dup_generic_t;
10035 :
10036 76 : case OMP_CLAUSE_USE_DEVICE_ADDR:
10037 76 : field_ok = true;
10038 76 : t = OMP_CLAUSE_DECL (c);
10039 76 : if (!processing_template_decl
10040 74 : && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
10041 74 : && !TYPE_REF_P (TREE_TYPE (t))
10042 143 : && !cxx_mark_addressable (t))
10043 : remove = true;
10044 76 : goto check_dup_generic;
10045 :
10046 : case OMP_CLAUSE_NOWAIT:
10047 : case OMP_CLAUSE_DEFAULT:
10048 : case OMP_CLAUSE_UNTIED:
10049 : case OMP_CLAUSE_COLLAPSE:
10050 : case OMP_CLAUSE_PARALLEL:
10051 : case OMP_CLAUSE_FOR:
10052 : case OMP_CLAUSE_SECTIONS:
10053 : case OMP_CLAUSE_TASKGROUP:
10054 : case OMP_CLAUSE_PROC_BIND:
10055 : case OMP_CLAUSE_DEVICE_TYPE:
10056 : case OMP_CLAUSE_NOGROUP:
10057 : case OMP_CLAUSE_THREADS:
10058 : case OMP_CLAUSE_SIMD:
10059 : case OMP_CLAUSE_DEFAULTMAP:
10060 : case OMP_CLAUSE_BIND:
10061 : case OMP_CLAUSE_AUTO:
10062 : case OMP_CLAUSE_INDEPENDENT:
10063 : case OMP_CLAUSE_SEQ:
10064 : case OMP_CLAUSE_IF_PRESENT:
10065 : case OMP_CLAUSE_FINALIZE:
10066 : case OMP_CLAUSE_NOHOST:
10067 : case OMP_CLAUSE_INDIRECT:
10068 : break;
10069 :
10070 231 : case OMP_CLAUSE_MERGEABLE:
10071 231 : mergeable_seen = true;
10072 231 : break;
10073 :
10074 322 : case OMP_CLAUSE_TILE:
10075 754 : for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
10076 432 : list = TREE_CHAIN (list))
10077 : {
10078 432 : t = TREE_VALUE (list);
10079 :
10080 432 : if (t == error_mark_node)
10081 : remove = true;
10082 403 : else if (!type_dependent_expression_p (t)
10083 403 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10084 : {
10085 3 : error_at (OMP_CLAUSE_LOCATION (c),
10086 : "%<tile%> argument needs integral type");
10087 3 : remove = true;
10088 : }
10089 : else
10090 : {
10091 400 : t = mark_rvalue_use (t);
10092 400 : if (!processing_template_decl)
10093 : {
10094 : /* Zero is used to indicate '*', we permit you
10095 : to get there via an ICE of value zero. */
10096 385 : t = maybe_constant_value (t);
10097 385 : if (!tree_fits_shwi_p (t)
10098 369 : || tree_to_shwi (t) < 0)
10099 : {
10100 40 : error_at (OMP_CLAUSE_LOCATION (c),
10101 : "%<tile%> argument needs positive "
10102 : "integral constant");
10103 40 : remove = true;
10104 : }
10105 : }
10106 : }
10107 :
10108 : /* Update list item. */
10109 432 : TREE_VALUE (list) = t;
10110 : }
10111 : break;
10112 :
10113 1027 : case OMP_CLAUSE_SIZES:
10114 1027 : for (tree list = OMP_CLAUSE_SIZES_LIST (c);
10115 2688 : !remove && list; list = TREE_CHAIN (list))
10116 : {
10117 1661 : t = TREE_VALUE (list);
10118 :
10119 1661 : if (t == error_mark_node)
10120 0 : t = integer_one_node;
10121 1661 : else if (!type_dependent_expression_p (t)
10122 1661 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10123 : {
10124 8 : error_at (OMP_CLAUSE_LOCATION (c),
10125 : "%<sizes%> argument needs positive integral "
10126 : "constant");
10127 8 : t = integer_one_node;
10128 : }
10129 : else
10130 : {
10131 1653 : t = mark_rvalue_use (t);
10132 1653 : if (!processing_template_decl)
10133 : {
10134 1636 : t = maybe_constant_value (t);
10135 1636 : HOST_WIDE_INT n;
10136 1636 : if (!tree_fits_shwi_p (t)
10137 1632 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
10138 1632 : || (n = tree_to_shwi (t)) <= 0
10139 3240 : || (int)n != n)
10140 : {
10141 32 : error_at (OMP_CLAUSE_LOCATION (c),
10142 : "%<sizes%> argument needs positive "
10143 : "integral constant");
10144 32 : t = integer_one_node;
10145 : }
10146 : }
10147 : }
10148 :
10149 : /* Update list item. */
10150 1661 : TREE_VALUE (list) = t;
10151 : }
10152 : break;
10153 :
10154 630 : case OMP_CLAUSE_ORDERED:
10155 630 : ordered_seen = true;
10156 630 : break;
10157 :
10158 1549 : case OMP_CLAUSE_ORDER:
10159 1549 : if (order_seen)
10160 : remove = true;
10161 : else
10162 : order_seen = true;
10163 : break;
10164 :
10165 638 : case OMP_CLAUSE_INBRANCH:
10166 638 : case OMP_CLAUSE_NOTINBRANCH:
10167 638 : if (branch_seen)
10168 : {
10169 3 : error_at (OMP_CLAUSE_LOCATION (c),
10170 : "%<inbranch%> clause is incompatible with "
10171 : "%<notinbranch%>");
10172 3 : remove = true;
10173 : }
10174 : branch_seen = true;
10175 : break;
10176 :
10177 300 : case OMP_CLAUSE_INCLUSIVE:
10178 300 : case OMP_CLAUSE_EXCLUSIVE:
10179 300 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10180 300 : if (!t)
10181 300 : t = OMP_CLAUSE_DECL (c);
10182 300 : if (t == current_class_ptr)
10183 : {
10184 0 : error_at (OMP_CLAUSE_LOCATION (c),
10185 : "%<this%> allowed in OpenMP only in %<declare simd%>"
10186 : " clauses");
10187 0 : remove = true;
10188 0 : break;
10189 : }
10190 300 : if (!VAR_P (t)
10191 : && TREE_CODE (t) != PARM_DECL
10192 : && TREE_CODE (t) != FIELD_DECL)
10193 : {
10194 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
10195 : break;
10196 0 : if (DECL_P (t))
10197 0 : error_at (OMP_CLAUSE_LOCATION (c),
10198 : "%qD is not a variable in clause %qs", t,
10199 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10200 : else
10201 0 : error_at (OMP_CLAUSE_LOCATION (c),
10202 : "%qE is not a variable in clause %qs", t,
10203 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10204 : remove = true;
10205 : }
10206 : break;
10207 :
10208 : case OMP_CLAUSE_FULL:
10209 : break;
10210 :
10211 470 : case OMP_CLAUSE_PARTIAL:
10212 470 : partial_seen = true;
10213 470 : t = OMP_CLAUSE_PARTIAL_EXPR (c);
10214 470 : if (!t)
10215 : break;
10216 :
10217 313 : if (t == error_mark_node)
10218 : t = NULL_TREE;
10219 313 : else if (!type_dependent_expression_p (t)
10220 313 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10221 : {
10222 3 : error_at (OMP_CLAUSE_LOCATION (c),
10223 : "%<partial%> argument needs positive constant "
10224 : "integer expression");
10225 3 : t = NULL_TREE;
10226 : }
10227 : else
10228 : {
10229 310 : t = mark_rvalue_use (t);
10230 310 : if (!processing_template_decl)
10231 : {
10232 292 : t = maybe_constant_value (t);
10233 :
10234 292 : HOST_WIDE_INT n;
10235 584 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
10236 292 : || !tree_fits_shwi_p (t)
10237 286 : || (n = tree_to_shwi (t)) <= 0
10238 560 : || (int)n != n)
10239 : {
10240 24 : error_at (OMP_CLAUSE_LOCATION (c),
10241 : "%<partial%> argument needs positive "
10242 : "constant integer expression");
10243 24 : t = NULL_TREE;
10244 : }
10245 : }
10246 : }
10247 :
10248 313 : OMP_CLAUSE_PARTIAL_EXPR (c) = t;
10249 313 : break;
10250 549 : case OMP_CLAUSE_INIT:
10251 549 : init_seen = true;
10252 549 : OMP_CLAUSE_INIT_PREFER_TYPE (c)
10253 549 : = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c));
10254 549 : if (!OMP_CLAUSE_INIT_TARGETSYNC (c))
10255 271 : init_no_targetsync_clause = c;
10256 : /* FALLTHRU */
10257 844 : case OMP_CLAUSE_DESTROY:
10258 844 : case OMP_CLAUSE_USE:
10259 844 : init_use_destroy_seen = true;
10260 844 : t = OMP_CLAUSE_DECL (c);
10261 844 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
10262 : {
10263 9 : error_at (OMP_CLAUSE_LOCATION (c),
10264 : "%qD appears more than once in action clauses", t);
10265 9 : remove = true;
10266 9 : break;
10267 : }
10268 835 : bitmap_set_bit (&generic_head, DECL_UID (t));
10269 : /* FALLTHRU */
10270 1099 : case OMP_CLAUSE_INTEROP:
10271 1099 : if (!processing_template_decl)
10272 : {
10273 1003 : if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
10274 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) && */
10275 1003 : !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
10276 : {
10277 126 : error_at (OMP_CLAUSE_LOCATION (c),
10278 : "%qD must be of %<omp_interop_t%>",
10279 63 : OMP_CLAUSE_DECL (c));
10280 63 : remove = true;
10281 : }
10282 940 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
10283 481 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
10284 1058 : && TREE_READONLY (OMP_CLAUSE_DECL (c)))
10285 : {
10286 36 : error_at (OMP_CLAUSE_LOCATION (c),
10287 18 : "%qD shall not be const", OMP_CLAUSE_DECL (c));
10288 18 : remove = true;
10289 : }
10290 : }
10291 1099 : pc = &OMP_CLAUSE_CHAIN (c);
10292 1099 : break;
10293 0 : default:
10294 0 : gcc_unreachable ();
10295 55 : }
10296 :
10297 97570 : if (remove)
10298 : {
10299 2535 : if (grp_start_p)
10300 : {
10301 : /* If we found a clause to remove, we want to remove the whole
10302 : expanded group, otherwise gimplify
10303 : (omp_resolve_clause_dependencies) can get confused. */
10304 817 : *grp_start_p = grp_sentinel;
10305 817 : pc = grp_start_p;
10306 817 : grp_start_p = NULL;
10307 : }
10308 : else
10309 1718 : *pc = OMP_CLAUSE_CHAIN (c);
10310 : }
10311 : else
10312 95035 : pc = &OMP_CLAUSE_CHAIN (c);
10313 : }
10314 :
10315 62789 : if (grp_start_p
10316 62789 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
10317 140 : for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc))
10318 86 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
10319 :
10320 62789 : if (reduction_seen < 0 && (ordered_seen || schedule_seen))
10321 62789 : reduction_seen = -2;
10322 :
10323 158789 : for (pc = &clauses, c = clauses; c ; c = *pc)
10324 : {
10325 96000 : enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
10326 96000 : bool remove = false;
10327 96000 : bool need_complete_type = false;
10328 96000 : bool need_default_ctor = false;
10329 96000 : bool need_copy_ctor = false;
10330 96000 : bool need_copy_assignment = false;
10331 96000 : bool need_implicitly_determined = false;
10332 96000 : bool need_dtor = false;
10333 96000 : tree type, inner_type;
10334 :
10335 96000 : switch (c_kind)
10336 : {
10337 : case OMP_CLAUSE_SHARED:
10338 : need_implicitly_determined = true;
10339 : break;
10340 2550 : case OMP_CLAUSE_PRIVATE:
10341 2550 : need_complete_type = true;
10342 2550 : need_default_ctor = true;
10343 2550 : need_dtor = true;
10344 2550 : need_implicitly_determined = true;
10345 2550 : break;
10346 3163 : case OMP_CLAUSE_FIRSTPRIVATE:
10347 3163 : need_complete_type = true;
10348 3163 : need_copy_ctor = true;
10349 3163 : need_dtor = true;
10350 3163 : need_implicitly_determined = true;
10351 3163 : break;
10352 2766 : case OMP_CLAUSE_LASTPRIVATE:
10353 2766 : need_complete_type = true;
10354 2766 : need_copy_assignment = true;
10355 2766 : need_implicitly_determined = true;
10356 2766 : break;
10357 7335 : case OMP_CLAUSE_REDUCTION:
10358 7335 : if (reduction_seen == -2)
10359 27 : OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
10360 7335 : if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10361 424 : need_copy_assignment = true;
10362 : need_implicitly_determined = true;
10363 : break;
10364 : case OMP_CLAUSE_IN_REDUCTION:
10365 : case OMP_CLAUSE_TASK_REDUCTION:
10366 : case OMP_CLAUSE_INCLUSIVE:
10367 : case OMP_CLAUSE_EXCLUSIVE:
10368 : need_implicitly_determined = true;
10369 : break;
10370 1550 : case OMP_CLAUSE_LINEAR:
10371 1550 : if (ort != C_ORT_OMP_DECLARE_SIMD)
10372 : need_implicitly_determined = true;
10373 679 : else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
10374 721 : && !bitmap_bit_p (&map_head,
10375 42 : DECL_UID (OMP_CLAUSE_LINEAR_STEP (c))))
10376 : {
10377 6 : error_at (OMP_CLAUSE_LOCATION (c),
10378 : "%<linear%> clause step is a parameter %qD not "
10379 : "specified in %<uniform%> clause",
10380 6 : OMP_CLAUSE_LINEAR_STEP (c));
10381 6 : *pc = OMP_CLAUSE_CHAIN (c);
10382 74399 : continue;
10383 : }
10384 : break;
10385 : case OMP_CLAUSE_COPYPRIVATE:
10386 369 : need_copy_assignment = true;
10387 : break;
10388 : case OMP_CLAUSE_COPYIN:
10389 369 : need_copy_assignment = true;
10390 : break;
10391 798 : case OMP_CLAUSE_SIMDLEN:
10392 798 : if (safelen
10393 345 : && !processing_template_decl
10394 1143 : && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
10395 345 : OMP_CLAUSE_SIMDLEN_EXPR (c)))
10396 : {
10397 0 : error_at (OMP_CLAUSE_LOCATION (c),
10398 : "%<simdlen%> clause value is bigger than "
10399 : "%<safelen%> clause value");
10400 0 : OMP_CLAUSE_SIMDLEN_EXPR (c)
10401 0 : = OMP_CLAUSE_SAFELEN_EXPR (safelen);
10402 : }
10403 798 : pc = &OMP_CLAUSE_CHAIN (c);
10404 798 : continue;
10405 3877 : case OMP_CLAUSE_SCHEDULE:
10406 3877 : if (ordered_seen
10407 3877 : && (OMP_CLAUSE_SCHEDULE_KIND (c)
10408 : & OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
10409 : {
10410 21 : error_at (OMP_CLAUSE_LOCATION (c),
10411 : "%<nonmonotonic%> schedule modifier specified "
10412 : "together with %<ordered%> clause");
10413 42 : OMP_CLAUSE_SCHEDULE_KIND (c)
10414 21 : = (enum omp_clause_schedule_kind)
10415 21 : (OMP_CLAUSE_SCHEDULE_KIND (c)
10416 : & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
10417 : }
10418 3877 : if (reduction_seen == -2)
10419 9 : error_at (OMP_CLAUSE_LOCATION (c),
10420 : "%qs clause specified together with %<inscan%> "
10421 : "%<reduction%> clause", "schedule");
10422 3877 : pc = &OMP_CLAUSE_CHAIN (c);
10423 3877 : continue;
10424 51 : case OMP_CLAUSE_NOGROUP:
10425 51 : if (reduction_seen)
10426 : {
10427 3 : error_at (OMP_CLAUSE_LOCATION (c),
10428 : "%<nogroup%> clause must not be used together with "
10429 : "%<reduction%> clause");
10430 3 : *pc = OMP_CLAUSE_CHAIN (c);
10431 3 : continue;
10432 : }
10433 48 : pc = &OMP_CLAUSE_CHAIN (c);
10434 48 : continue;
10435 165 : case OMP_CLAUSE_GRAINSIZE:
10436 165 : if (num_tasks_seen)
10437 : {
10438 6 : error_at (OMP_CLAUSE_LOCATION (c),
10439 : "%<grainsize%> clause must not be used together with "
10440 : "%<num_tasks%> clause");
10441 6 : *pc = OMP_CLAUSE_CHAIN (c);
10442 6 : continue;
10443 : }
10444 159 : pc = &OMP_CLAUSE_CHAIN (c);
10445 159 : continue;
10446 630 : case OMP_CLAUSE_ORDERED:
10447 630 : if (reduction_seen == -2)
10448 6 : error_at (OMP_CLAUSE_LOCATION (c),
10449 : "%qs clause specified together with %<inscan%> "
10450 : "%<reduction%> clause", "ordered");
10451 630 : pc = &OMP_CLAUSE_CHAIN (c);
10452 630 : continue;
10453 1525 : case OMP_CLAUSE_ORDER:
10454 1525 : if (ordered_seen)
10455 : {
10456 12 : error_at (OMP_CLAUSE_LOCATION (c),
10457 : "%<order%> clause must not be used together "
10458 : "with %<ordered%> clause");
10459 12 : *pc = OMP_CLAUSE_CHAIN (c);
10460 12 : continue;
10461 : }
10462 1513 : pc = &OMP_CLAUSE_CHAIN (c);
10463 1513 : continue;
10464 57 : case OMP_CLAUSE_DETACH:
10465 57 : if (mergeable_seen)
10466 : {
10467 6 : error_at (OMP_CLAUSE_LOCATION (c),
10468 : "%<detach%> clause must not be used together with "
10469 : "%<mergeable%> clause");
10470 6 : *pc = OMP_CLAUSE_CHAIN (c);
10471 6 : continue;
10472 : }
10473 51 : pc = &OMP_CLAUSE_CHAIN (c);
10474 51 : continue;
10475 15976 : case OMP_CLAUSE_MAP:
10476 15976 : if (target_in_reduction_seen && !processing_template_decl)
10477 : {
10478 684 : t = OMP_CLAUSE_DECL (c);
10479 684 : while (handled_component_p (t)
10480 : || INDIRECT_REF_P (t)
10481 : || TREE_CODE (t) == ADDR_EXPR
10482 : || TREE_CODE (t) == MEM_REF
10483 804 : || TREE_CODE (t) == NON_LVALUE_EXPR)
10484 120 : t = TREE_OPERAND (t, 0);
10485 684 : if (DECL_P (t)
10486 684 : && bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
10487 342 : OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10488 : }
10489 15976 : pc = &OMP_CLAUSE_CHAIN (c);
10490 15976 : continue;
10491 225 : case OMP_CLAUSE_FULL:
10492 225 : if (partial_seen)
10493 : {
10494 12 : error_at (OMP_CLAUSE_LOCATION (c),
10495 : "%<full%> clause must not be used together "
10496 : "with %<partial%> clause");
10497 12 : *pc = OMP_CLAUSE_CHAIN (c);
10498 12 : continue;
10499 : }
10500 213 : pc = &OMP_CLAUSE_CHAIN (c);
10501 213 : continue;
10502 6894 : case OMP_CLAUSE_NOWAIT:
10503 6894 : if (copyprivate_seen)
10504 : {
10505 6 : error_at (OMP_CLAUSE_LOCATION (c),
10506 : "%<nowait%> clause must not be used together "
10507 : "with %<copyprivate%> clause");
10508 6 : *pc = OMP_CLAUSE_CHAIN (c);
10509 6 : continue;
10510 : }
10511 : /* FALLTHRU */
10512 50445 : default:
10513 50445 : pc = &OMP_CLAUSE_CHAIN (c);
10514 50445 : continue;
10515 : }
10516 :
10517 22239 : t = OMP_CLAUSE_DECL (c);
10518 22239 : switch (c_kind)
10519 : {
10520 2766 : case OMP_CLAUSE_LASTPRIVATE:
10521 2766 : if (DECL_P (t)
10522 2766 : && !bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
10523 : {
10524 2666 : need_default_ctor = true;
10525 2666 : need_dtor = true;
10526 : }
10527 : break;
10528 :
10529 9474 : case OMP_CLAUSE_REDUCTION:
10530 9474 : case OMP_CLAUSE_IN_REDUCTION:
10531 9474 : case OMP_CLAUSE_TASK_REDUCTION:
10532 9474 : if (allocate_seen)
10533 : {
10534 1561 : if (TREE_CODE (t) == MEM_REF)
10535 : {
10536 162 : t = TREE_OPERAND (t, 0);
10537 162 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
10538 0 : t = TREE_OPERAND (t, 0);
10539 162 : if (TREE_CODE (t) == ADDR_EXPR
10540 120 : || INDIRECT_REF_P (t))
10541 80 : t = TREE_OPERAND (t, 0);
10542 162 : if (DECL_P (t))
10543 162 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10544 : }
10545 1399 : else if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10546 : {
10547 192 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10548 96 : t = TREE_OPERAND (t, 0);
10549 96 : if (DECL_P (t))
10550 96 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10551 96 : t = OMP_CLAUSE_DECL (c);
10552 : }
10553 1303 : else if (DECL_P (t))
10554 1303 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10555 1561 : t = OMP_CLAUSE_DECL (c);
10556 : }
10557 9474 : if (processing_template_decl
10558 863 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10559 : break;
10560 8904 : if (finish_omp_reduction_clause (c, &need_default_ctor,
10561 : &need_dtor))
10562 : remove = true;
10563 : else
10564 8820 : t = OMP_CLAUSE_DECL (c);
10565 : break;
10566 :
10567 277 : case OMP_CLAUSE_COPYIN:
10568 277 : if (processing_template_decl
10569 0 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10570 : break;
10571 277 : if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t))
10572 : {
10573 15 : error_at (OMP_CLAUSE_LOCATION (c),
10574 : "%qE must be %<threadprivate%> for %<copyin%>", t);
10575 15 : remove = true;
10576 : }
10577 : break;
10578 :
10579 : default:
10580 : break;
10581 : }
10582 :
10583 22239 : if (processing_template_decl
10584 1544 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10585 : {
10586 632 : pc = &OMP_CLAUSE_CHAIN (c);
10587 632 : continue;
10588 : }
10589 :
10590 21607 : if (need_complete_type || need_copy_assignment)
10591 : {
10592 9216 : t = require_complete_type (t);
10593 9216 : if (t == error_mark_node)
10594 : remove = true;
10595 9192 : else if (!processing_template_decl
10596 8809 : && TYPE_REF_P (TREE_TYPE (t))
10597 9748 : && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
10598 : remove = true;
10599 : }
10600 21607 : if (need_implicitly_determined)
10601 : {
10602 20566 : const char *share_name = NULL;
10603 :
10604 20566 : if (allocate_seen
10605 5006 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10606 24693 : && DECL_P (t))
10607 3917 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10608 :
10609 20566 : if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
10610 : share_name = "threadprivate";
10611 20524 : else switch (cxx_omp_predetermined_sharing_1 (t))
10612 : {
10613 : case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
10614 : break;
10615 47 : case OMP_CLAUSE_DEFAULT_SHARED:
10616 47 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10617 30 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10618 64 : && c_omp_predefined_variable (t))
10619 : /* The __func__ variable and similar function-local predefined
10620 : variables may be listed in a shared or firstprivate
10621 : clause. */
10622 : break;
10623 31 : if (VAR_P (t)
10624 31 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10625 9 : && TREE_STATIC (t)
10626 40 : && cxx_omp_const_qual_no_mutable (t))
10627 : {
10628 6 : tree ctx = CP_DECL_CONTEXT (t);
10629 : /* const qualified static data members without mutable
10630 : member may be specified in firstprivate clause. */
10631 6 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
10632 : break;
10633 : }
10634 : share_name = "shared";
10635 : break;
10636 : case OMP_CLAUSE_DEFAULT_PRIVATE:
10637 : share_name = "private";
10638 : break;
10639 0 : default:
10640 0 : gcc_unreachable ();
10641 : }
10642 : if (share_name)
10643 : {
10644 67 : error_at (OMP_CLAUSE_LOCATION (c),
10645 : "%qE is predetermined %qs for %qs",
10646 : omp_clause_printable_decl (t), share_name,
10647 67 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10648 67 : remove = true;
10649 : }
10650 20499 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10651 18440 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
10652 35805 : && cxx_omp_const_qual_no_mutable (t))
10653 : {
10654 126 : error_at (OMP_CLAUSE_LOCATION (c),
10655 : "%<const%> qualified %qE without %<mutable%> member "
10656 : "may appear only in %<shared%> or %<firstprivate%> "
10657 : "clauses", omp_clause_printable_decl (t));
10658 63 : remove = true;
10659 : }
10660 : }
10661 :
10662 21607 : if (detach_seen
10663 16 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10664 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
10665 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10666 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10667 21623 : && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen))
10668 : {
10669 6 : error_at (OMP_CLAUSE_LOCATION (c),
10670 : "the event handle of a %<detach%> clause "
10671 : "should not be in a data-sharing clause");
10672 6 : remove = true;
10673 : }
10674 :
10675 : /* We're interested in the base element, not arrays. */
10676 21607 : inner_type = type = TREE_TYPE (t);
10677 21607 : if ((need_complete_type
10678 : || need_copy_assignment
10679 12391 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10680 5711 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10681 4238 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10682 30087 : && TYPE_REF_P (inner_type))
10683 878 : inner_type = TREE_TYPE (inner_type);
10684 24198 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
10685 2591 : inner_type = TREE_TYPE (inner_type);
10686 :
10687 : /* Check for special function availability by building a call to one.
10688 : Save the results, because later we won't be in the right context
10689 : for making these queries. */
10690 2397 : if (CLASS_TYPE_P (inner_type)
10691 2397 : && COMPLETE_TYPE_P (inner_type)
10692 2328 : && (need_default_ctor || need_copy_ctor
10693 1091 : || need_copy_assignment || need_dtor)
10694 2004 : && !type_dependent_expression_p (t)
10695 23611 : && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
10696 : need_copy_ctor, need_copy_assignment,
10697 : need_dtor))
10698 : remove = true;
10699 :
10700 21607 : if (!remove
10701 21607 : && c_kind == OMP_CLAUSE_SHARED
10702 2056 : && processing_template_decl)
10703 : {
10704 125 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10705 125 : if (t)
10706 5 : OMP_CLAUSE_DECL (c) = t;
10707 : }
10708 :
10709 21607 : if (remove)
10710 292 : *pc = OMP_CLAUSE_CHAIN (c);
10711 : else
10712 21315 : pc = &OMP_CLAUSE_CHAIN (c);
10713 : }
10714 :
10715 62789 : if (allocate_seen)
10716 16877 : for (pc = &clauses, c = clauses; c ; c = *pc)
10717 : {
10718 14584 : bool remove = false;
10719 14584 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
10720 2556 : && !OMP_CLAUSE_ALLOCATE_COMBINED (c)
10721 2156 : && DECL_P (OMP_CLAUSE_DECL (c))
10722 16740 : && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c))))
10723 : {
10724 15 : error_at (OMP_CLAUSE_LOCATION (c),
10725 : "%qD specified in %<allocate%> clause but not in "
10726 15 : "an explicit privatization clause", OMP_CLAUSE_DECL (c));
10727 15 : remove = true;
10728 : }
10729 14584 : if (remove)
10730 15 : *pc = OMP_CLAUSE_CHAIN (c);
10731 : else
10732 14569 : pc = &OMP_CLAUSE_CHAIN (c);
10733 : }
10734 :
10735 62789 : if (ort == C_ORT_OMP_INTEROP
10736 62789 : && depend_clause
10737 60 : && (!init_use_destroy_seen
10738 57 : || (init_seen && init_no_targetsync_clause)))
10739 : {
10740 9 : auto_diagnostic_group d;
10741 9 : error_at (OMP_CLAUSE_LOCATION (depend_clause),
10742 : "%<depend%> clause requires action clauses with "
10743 : "%<targetsync%> interop-type");
10744 9 : if (init_no_targetsync_clause)
10745 6 : inform (OMP_CLAUSE_LOCATION (init_no_targetsync_clause),
10746 : "%<init%> clause lacks the %<targetsync%> modifier");
10747 9 : }
10748 :
10749 62789 : bitmap_obstack_release (NULL);
10750 62789 : return clauses;
10751 : }
10752 :
10753 : /* Start processing OpenMP clauses that can include any
10754 : privatization clauses for non-static data members. */
10755 :
10756 : tree
10757 48638 : push_omp_privatization_clauses (bool ignore_next)
10758 : {
10759 48638 : if (omp_private_member_ignore_next)
10760 : {
10761 656 : omp_private_member_ignore_next = ignore_next;
10762 656 : return NULL_TREE;
10763 : }
10764 47982 : omp_private_member_ignore_next = ignore_next;
10765 47982 : if (omp_private_member_map)
10766 24 : omp_private_member_vec.safe_push (error_mark_node);
10767 47982 : return push_stmt_list ();
10768 : }
10769 :
10770 : /* Revert remapping of any non-static data members since
10771 : the last push_omp_privatization_clauses () call. */
10772 :
10773 : void
10774 48632 : pop_omp_privatization_clauses (tree stmt)
10775 : {
10776 48632 : if (stmt == NULL_TREE)
10777 : return;
10778 47976 : stmt = pop_stmt_list (stmt);
10779 47976 : if (omp_private_member_map)
10780 : {
10781 1280 : while (!omp_private_member_vec.is_empty ())
10782 : {
10783 850 : tree t = omp_private_member_vec.pop ();
10784 850 : if (t == error_mark_node)
10785 : {
10786 24 : add_stmt (stmt);
10787 24 : return;
10788 : }
10789 826 : bool no_decl_expr = t == integer_zero_node;
10790 826 : if (no_decl_expr)
10791 136 : t = omp_private_member_vec.pop ();
10792 826 : tree *v = omp_private_member_map->get (t);
10793 826 : gcc_assert (v);
10794 826 : if (!no_decl_expr)
10795 690 : add_decl_expr (*v);
10796 826 : omp_private_member_map->remove (t);
10797 : }
10798 860 : delete omp_private_member_map;
10799 430 : omp_private_member_map = NULL;
10800 : }
10801 47952 : add_stmt (stmt);
10802 : }
10803 :
10804 : /* Remember OpenMP privatization clauses mapping and clear it.
10805 : Used for lambdas. */
10806 :
10807 : void
10808 16155707 : save_omp_privatization_clauses (vec<tree> &save)
10809 : {
10810 16155707 : save = vNULL;
10811 16155707 : if (omp_private_member_ignore_next)
10812 2 : save.safe_push (integer_one_node);
10813 16155707 : omp_private_member_ignore_next = false;
10814 16155707 : if (!omp_private_member_map)
10815 : return;
10816 :
10817 0 : while (!omp_private_member_vec.is_empty ())
10818 : {
10819 0 : tree t = omp_private_member_vec.pop ();
10820 0 : if (t == error_mark_node)
10821 : {
10822 0 : save.safe_push (t);
10823 0 : continue;
10824 : }
10825 0 : tree n = t;
10826 0 : if (t == integer_zero_node)
10827 0 : t = omp_private_member_vec.pop ();
10828 0 : tree *v = omp_private_member_map->get (t);
10829 0 : gcc_assert (v);
10830 0 : save.safe_push (*v);
10831 0 : save.safe_push (t);
10832 0 : if (n != t)
10833 0 : save.safe_push (n);
10834 : }
10835 0 : delete omp_private_member_map;
10836 0 : omp_private_member_map = NULL;
10837 : }
10838 :
10839 : /* Restore OpenMP privatization clauses mapping saved by the
10840 : above function. */
10841 :
10842 : void
10843 16155707 : restore_omp_privatization_clauses (vec<tree> &save)
10844 : {
10845 16155707 : gcc_assert (omp_private_member_vec.is_empty ());
10846 16155707 : omp_private_member_ignore_next = false;
10847 16155707 : if (save.is_empty ())
10848 : return;
10849 4 : if (save.length () == 1 && save[0] == integer_one_node)
10850 : {
10851 2 : omp_private_member_ignore_next = true;
10852 2 : save.release ();
10853 2 : return;
10854 : }
10855 :
10856 0 : omp_private_member_map = new hash_map <tree, tree>;
10857 0 : while (!save.is_empty ())
10858 : {
10859 0 : tree t = save.pop ();
10860 0 : tree n = t;
10861 0 : if (t != error_mark_node)
10862 : {
10863 0 : if (t == integer_one_node)
10864 : {
10865 0 : omp_private_member_ignore_next = true;
10866 0 : gcc_assert (save.is_empty ());
10867 0 : break;
10868 : }
10869 0 : if (t == integer_zero_node)
10870 0 : t = save.pop ();
10871 0 : tree &v = omp_private_member_map->get_or_insert (t);
10872 0 : v = save.pop ();
10873 : }
10874 0 : omp_private_member_vec.safe_push (t);
10875 0 : if (n != t)
10876 0 : omp_private_member_vec.safe_push (n);
10877 : }
10878 0 : save.release ();
10879 : }
10880 :
10881 : /* For all variables in the tree_list VARS, mark them as thread local. */
10882 :
10883 : void
10884 241 : finish_omp_threadprivate (tree vars)
10885 : {
10886 241 : tree t;
10887 :
10888 : /* Mark every variable in VARS to be assigned thread local storage. */
10889 515 : for (t = vars; t; t = TREE_CHAIN (t))
10890 : {
10891 274 : tree v = TREE_PURPOSE (t);
10892 274 : location_t loc = EXPR_LOCATION (TREE_VALUE (t));
10893 :
10894 274 : if (error_operand_p (v))
10895 : ;
10896 274 : else if (!VAR_P (v))
10897 6 : error_at (loc, "%<threadprivate%> %qD is not file, namespace "
10898 : "or block scope variable", v);
10899 : /* If V had already been marked threadprivate, it doesn't matter
10900 : whether it had been used prior to this point. */
10901 268 : else if (TREE_USED (v)
10902 268 : && (DECL_LANG_SPECIFIC (v) == NULL
10903 3 : || !CP_DECL_THREADPRIVATE_P (v)))
10904 6 : error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10905 262 : else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10906 6 : error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10907 256 : else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v))))
10908 3 : error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10909 204 : else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))
10910 276 : && CP_DECL_CONTEXT (v) != current_class_type)
10911 6 : error_at (loc, "%<threadprivate%> %qE directive not "
10912 6 : "in %qT definition", v, CP_DECL_CONTEXT (v));
10913 : else
10914 : {
10915 : /* Allocate a LANG_SPECIFIC structure for V, if needed. */
10916 247 : if (DECL_LANG_SPECIFIC (v) == NULL)
10917 203 : retrofit_lang_decl (v);
10918 :
10919 247 : if (! CP_DECL_THREAD_LOCAL_P (v))
10920 : {
10921 247 : CP_DECL_THREAD_LOCAL_P (v) = true;
10922 247 : set_decl_tls_model (v, decl_default_tls_model (v));
10923 : /* If rtl has been already set for this var, call
10924 : make_decl_rtl once again, so that encode_section_info
10925 : has a chance to look at the new decl flags. */
10926 247 : if (DECL_RTL_SET_P (v))
10927 0 : make_decl_rtl (v);
10928 : }
10929 247 : CP_DECL_THREADPRIVATE_P (v) = 1;
10930 : }
10931 : }
10932 241 : }
10933 :
10934 : /* Build an OpenMP structured block. */
10935 :
10936 : tree
10937 64121 : begin_omp_structured_block (void)
10938 : {
10939 64121 : return do_pushlevel (sk_omp);
10940 : }
10941 :
10942 : tree
10943 64106 : finish_omp_structured_block (tree block)
10944 : {
10945 64106 : return do_poplevel (block);
10946 : }
10947 :
10948 : /* Similarly, except force the retention of the BLOCK. */
10949 :
10950 : tree
10951 14824 : begin_omp_parallel (void)
10952 : {
10953 14824 : keep_next_level (true);
10954 14824 : return begin_omp_structured_block ();
10955 : }
10956 :
10957 : /* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
10958 : statement. */
10959 :
10960 : tree
10961 768 : finish_oacc_data (tree clauses, tree block)
10962 : {
10963 768 : tree stmt;
10964 :
10965 768 : block = finish_omp_structured_block (block);
10966 :
10967 768 : stmt = make_node (OACC_DATA);
10968 768 : TREE_TYPE (stmt) = void_type_node;
10969 768 : OACC_DATA_CLAUSES (stmt) = clauses;
10970 768 : OACC_DATA_BODY (stmt) = block;
10971 :
10972 768 : return add_stmt (stmt);
10973 : }
10974 :
10975 : /* Generate OACC_HOST_DATA, with CLAUSES and BLOCK as its compound
10976 : statement. */
10977 :
10978 : tree
10979 55 : finish_oacc_host_data (tree clauses, tree block)
10980 : {
10981 55 : tree stmt;
10982 :
10983 55 : block = finish_omp_structured_block (block);
10984 :
10985 55 : stmt = make_node (OACC_HOST_DATA);
10986 55 : TREE_TYPE (stmt) = void_type_node;
10987 55 : OACC_HOST_DATA_CLAUSES (stmt) = clauses;
10988 55 : OACC_HOST_DATA_BODY (stmt) = block;
10989 :
10990 55 : return add_stmt (stmt);
10991 : }
10992 :
10993 : /* Generate OMP construct CODE, with BODY and CLAUSES as its compound
10994 : statement. */
10995 :
10996 : tree
10997 4653 : finish_omp_construct (enum tree_code code, tree body, tree clauses)
10998 : {
10999 4653 : body = finish_omp_structured_block (body);
11000 :
11001 4653 : tree stmt = make_node (code);
11002 4653 : TREE_TYPE (stmt) = void_type_node;
11003 4653 : OMP_BODY (stmt) = body;
11004 4653 : OMP_CLAUSES (stmt) = clauses;
11005 :
11006 4653 : return add_stmt (stmt);
11007 : }
11008 :
11009 : /* Used to walk OpenMP target directive body. */
11010 :
11011 : struct omp_target_walk_data
11012 : {
11013 : /* Holds the 'this' expression found in current function. */
11014 : tree current_object;
11015 :
11016 : /* True if the 'this' expression was accessed in the target body. */
11017 : bool this_expr_accessed;
11018 :
11019 : /* For non-static functions, record which pointer-typed members were
11020 : accessed, and the whole expression. */
11021 : hash_map<tree, tree> ptr_members_accessed;
11022 :
11023 : /* Record which lambda objects were accessed in target body. */
11024 : hash_set<tree> lambda_objects_accessed;
11025 :
11026 : /* For lambda functions, the __closure object expression of the current
11027 : function, and the set of captured variables accessed in target body. */
11028 : tree current_closure;
11029 : hash_set<tree> closure_vars_accessed;
11030 :
11031 : /* Local variables declared inside a BIND_EXPR, used to filter out such
11032 : variables when recording lambda_objects_accessed. */
11033 : hash_set<tree> local_decls;
11034 :
11035 : omp_mapper_list<tree> *mappers;
11036 : };
11037 :
11038 : /* Helper function of finish_omp_target_clauses, called via
11039 : cp_walk_tree_without_duplicates. Traverse body of OpenMP target
11040 : directive *TP, and fill out omp_target_walk_data passed in *PTR. */
11041 :
11042 : static tree
11043 228829 : finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr)
11044 : {
11045 228829 : tree t = *tp;
11046 228829 : struct omp_target_walk_data *data = (struct omp_target_walk_data *) ptr;
11047 228829 : tree current_object = data->current_object;
11048 228829 : tree current_closure = data->current_closure;
11049 228829 : omp_mapper_list<tree> *mlist = data->mappers;
11050 :
11051 : /* References inside of these expression codes shouldn't incur any
11052 : form of mapping, so return early. */
11053 228829 : if (TREE_CODE (t) == SIZEOF_EXPR
11054 228821 : || TREE_CODE (t) == ALIGNOF_EXPR)
11055 : {
11056 8 : *walk_subtrees = 0;
11057 8 : return NULL_TREE;
11058 : }
11059 :
11060 228821 : if (TREE_CODE (t) == OMP_CLAUSE)
11061 : return NULL_TREE;
11062 :
11063 216223 : if (!processing_template_decl)
11064 : {
11065 216223 : tree aggr_type = NULL_TREE;
11066 :
11067 216223 : if (TREE_CODE (t) == COMPONENT_REF
11068 216223 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
11069 2257 : aggr_type = TREE_TYPE (TREE_OPERAND (t, 0));
11070 213966 : else if ((TREE_CODE (t) == VAR_DECL
11071 : || TREE_CODE (t) == PARM_DECL
11072 : || TREE_CODE (t) == RESULT_DECL)
11073 16988 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
11074 1216 : aggr_type = TREE_TYPE (t);
11075 :
11076 3473 : if (aggr_type)
11077 : {
11078 3473 : tree mapper_fn = cxx_omp_mapper_lookup (NULL_TREE, aggr_type);
11079 3473 : if (mapper_fn)
11080 199 : mlist->add_mapper (NULL_TREE, aggr_type, mapper_fn);
11081 : }
11082 : }
11083 :
11084 216223 : if (current_object)
11085 : {
11086 2564 : tree this_expr = TREE_OPERAND (current_object, 0);
11087 :
11088 2564 : if (operand_equal_p (t, this_expr))
11089 : {
11090 35 : data->this_expr_accessed = true;
11091 35 : *walk_subtrees = 0;
11092 35 : return NULL_TREE;
11093 : }
11094 :
11095 2529 : if (TREE_CODE (t) == COMPONENT_REF
11096 115 : && POINTER_TYPE_P (TREE_TYPE (t))
11097 36 : && operand_equal_p (TREE_OPERAND (t, 0), current_object)
11098 2563 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL)
11099 : {
11100 34 : data->this_expr_accessed = true;
11101 34 : tree fld = TREE_OPERAND (t, 1);
11102 34 : if (data->ptr_members_accessed.get (fld) == NULL)
11103 : {
11104 14 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
11105 4 : t = convert_from_reference (t);
11106 14 : data->ptr_members_accessed.put (fld, t);
11107 : }
11108 34 : *walk_subtrees = 0;
11109 34 : return NULL_TREE;
11110 : }
11111 : }
11112 :
11113 : /* When the current_function_decl is a lambda function, the closure object
11114 : argument's type seems to not yet have fields laid out, so a recording
11115 : of DECL_VALUE_EXPRs during the target body walk seems the only way to
11116 : find them. */
11117 216154 : if (current_closure
11118 300 : && (VAR_P (t)
11119 : || TREE_CODE (t) == PARM_DECL
11120 : || TREE_CODE (t) == RESULT_DECL)
11121 24 : && DECL_HAS_VALUE_EXPR_P (t)
11122 10 : && TREE_CODE (DECL_VALUE_EXPR (t)) == COMPONENT_REF
11123 216164 : && operand_equal_p (current_closure,
11124 10 : TREE_OPERAND (DECL_VALUE_EXPR (t), 0)))
11125 : {
11126 9 : if (!data->closure_vars_accessed.contains (t))
11127 9 : data->closure_vars_accessed.add (t);
11128 9 : *walk_subtrees = 0;
11129 9 : return NULL_TREE;
11130 : }
11131 :
11132 216145 : if (TREE_CODE (t) == BIND_EXPR)
11133 : {
11134 20011 : if (tree block = BIND_EXPR_BLOCK (t))
11135 22467 : for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
11136 2460 : if (!data->local_decls.contains (var))
11137 2460 : data->local_decls.add (var);
11138 20011 : return NULL_TREE;
11139 : }
11140 :
11141 200737 : if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
11142 : {
11143 39 : tree lt = TREE_TYPE (t);
11144 39 : gcc_assert (CLASS_TYPE_P (lt));
11145 :
11146 39 : if (!data->lambda_objects_accessed.contains (t)
11147 : /* Do not prepare to create target maps for locally declared
11148 : lambdas or anonymous ones. */
11149 39 : && !data->local_decls.contains (t)
11150 72 : && TREE_CODE (t) != TARGET_EXPR)
11151 13 : data->lambda_objects_accessed.add (t);
11152 39 : *walk_subtrees = 0;
11153 39 : return NULL_TREE;
11154 : }
11155 :
11156 : return NULL_TREE;
11157 : }
11158 :
11159 : /* Helper function for finish_omp_target, and also from tsubst_expr.
11160 : Create additional clauses for mapping of non-static members, lambda objects,
11161 : etc. */
11162 :
11163 : void
11164 6958 : finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr)
11165 : {
11166 6958 : omp_target_walk_data data;
11167 6958 : data.this_expr_accessed = false;
11168 6958 : data.current_object = NULL_TREE;
11169 :
11170 6958 : if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr)
11171 96 : if (tree ct = current_nonlambda_class_type ())
11172 : {
11173 95 : tree object = maybe_dummy_object (ct, NULL);
11174 95 : object = maybe_resolve_dummy (object, true);
11175 95 : data.current_object = object;
11176 : }
11177 :
11178 6958 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11179 : {
11180 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11181 8 : data.current_closure = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11182 : }
11183 : else
11184 6950 : data.current_closure = NULL_TREE;
11185 :
11186 6958 : auto_vec<tree, 16> new_clauses;
11187 :
11188 6958 : if (!processing_template_decl)
11189 : {
11190 6958 : hash_set<omp_name_type<tree> > seen_types;
11191 6958 : auto_vec<tree> mapper_fns;
11192 6958 : omp_mapper_list<tree> mlist (&seen_types, &mapper_fns);
11193 6958 : data.mappers = &mlist;
11194 :
11195 6958 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11196 : &data);
11197 :
11198 6958 : unsigned int i;
11199 6958 : tree mapper_fn;
11200 14009 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11201 93 : c_omp_find_nested_mappers (&mlist, mapper_fn);
11202 :
11203 7121 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11204 : {
11205 93 : tree mapper = cxx_omp_extract_mapper_directive (mapper_fn);
11206 93 : if (mapper == error_mark_node)
11207 0 : continue;
11208 93 : tree mapper_name = OMP_DECLARE_MAPPER_ID (mapper);
11209 93 : tree decl = OMP_DECLARE_MAPPER_DECL (mapper);
11210 93 : if (BASELINK_P (mapper_fn))
11211 0 : mapper_fn = BASELINK_FUNCTIONS (mapper_fn);
11212 :
11213 93 : tree c = build_omp_clause (loc, OMP_CLAUSE__MAPPER_BINDING_);
11214 93 : OMP_CLAUSE__MAPPER_BINDING__ID (c) = mapper_name;
11215 93 : OMP_CLAUSE__MAPPER_BINDING__DECL (c) = decl;
11216 93 : OMP_CLAUSE__MAPPER_BINDING__MAPPER (c) = mapper_fn;
11217 :
11218 93 : new_clauses.safe_push (c);
11219 : }
11220 6958 : }
11221 : else
11222 : {
11223 0 : data.mappers = NULL;
11224 0 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11225 : &data);
11226 : }
11227 :
11228 6958 : tree omp_target_this_expr = NULL_TREE;
11229 6958 : tree *explicit_this_deref_map = NULL;
11230 6958 : if (data.this_expr_accessed)
11231 : {
11232 31 : omp_target_this_expr = TREE_OPERAND (data.current_object, 0);
11233 :
11234 : /* See if explicit user-specified map(this[:]) clause already exists.
11235 : If not, we create an implicit map(tofrom:this[:1]) clause. */
11236 80 : for (tree *cp = clauses_ptr; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
11237 50 : if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
11238 47 : && (TREE_CODE (OMP_CLAUSE_DECL (*cp)) == INDIRECT_REF
11239 40 : || TREE_CODE (OMP_CLAUSE_DECL (*cp)) == MEM_REF)
11240 57 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*cp), 0),
11241 : omp_target_this_expr))
11242 : {
11243 : explicit_this_deref_map = cp;
11244 : break;
11245 : }
11246 : }
11247 :
11248 6958 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11249 6958 : && (data.this_expr_accessed
11250 1 : || !data.closure_vars_accessed.is_empty ()))
11251 : {
11252 : /* For lambda functions, we need to first create a copy of the
11253 : __closure object. */
11254 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11255 8 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11256 8 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11257 8 : OMP_CLAUSE_DECL (c)
11258 8 : = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11259 8 : OMP_CLAUSE_SIZE (c)
11260 8 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure)));
11261 8 : new_clauses.safe_push (c);
11262 :
11263 8 : tree closure_obj = OMP_CLAUSE_DECL (c);
11264 8 : tree closure_type = TREE_TYPE (closure_obj);
11265 :
11266 16 : gcc_assert (LAMBDA_TYPE_P (closure_type)
11267 : && CLASS_TYPE_P (closure_type));
11268 :
11269 8 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11270 8 : OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
11271 8 : OMP_CLAUSE_DECL (c2) = closure;
11272 8 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11273 8 : new_clauses.safe_push (c2);
11274 : }
11275 :
11276 6958 : if (data.this_expr_accessed)
11277 : {
11278 : /* If the this-expr was accessed, create a map(*this) clause. */
11279 31 : enum gomp_map_kind kind = GOMP_MAP_TOFROM;
11280 31 : if (explicit_this_deref_map)
11281 : {
11282 1 : tree this_map = *explicit_this_deref_map;
11283 1 : tree nc = OMP_CLAUSE_CHAIN (this_map);
11284 2 : gcc_assert (nc != NULL_TREE
11285 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11286 : && (OMP_CLAUSE_MAP_KIND (nc)
11287 : == GOMP_MAP_FIRSTPRIVATE_POINTER));
11288 1 : kind = OMP_CLAUSE_MAP_KIND (this_map);
11289 : /* Remove the original 'map(*this) map(firstprivate_ptr:this)'
11290 : two-map sequence away from the chain. */
11291 1 : *explicit_this_deref_map = OMP_CLAUSE_CHAIN (nc);
11292 : }
11293 31 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11294 31 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11295 31 : OMP_CLAUSE_DECL (c)
11296 31 : = build_indirect_ref (loc, omp_target_this_expr, RO_UNARY_STAR);
11297 31 : OMP_CLAUSE_SIZE (c)
11298 31 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (omp_target_this_expr)));
11299 31 : new_clauses.safe_push (c);
11300 :
11301 : /* If we're in a lambda function, the this-pointer will actually be
11302 : '__closure->this', a mapped member of __closure, hence always_pointer.
11303 : Otherwise it's a firstprivate pointer. */
11304 31 : enum gomp_map_kind ptr_kind
11305 31 : = (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11306 31 : ? GOMP_MAP_ALWAYS_POINTER
11307 24 : : GOMP_MAP_FIRSTPRIVATE_POINTER);
11308 31 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11309 31 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11310 31 : OMP_CLAUSE_DECL (c) = omp_target_this_expr;
11311 31 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11312 31 : new_clauses.safe_push (c);
11313 : }
11314 :
11315 6958 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11316 : {
11317 8 : if (omp_target_this_expr)
11318 : {
11319 7 : STRIP_NOPS (omp_target_this_expr);
11320 7 : gcc_assert (DECL_HAS_VALUE_EXPR_P (omp_target_this_expr));
11321 7 : omp_target_this_expr = DECL_VALUE_EXPR (omp_target_this_expr);
11322 : }
11323 :
11324 17 : for (hash_set<tree>::iterator i = data.closure_vars_accessed.begin ();
11325 34 : i != data.closure_vars_accessed.end (); ++i)
11326 : {
11327 9 : tree orig_decl = *i;
11328 9 : tree closure_expr = DECL_VALUE_EXPR (orig_decl);
11329 :
11330 9 : if (TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE
11331 9 : || TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE)
11332 : {
11333 : /* this-pointer is processed above, outside this loop. */
11334 3 : if (omp_target_this_expr
11335 3 : && operand_equal_p (closure_expr, omp_target_this_expr))
11336 0 : continue;
11337 :
11338 3 : bool ptr_p = TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE;
11339 3 : enum gomp_map_kind kind, ptr_kind, nc_kind;
11340 3 : tree size;
11341 :
11342 3 : if (ptr_p)
11343 : {
11344 : /* For pointers, default mapped as zero-length array
11345 : section. */
11346 2 : kind = GOMP_MAP_ALLOC;
11347 2 : nc_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
11348 2 : ptr_kind = GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
11349 2 : size = size_zero_node;
11350 : }
11351 : else
11352 : {
11353 : /* For references, default mapped as appearing on map
11354 : clause. */
11355 1 : kind = GOMP_MAP_TOFROM;
11356 1 : nc_kind = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
11357 1 : ptr_kind = GOMP_MAP_ALWAYS_POINTER;
11358 1 : size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure_expr)));
11359 : }
11360 :
11361 6 : for (tree *p = clauses_ptr; *p; p = &OMP_CLAUSE_CHAIN (*p))
11362 3 : if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_MAP
11363 1 : && (TREE_CODE (OMP_CLAUSE_DECL (*p)) == INDIRECT_REF
11364 1 : || TREE_CODE (OMP_CLAUSE_DECL (*p)) == MEM_REF)
11365 3 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*p), 0),
11366 : orig_decl))
11367 : {
11368 : /* If this was already specified by user as a map,
11369 : save the user specified map kind, delete the
11370 : "map(*ptr/ref), map(firstprivate ptr/ref)" sequence,
11371 : and insert our own sequence:
11372 : "map(*__closure->ptr/ref), map(<ptr_kind>:__closure->ref"
11373 : */
11374 0 : tree nc = OMP_CLAUSE_CHAIN (*p);
11375 0 : gcc_assert (nc != NULL_TREE
11376 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11377 : && OMP_CLAUSE_MAP_KIND (nc) == nc_kind);
11378 : /* Update with user specified kind and size. */
11379 0 : kind = OMP_CLAUSE_MAP_KIND (*p);
11380 0 : size = OMP_CLAUSE_SIZE (*p);
11381 0 : *p = OMP_CLAUSE_CHAIN (nc);
11382 0 : break;
11383 : }
11384 :
11385 3 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11386 3 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11387 3 : OMP_CLAUSE_DECL (c)
11388 3 : = build_indirect_ref (loc, closure_expr, RO_UNARY_STAR);
11389 3 : OMP_CLAUSE_SIZE (c) = size;
11390 3 : if (ptr_p)
11391 2 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11392 3 : new_clauses.safe_push (c);
11393 :
11394 3 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11395 3 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11396 3 : OMP_CLAUSE_DECL (c) = closure_expr;
11397 3 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11398 3 : new_clauses.safe_push (c);
11399 : }
11400 : }
11401 : }
11402 :
11403 6958 : if (!data.ptr_members_accessed.is_empty ())
11404 14 : for (hash_map<tree, tree>::iterator i = data.ptr_members_accessed.begin ();
11405 56 : i != data.ptr_members_accessed.end (); ++i)
11406 : {
11407 : /* For each referenced member that is of pointer or reference-to-pointer
11408 : type, create the equivalent of map(alloc:this->ptr[:0]). */
11409 14 : tree field_decl = (*i).first;
11410 14 : tree ptr_member = (*i).second;
11411 :
11412 26 : for (tree c = *clauses_ptr; c; c = OMP_CLAUSE_CHAIN (c))
11413 : {
11414 16 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
11415 2 : continue;
11416 : /* If map(this->ptr[:N]) already exists, avoid creating another
11417 : such map. */
11418 14 : tree decl = OMP_CLAUSE_DECL (c);
11419 14 : if ((TREE_CODE (decl) == INDIRECT_REF
11420 10 : || TREE_CODE (decl) == MEM_REF)
11421 14 : && operand_equal_p (TREE_OPERAND (decl, 0), ptr_member))
11422 4 : goto next_ptr_member;
11423 : }
11424 :
11425 10 : if (!cxx_mark_addressable (ptr_member))
11426 0 : gcc_unreachable ();
11427 :
11428 10 : if (TREE_CODE (TREE_TYPE (field_decl)) == REFERENCE_TYPE)
11429 : {
11430 : /* For reference to pointers, we need to map the referenced
11431 : pointer first for things to be correct. */
11432 4 : tree ptr_member_type = TREE_TYPE (ptr_member);
11433 :
11434 : /* Map pointer target as zero-length array section. */
11435 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11436 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11437 4 : OMP_CLAUSE_DECL (c)
11438 4 : = build1 (INDIRECT_REF, TREE_TYPE (ptr_member_type), ptr_member);
11439 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11440 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11441 :
11442 : /* Map pointer to zero-length array section. */
11443 4 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11444 4 : OMP_CLAUSE_SET_MAP_KIND
11445 : (c2, GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION);
11446 4 : OMP_CLAUSE_DECL (c2) = ptr_member;
11447 4 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11448 :
11449 : /* Attach reference-to-pointer field to pointer. */
11450 4 : tree c3 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11451 4 : OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH);
11452 4 : OMP_CLAUSE_DECL (c3) = TREE_OPERAND (ptr_member, 0);
11453 4 : OMP_CLAUSE_SIZE (c3) = size_zero_node;
11454 :
11455 4 : new_clauses.safe_push (c);
11456 4 : new_clauses.safe_push (c2);
11457 4 : new_clauses.safe_push (c3);
11458 : }
11459 6 : else if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
11460 : {
11461 : /* Map pointer target as zero-length array section. */
11462 6 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11463 6 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11464 6 : OMP_CLAUSE_DECL (c) = build_indirect_ref (loc, ptr_member,
11465 : RO_UNARY_STAR);
11466 6 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11467 6 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11468 :
11469 : /* Attach zero-length array section to pointer. */
11470 6 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11471 6 : OMP_CLAUSE_SET_MAP_KIND
11472 : (c2, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11473 6 : OMP_CLAUSE_DECL (c2) = ptr_member;
11474 6 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11475 :
11476 6 : new_clauses.safe_push (c);
11477 6 : new_clauses.safe_push (c2);
11478 : }
11479 : else
11480 0 : gcc_unreachable ();
11481 :
11482 14 : next_ptr_member:
11483 14 : ;
11484 : }
11485 :
11486 6971 : for (hash_set<tree>::iterator i = data.lambda_objects_accessed.begin ();
11487 6984 : i != data.lambda_objects_accessed.end (); ++i)
11488 : {
11489 13 : tree lobj = *i;
11490 13 : if (TREE_CODE (lobj) == TARGET_EXPR)
11491 0 : lobj = TARGET_EXPR_SLOT (lobj);
11492 :
11493 13 : tree lt = TREE_TYPE (lobj);
11494 26 : gcc_assert (LAMBDA_TYPE_P (lt) && CLASS_TYPE_P (lt));
11495 :
11496 13 : tree lc = build_omp_clause (loc, OMP_CLAUSE_MAP);
11497 13 : OMP_CLAUSE_SET_MAP_KIND (lc, GOMP_MAP_TO);
11498 13 : OMP_CLAUSE_DECL (lc) = lobj;
11499 13 : OMP_CLAUSE_SIZE (lc) = TYPE_SIZE_UNIT (lt);
11500 13 : new_clauses.safe_push (lc);
11501 :
11502 180 : for (tree fld = TYPE_FIELDS (lt); fld; fld = DECL_CHAIN (fld))
11503 : {
11504 167 : if (TREE_CODE (TREE_TYPE (fld)) == POINTER_TYPE)
11505 : {
11506 4 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11507 : lobj, fld, NULL_TREE);
11508 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11509 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11510 4 : OMP_CLAUSE_DECL (c)
11511 4 : = build_indirect_ref (loc, exp, RO_UNARY_STAR);
11512 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11513 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11514 4 : new_clauses.safe_push (c);
11515 :
11516 4 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11517 4 : OMP_CLAUSE_SET_MAP_KIND
11518 : (c, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11519 4 : OMP_CLAUSE_DECL (c) = exp;
11520 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11521 4 : new_clauses.safe_push (c);
11522 : }
11523 163 : else if (TREE_CODE (TREE_TYPE (fld)) == REFERENCE_TYPE)
11524 : {
11525 0 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11526 : lobj, fld, NULL_TREE);
11527 0 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11528 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11529 0 : OMP_CLAUSE_DECL (c)
11530 0 : = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
11531 0 : OMP_CLAUSE_SIZE (c)
11532 0 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (exp)));
11533 0 : new_clauses.safe_push (c);
11534 :
11535 0 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11536 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
11537 0 : OMP_CLAUSE_DECL (c) = exp;
11538 0 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11539 0 : new_clauses.safe_push (c);
11540 : }
11541 : }
11542 : }
11543 :
11544 6958 : tree c = *clauses_ptr;
11545 14138 : for (int i = new_clauses.length () - 1; i >= 0; i--)
11546 : {
11547 222 : OMP_CLAUSE_CHAIN (new_clauses[i]) = c;
11548 222 : c = new_clauses[i];
11549 : }
11550 6958 : *clauses_ptr = c;
11551 6958 : }
11552 :
11553 : /* Called from cp_parser_omp_target. Create additional implicit clauses for
11554 : OpenMP target directives, and do sanity checks. */
11555 :
11556 : tree
11557 6948 : finish_omp_target (location_t loc, tree clauses, tree body, bool combined_p)
11558 : {
11559 6948 : if (!processing_template_decl)
11560 6142 : finish_omp_target_clauses (loc, body, &clauses);
11561 :
11562 6948 : tree stmt = make_node (OMP_TARGET);
11563 6948 : TREE_TYPE (stmt) = void_type_node;
11564 6948 : OMP_TARGET_CLAUSES (stmt) = clauses;
11565 6948 : OMP_TARGET_BODY (stmt) = body;
11566 6948 : OMP_TARGET_COMBINED (stmt) = combined_p;
11567 6948 : SET_EXPR_LOCATION (stmt, loc);
11568 :
11569 6948 : tree c = clauses;
11570 16669 : while (c)
11571 : {
11572 9721 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11573 5625 : switch (OMP_CLAUSE_MAP_KIND (c))
11574 : {
11575 : case GOMP_MAP_TO:
11576 : case GOMP_MAP_ALWAYS_TO:
11577 : case GOMP_MAP_PRESENT_TO:
11578 : case GOMP_MAP_ALWAYS_PRESENT_TO:
11579 : case GOMP_MAP_FROM:
11580 : case GOMP_MAP_ALWAYS_FROM:
11581 : case GOMP_MAP_PRESENT_FROM:
11582 : case GOMP_MAP_ALWAYS_PRESENT_FROM:
11583 : case GOMP_MAP_TOFROM:
11584 : case GOMP_MAP_ALWAYS_TOFROM:
11585 : case GOMP_MAP_PRESENT_TOFROM:
11586 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
11587 : case GOMP_MAP_ALLOC:
11588 : case GOMP_MAP_PRESENT_ALLOC:
11589 : case GOMP_MAP_FIRSTPRIVATE_POINTER:
11590 : case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
11591 : case GOMP_MAP_ALWAYS_POINTER:
11592 : case GOMP_MAP_ATTACH_DETACH:
11593 : case GOMP_MAP_ATTACH:
11594 : case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
11595 : case GOMP_MAP_POINTER:
11596 : case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
11597 : break;
11598 3 : default:
11599 3 : error_at (OMP_CLAUSE_LOCATION (c),
11600 : "%<#pragma omp target%> with map-type other "
11601 : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
11602 : "on %<map%> clause");
11603 3 : break;
11604 : }
11605 9721 : c = OMP_CLAUSE_CHAIN (c);
11606 : }
11607 6948 : return add_stmt (stmt);
11608 : }
11609 :
11610 : tree
11611 9348 : finish_omp_parallel (tree clauses, tree body)
11612 : {
11613 9348 : tree stmt;
11614 :
11615 9348 : body = finish_omp_structured_block (body);
11616 :
11617 9348 : stmt = make_node (OMP_PARALLEL);
11618 9348 : TREE_TYPE (stmt) = void_type_node;
11619 9348 : OMP_PARALLEL_CLAUSES (stmt) = clauses;
11620 9348 : OMP_PARALLEL_BODY (stmt) = body;
11621 :
11622 9348 : return add_stmt (stmt);
11623 : }
11624 :
11625 : tree
11626 2162 : begin_omp_task (void)
11627 : {
11628 2162 : keep_next_level (true);
11629 2162 : return begin_omp_structured_block ();
11630 : }
11631 :
11632 : tree
11633 2162 : finish_omp_task (tree clauses, tree body)
11634 : {
11635 2162 : tree stmt;
11636 :
11637 2162 : body = finish_omp_structured_block (body);
11638 :
11639 2162 : stmt = make_node (OMP_TASK);
11640 2162 : TREE_TYPE (stmt) = void_type_node;
11641 2162 : OMP_TASK_CLAUSES (stmt) = clauses;
11642 2162 : OMP_TASK_BODY (stmt) = body;
11643 :
11644 2162 : return add_stmt (stmt);
11645 : }
11646 :
11647 : /* Helper function for finish_omp_for. Convert Ith random access iterator
11648 : into integral iterator. Return FALSE if successful. */
11649 :
11650 : static bool
11651 813 : handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
11652 : tree declv, tree orig_declv, tree initv,
11653 : tree condv, tree incrv, tree *body,
11654 : tree *pre_body, tree &clauses,
11655 : int collapse, int ordered)
11656 : {
11657 813 : tree diff, iter_init, iter_incr = NULL, last;
11658 813 : tree incr_var = NULL, orig_pre_body, orig_body, c;
11659 813 : tree decl = TREE_VEC_ELT (declv, i);
11660 813 : tree init = TREE_VEC_ELT (initv, i);
11661 813 : tree cond = TREE_VEC_ELT (condv, i);
11662 813 : tree incr = TREE_VEC_ELT (incrv, i);
11663 813 : tree iter = decl;
11664 813 : location_t elocus = locus;
11665 :
11666 813 : if (init && EXPR_HAS_LOCATION (init))
11667 12 : elocus = EXPR_LOCATION (init);
11668 :
11669 813 : switch (TREE_CODE (cond))
11670 : {
11671 810 : case GT_EXPR:
11672 810 : case GE_EXPR:
11673 810 : case LT_EXPR:
11674 810 : case LE_EXPR:
11675 810 : case NE_EXPR:
11676 810 : if (TREE_OPERAND (cond, 1) == iter)
11677 42 : cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
11678 42 : TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
11679 810 : if (TREE_OPERAND (cond, 0) != iter)
11680 0 : cond = error_mark_node;
11681 : else
11682 : {
11683 810 : tree tem = build_x_binary_op (EXPR_LOCATION (cond),
11684 810 : TREE_CODE (cond),
11685 : iter, ERROR_MARK,
11686 810 : TREE_OPERAND (cond, 1), ERROR_MARK,
11687 : NULL_TREE, NULL, tf_warning_or_error);
11688 810 : if (error_operand_p (tem))
11689 : return true;
11690 : }
11691 : break;
11692 3 : default:
11693 3 : cond = error_mark_node;
11694 3 : break;
11695 : }
11696 810 : if (cond == error_mark_node)
11697 : {
11698 3 : error_at (elocus, "invalid controlling predicate");
11699 3 : return true;
11700 : }
11701 807 : diff = build_x_binary_op (elocus, MINUS_EXPR,
11702 807 : TREE_OPERAND (cond, 1), ERROR_MARK,
11703 : iter, ERROR_MARK,
11704 : NULL_TREE, NULL, tf_warning_or_error);
11705 807 : diff = cp_fully_fold (diff);
11706 807 : if (error_operand_p (diff))
11707 : return true;
11708 807 : if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
11709 : {
11710 0 : error_at (elocus, "difference between %qE and %qD does not have integer type",
11711 0 : TREE_OPERAND (cond, 1), iter);
11712 0 : return true;
11713 : }
11714 807 : if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
11715 807 : TREE_VEC_ELT (declv, i), NULL_TREE,
11716 : cond, cp_walk_subtrees))
11717 : return true;
11718 :
11719 762 : switch (TREE_CODE (incr))
11720 : {
11721 370 : case PREINCREMENT_EXPR:
11722 370 : case PREDECREMENT_EXPR:
11723 370 : case POSTINCREMENT_EXPR:
11724 370 : case POSTDECREMENT_EXPR:
11725 370 : if (TREE_OPERAND (incr, 0) != iter)
11726 : {
11727 0 : incr = error_mark_node;
11728 0 : break;
11729 : }
11730 370 : iter_incr = build_x_unary_op (EXPR_LOCATION (incr),
11731 370 : TREE_CODE (incr), iter,
11732 : NULL_TREE, tf_warning_or_error);
11733 370 : if (error_operand_p (iter_incr))
11734 : return true;
11735 370 : else if (TREE_CODE (incr) == PREINCREMENT_EXPR
11736 219 : || TREE_CODE (incr) == POSTINCREMENT_EXPR)
11737 299 : incr = integer_one_node;
11738 : else
11739 71 : incr = integer_minus_one_node;
11740 : break;
11741 392 : case MODIFY_EXPR:
11742 392 : if (TREE_OPERAND (incr, 0) != iter)
11743 0 : incr = error_mark_node;
11744 392 : else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
11745 392 : || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
11746 : {
11747 392 : tree rhs = TREE_OPERAND (incr, 1);
11748 392 : if (TREE_OPERAND (rhs, 0) == iter)
11749 : {
11750 299 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
11751 : != INTEGER_TYPE)
11752 0 : incr = error_mark_node;
11753 : else
11754 : {
11755 299 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11756 299 : iter, TREE_CODE (rhs),
11757 299 : TREE_OPERAND (rhs, 1),
11758 : NULL_TREE,
11759 : tf_warning_or_error);
11760 299 : if (error_operand_p (iter_incr))
11761 : return true;
11762 299 : incr = TREE_OPERAND (rhs, 1);
11763 299 : incr = cp_convert (TREE_TYPE (diff), incr,
11764 : tf_warning_or_error);
11765 299 : if (TREE_CODE (rhs) == MINUS_EXPR)
11766 : {
11767 16 : incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
11768 16 : incr = fold_simple (incr);
11769 : }
11770 299 : if (TREE_CODE (incr) != INTEGER_CST
11771 299 : && (TREE_CODE (incr) != NOP_EXPR
11772 66 : || (TREE_CODE (TREE_OPERAND (incr, 0))
11773 : != INTEGER_CST)))
11774 : iter_incr = NULL;
11775 : }
11776 : }
11777 93 : else if (TREE_OPERAND (rhs, 1) == iter)
11778 : {
11779 93 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
11780 93 : || TREE_CODE (rhs) != PLUS_EXPR)
11781 0 : incr = error_mark_node;
11782 : else
11783 : {
11784 93 : iter_incr = build_x_binary_op (EXPR_LOCATION (rhs),
11785 : PLUS_EXPR,
11786 93 : TREE_OPERAND (rhs, 0),
11787 : ERROR_MARK, iter,
11788 : ERROR_MARK, NULL_TREE, NULL,
11789 : tf_warning_or_error);
11790 93 : if (error_operand_p (iter_incr))
11791 : return true;
11792 93 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11793 : iter, NOP_EXPR,
11794 : iter_incr, NULL_TREE,
11795 : tf_warning_or_error);
11796 93 : if (error_operand_p (iter_incr))
11797 : return true;
11798 93 : incr = TREE_OPERAND (rhs, 0);
11799 93 : iter_incr = NULL;
11800 : }
11801 : }
11802 : else
11803 0 : incr = error_mark_node;
11804 : }
11805 : else
11806 0 : incr = error_mark_node;
11807 : break;
11808 0 : default:
11809 0 : incr = error_mark_node;
11810 0 : break;
11811 : }
11812 :
11813 762 : if (incr == error_mark_node)
11814 : {
11815 0 : error_at (elocus, "invalid increment expression");
11816 0 : return true;
11817 : }
11818 :
11819 762 : incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
11820 762 : incr = cp_fully_fold (incr);
11821 762 : tree loop_iv_seen = NULL_TREE;
11822 1735 : for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11823 1093 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11824 1093 : && OMP_CLAUSE_DECL (c) == iter)
11825 : {
11826 120 : if (code == OMP_TASKLOOP || code == OMP_LOOP)
11827 : {
11828 60 : loop_iv_seen = c;
11829 60 : OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
11830 : }
11831 : break;
11832 : }
11833 973 : else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
11834 113 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
11835 1007 : && OMP_CLAUSE_DECL (c) == iter)
11836 : {
11837 30 : loop_iv_seen = c;
11838 30 : if (code == OMP_TASKLOOP)
11839 25 : OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
11840 : }
11841 :
11842 762 : decl = create_temporary_var (TREE_TYPE (diff));
11843 762 : pushdecl (decl);
11844 762 : add_decl_expr (decl);
11845 762 : last = create_temporary_var (TREE_TYPE (diff));
11846 762 : pushdecl (last);
11847 762 : add_decl_expr (last);
11848 762 : if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST
11849 10 : && (!ordered || (i < collapse && collapse > 1)))
11850 : {
11851 10 : incr_var = create_temporary_var (TREE_TYPE (diff));
11852 10 : pushdecl (incr_var);
11853 10 : add_decl_expr (incr_var);
11854 : }
11855 762 : gcc_assert (stmts_are_full_exprs_p ());
11856 762 : tree diffvar = NULL_TREE;
11857 762 : if (code == OMP_TASKLOOP)
11858 : {
11859 101 : if (!loop_iv_seen)
11860 : {
11861 38 : tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11862 38 : OMP_CLAUSE_DECL (ivc) = iter;
11863 38 : cxx_omp_finish_clause (ivc, NULL, false);
11864 38 : OMP_CLAUSE_CHAIN (ivc) = clauses;
11865 38 : clauses = ivc;
11866 : }
11867 101 : tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11868 101 : OMP_CLAUSE_DECL (lvc) = last;
11869 101 : OMP_CLAUSE_CHAIN (lvc) = clauses;
11870 101 : clauses = lvc;
11871 101 : diffvar = create_temporary_var (TREE_TYPE (diff));
11872 101 : pushdecl (diffvar);
11873 101 : add_decl_expr (diffvar);
11874 : }
11875 661 : else if (code == OMP_LOOP)
11876 : {
11877 43 : if (!loop_iv_seen)
11878 : {
11879 : /* While iterators on the loop construct are predetermined
11880 : lastprivate, if the decl is not declared inside of the
11881 : loop, OMP_CLAUSE_LASTPRIVATE should have been added
11882 : already. */
11883 16 : loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11884 16 : OMP_CLAUSE_DECL (loop_iv_seen) = iter;
11885 16 : OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
11886 16 : clauses = loop_iv_seen;
11887 : }
11888 27 : else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
11889 : {
11890 5 : OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
11891 5 : OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
11892 5 : OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
11893 : }
11894 43 : if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
11895 21 : cxx_omp_finish_clause (loop_iv_seen, NULL, false);
11896 : }
11897 :
11898 762 : orig_pre_body = *pre_body;
11899 762 : *pre_body = push_stmt_list ();
11900 762 : if (orig_pre_body)
11901 610 : add_stmt (orig_pre_body);
11902 762 : if (init != NULL)
11903 61 : finish_expr_stmt (build_x_modify_expr (elocus,
11904 : iter, NOP_EXPR, init,
11905 : NULL_TREE, tf_warning_or_error));
11906 762 : init = build_int_cst (TREE_TYPE (diff), 0);
11907 762 : if (c && iter_incr == NULL
11908 28 : && (!ordered || (i < collapse && collapse > 1)))
11909 : {
11910 28 : if (incr_var)
11911 : {
11912 10 : finish_expr_stmt (build_x_modify_expr (elocus,
11913 : incr_var, NOP_EXPR,
11914 : incr, NULL_TREE,
11915 : tf_warning_or_error));
11916 10 : incr = incr_var;
11917 : }
11918 28 : iter_incr = build_x_modify_expr (elocus,
11919 : iter, PLUS_EXPR, incr,
11920 : NULL_TREE, tf_warning_or_error);
11921 : }
11922 762 : if (c && ordered && i < collapse && collapse > 1)
11923 762 : iter_incr = incr;
11924 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11925 : last, NOP_EXPR, init,
11926 : NULL_TREE, tf_warning_or_error));
11927 762 : if (diffvar)
11928 : {
11929 101 : finish_expr_stmt (build_x_modify_expr (elocus,
11930 : diffvar, NOP_EXPR,
11931 : diff, NULL_TREE, tf_warning_or_error));
11932 101 : diff = diffvar;
11933 : }
11934 762 : *pre_body = pop_stmt_list (*pre_body);
11935 :
11936 1524 : cond = cp_build_binary_op (elocus,
11937 762 : TREE_CODE (cond), decl, diff,
11938 : tf_warning_or_error);
11939 762 : incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
11940 : elocus, incr, NULL_TREE);
11941 :
11942 762 : orig_body = *body;
11943 762 : *body = push_stmt_list ();
11944 762 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
11945 762 : iter_init = build_x_modify_expr (elocus,
11946 : iter, PLUS_EXPR, iter_init,
11947 : NULL_TREE, tf_warning_or_error);
11948 762 : if (iter_init != error_mark_node)
11949 759 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11950 762 : finish_expr_stmt (iter_init);
11951 762 : finish_expr_stmt (build_x_modify_expr (elocus,
11952 : last, NOP_EXPR, decl,
11953 : NULL_TREE, tf_warning_or_error));
11954 762 : add_stmt (orig_body);
11955 762 : *body = pop_stmt_list (*body);
11956 :
11957 762 : if (c)
11958 : {
11959 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list ();
11960 120 : if (!ordered)
11961 114 : finish_expr_stmt (iter_incr);
11962 : else
11963 : {
11964 6 : iter_init = decl;
11965 6 : if (i < collapse && collapse > 1 && !error_operand_p (iter_incr))
11966 2 : iter_init = build2 (PLUS_EXPR, TREE_TYPE (diff),
11967 : iter_init, iter_incr);
11968 6 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), iter_init, last);
11969 6 : iter_init = build_x_modify_expr (elocus,
11970 : iter, PLUS_EXPR, iter_init,
11971 : NULL_TREE, tf_warning_or_error);
11972 6 : if (iter_init != error_mark_node)
11973 6 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
11974 6 : finish_expr_stmt (iter_init);
11975 : }
11976 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c)
11977 240 : = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c));
11978 : }
11979 :
11980 762 : if (TREE_CODE (TREE_VEC_ELT (orig_declv, i)) == TREE_LIST)
11981 : {
11982 116 : tree t = TREE_VEC_ELT (orig_declv, i);
11983 116 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
11984 : && TREE_VALUE (t) == NULL_TREE
11985 : && TREE_CODE (TREE_CHAIN (t)) == TREE_VEC);
11986 116 : TREE_PURPOSE (t) = TREE_VEC_ELT (declv, i);
11987 116 : TREE_VALUE (t) = last;
11988 : }
11989 : else
11990 646 : TREE_VEC_ELT (orig_declv, i)
11991 1292 : = tree_cons (TREE_VEC_ELT (declv, i), last, NULL_TREE);
11992 762 : TREE_VEC_ELT (declv, i) = decl;
11993 762 : TREE_VEC_ELT (initv, i) = init;
11994 762 : TREE_VEC_ELT (condv, i) = cond;
11995 762 : TREE_VEC_ELT (incrv, i) = incr;
11996 :
11997 762 : return false;
11998 : }
11999 :
12000 : /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
12001 : are directly for their associated operands in the statement. DECL
12002 : and INIT are a combo; if DECL is NULL then INIT ought to be a
12003 : MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
12004 : optional statements that need to go before the loop into its
12005 : sk_omp scope. */
12006 :
12007 : tree
12008 21176 : finish_omp_for (location_t locus, enum tree_code code, tree declv,
12009 : tree orig_declv, tree initv, tree condv, tree incrv,
12010 : tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
12011 : {
12012 21176 : tree omp_for = NULL, orig_incr = NULL;
12013 21176 : tree decl = NULL, init, cond, incr;
12014 21176 : location_t elocus;
12015 21176 : int i;
12016 21176 : int collapse = 1;
12017 21176 : int ordered = 0;
12018 21176 : auto_vec<location_t> init_locv;
12019 :
12020 21176 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
12021 21176 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
12022 21176 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
12023 21176 : if (TREE_VEC_LENGTH (declv) > 1)
12024 : {
12025 4054 : if (tree ti = omp_find_clause (clauses, OMP_CLAUSE_TILE))
12026 83 : collapse = list_length (OMP_CLAUSE_TILE_LIST (ti));
12027 : else
12028 : {
12029 3971 : if (tree co = omp_find_clause (clauses, OMP_CLAUSE_COLLAPSE))
12030 3501 : collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
12031 470 : else if (tree si = omp_find_clause (clauses, OMP_CLAUSE_SIZES))
12032 394 : collapse = list_length (OMP_CLAUSE_SIZES_LIST (si));
12033 3971 : if (collapse != TREE_VEC_LENGTH (declv))
12034 100 : ordered = TREE_VEC_LENGTH (declv);
12035 : }
12036 : }
12037 48697 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12038 : {
12039 27557 : decl = TREE_VEC_ELT (declv, i);
12040 27557 : init = TREE_VEC_ELT (initv, i);
12041 27557 : cond = TREE_VEC_ELT (condv, i);
12042 27557 : incr = TREE_VEC_ELT (incrv, i);
12043 27557 : elocus = locus;
12044 :
12045 27557 : if (decl == global_namespace)
12046 : {
12047 1101 : gcc_assert (init == NULL_TREE && cond == NULL_TREE && incr == NULL_TREE);
12048 1101 : TREE_VEC_ELT (declv, i) = NULL_TREE;
12049 1101 : init_locv.safe_push (UNKNOWN_LOCATION);
12050 1101 : continue;
12051 : }
12052 : /* We are going to throw out the init's original MODIFY_EXPR or
12053 : MODOP_EXPR below. Save its location so we can use it when
12054 : reconstructing the expression farther down. Alternatively, if the
12055 : initializer is a binding of the iteration variable, save
12056 : that location. Any of these locations in the initialization clause
12057 : for the current nested loop are better than using the argument locus,
12058 : that points to the "for" of the outermost loop in the nest. */
12059 26456 : if (init && EXPR_HAS_LOCATION (init))
12060 17920 : elocus = EXPR_LOCATION (init);
12061 8536 : else if (decl && INDIRECT_REF_P (decl) && EXPR_HAS_LOCATION (decl))
12062 : /* This can happen for class iterators. */
12063 0 : elocus = EXPR_LOCATION (decl);
12064 8536 : else if (decl && DECL_P (decl))
12065 : {
12066 8509 : if (DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
12067 8509 : elocus = DECL_SOURCE_LOCATION (decl);
12068 0 : else if (DECL_INITIAL (decl)
12069 0 : && EXPR_HAS_LOCATION (DECL_INITIAL (decl)))
12070 0 : elocus = EXPR_LOCATION (DECL_INITIAL (decl));
12071 : }
12072 26456 : init_locv.safe_push (elocus);
12073 :
12074 26456 : if (decl == NULL)
12075 : {
12076 16612 : if (init != NULL)
12077 16609 : switch (TREE_CODE (init))
12078 : {
12079 16224 : case MODIFY_EXPR:
12080 16224 : decl = TREE_OPERAND (init, 0);
12081 16224 : init = TREE_OPERAND (init, 1);
12082 16224 : break;
12083 367 : case MODOP_EXPR:
12084 367 : if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
12085 : {
12086 367 : decl = TREE_OPERAND (init, 0);
12087 367 : init = TREE_OPERAND (init, 2);
12088 : }
12089 : break;
12090 : default:
12091 : break;
12092 : }
12093 :
12094 16612 : if (decl == NULL)
12095 : {
12096 21 : error_at (locus,
12097 : "expected iteration declaration or initialization");
12098 21 : return NULL;
12099 : }
12100 : }
12101 :
12102 26435 : if (cond == global_namespace)
12103 170 : continue;
12104 :
12105 26265 : if (cond == NULL)
12106 : {
12107 9 : error_at (elocus, "missing controlling predicate");
12108 9 : return NULL;
12109 : }
12110 :
12111 26256 : if (incr == NULL)
12112 : {
12113 6 : error_at (elocus, "missing increment expression");
12114 6 : return NULL;
12115 : }
12116 :
12117 26250 : TREE_VEC_ELT (declv, i) = decl;
12118 26250 : TREE_VEC_ELT (initv, i) = init;
12119 : }
12120 :
12121 21140 : if (orig_inits)
12122 : {
12123 : bool fail = false;
12124 : tree orig_init;
12125 21262 : FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
12126 1181 : if (orig_init
12127 3396 : && !c_omp_check_loop_iv_exprs (locus, code,
12128 : orig_declv ? orig_declv : declv, i,
12129 1164 : TREE_VEC_ELT (declv, i), orig_init,
12130 : NULL_TREE, cp_walk_subtrees))
12131 : fail = true;
12132 20081 : if (fail)
12133 887 : return NULL;
12134 : }
12135 :
12136 21083 : if (dependent_omp_for_p (declv, initv, condv, incrv, body))
12137 : {
12138 453 : tree stmt;
12139 :
12140 453 : stmt = make_node (code);
12141 :
12142 1499 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12143 : {
12144 593 : if (TREE_VEC_ELT (declv, i) == NULL_TREE)
12145 9 : continue;
12146 : /* This is really just a place-holder. We'll be decomposing this
12147 : again and going through the cp_build_modify_expr path below when
12148 : we instantiate the thing. */
12149 584 : TREE_VEC_ELT (initv, i)
12150 1168 : = build2_loc (init_locv[i], MODIFY_EXPR, void_type_node,
12151 584 : TREE_VEC_ELT (declv, i), TREE_VEC_ELT (initv, i));
12152 : }
12153 :
12154 453 : TREE_TYPE (stmt) = void_type_node;
12155 453 : OMP_FOR_INIT (stmt) = initv;
12156 453 : OMP_FOR_COND (stmt) = condv;
12157 453 : OMP_FOR_INCR (stmt) = incrv;
12158 453 : OMP_FOR_BODY (stmt) = body;
12159 453 : OMP_FOR_PRE_BODY (stmt) = pre_body;
12160 453 : OMP_FOR_CLAUSES (stmt) = clauses;
12161 :
12162 453 : SET_EXPR_LOCATION (stmt, locus);
12163 453 : return add_stmt (stmt);
12164 : }
12165 :
12166 20630 : if (!orig_declv)
12167 19843 : orig_declv = copy_node (declv);
12168 :
12169 20630 : if (processing_template_decl)
12170 612 : orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv));
12171 :
12172 48126 : for (i = 0; i < TREE_VEC_LENGTH (declv); )
12173 : {
12174 27588 : decl = TREE_VEC_ELT (declv, i);
12175 27588 : init = TREE_VEC_ELT (initv, i);
12176 27588 : cond = TREE_VEC_ELT (condv, i);
12177 27588 : incr = TREE_VEC_ELT (incrv, i);
12178 27588 : if (orig_incr)
12179 844 : TREE_VEC_ELT (orig_incr, i) = incr;
12180 27588 : elocus = init_locv[i];
12181 :
12182 27588 : if (decl == NULL_TREE)
12183 : {
12184 1092 : i++;
12185 1092 : continue;
12186 : }
12187 :
12188 26496 : if (!DECL_P (decl))
12189 : {
12190 6 : error_at (elocus, "expected iteration declaration or initialization");
12191 6 : return NULL;
12192 : }
12193 :
12194 26490 : if (incr && TREE_CODE (incr) == MODOP_EXPR)
12195 : {
12196 1 : if (orig_incr)
12197 1 : TREE_VEC_ELT (orig_incr, i) = incr;
12198 1 : incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
12199 1 : TREE_CODE (TREE_OPERAND (incr, 1)),
12200 1 : TREE_OPERAND (incr, 2),
12201 : tf_warning_or_error);
12202 : }
12203 :
12204 26490 : if (CLASS_TYPE_P (TREE_TYPE (decl)))
12205 : {
12206 825 : if (code == OMP_SIMD)
12207 : {
12208 12 : error_at (elocus, "%<#pragma omp simd%> used with class "
12209 : "iteration variable %qE", decl);
12210 12 : return NULL;
12211 : }
12212 813 : if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
12213 : initv, condv, incrv, &body,
12214 : &pre_body, clauses,
12215 : collapse, ordered))
12216 : return NULL;
12217 762 : continue;
12218 : }
12219 :
12220 51330 : if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
12221 27251 : && !TYPE_PTR_P (TREE_TYPE (decl)))
12222 : {
12223 14 : error_at (elocus, "invalid type for iteration variable %qE", decl);
12224 14 : return NULL;
12225 : }
12226 :
12227 25651 : if (!processing_template_decl && TREE_CODE (init) != TREE_VEC)
12228 24890 : init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
12229 : tf_warning_or_error);
12230 : else
12231 761 : init = build2_loc (elocus, MODIFY_EXPR, void_type_node, decl, init);
12232 25651 : if (decl == error_mark_node || init == error_mark_node)
12233 : return NULL;
12234 :
12235 25642 : TREE_VEC_ELT (declv, i) = decl;
12236 25642 : TREE_VEC_ELT (initv, i) = init;
12237 25642 : TREE_VEC_ELT (condv, i) = cond;
12238 25642 : TREE_VEC_ELT (incrv, i) = incr;
12239 25642 : i++;
12240 : }
12241 :
12242 20538 : if (pre_body && IS_EMPTY_STMT (pre_body))
12243 0 : pre_body = NULL;
12244 :
12245 41076 : omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
12246 : incrv, body, pre_body,
12247 20538 : !processing_template_decl);
12248 :
12249 : /* Check for iterators appearing in lb, b or incr expressions. */
12250 20538 : if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees))
12251 : omp_for = NULL_TREE;
12252 :
12253 20052 : if (omp_for == NULL)
12254 702 : return NULL;
12255 :
12256 19836 : add_stmt (omp_for);
12257 :
12258 45544 : for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
12259 : {
12260 25708 : init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i);
12261 25708 : if (init == NULL_TREE)
12262 1032 : continue;
12263 24676 : decl = TREE_OPERAND (init, 0);
12264 24676 : cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i);
12265 24676 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
12266 :
12267 24676 : if (!processing_template_decl)
12268 : {
12269 24155 : if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC)
12270 : {
12271 106 : tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1);
12272 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 1)
12273 106 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12274 106 : t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2);
12275 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 2)
12276 212 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12277 : }
12278 : else
12279 : {
12280 24049 : tree t = TREE_OPERAND (init, 1);
12281 24049 : TREE_OPERAND (init, 1)
12282 48098 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12283 : }
12284 24155 : if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC)
12285 : {
12286 121 : tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1);
12287 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1)
12288 121 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12289 121 : t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2);
12290 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2)
12291 242 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12292 : }
12293 : else
12294 : {
12295 24034 : tree t = TREE_OPERAND (cond, 1);
12296 24034 : TREE_OPERAND (cond, 1)
12297 48068 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12298 : }
12299 : }
12300 :
12301 24676 : if (TREE_CODE (incr) != MODIFY_EXPR)
12302 18471 : continue;
12303 :
12304 6205 : if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
12305 70 : && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
12306 6275 : && !processing_template_decl)
12307 : {
12308 64 : tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
12309 64 : if (TREE_SIDE_EFFECTS (t)
12310 8 : && t != decl
12311 70 : && (TREE_CODE (t) != NOP_EXPR
12312 0 : || TREE_OPERAND (t, 0) != decl))
12313 6 : TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
12314 12 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12315 :
12316 64 : t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
12317 64 : if (TREE_SIDE_EFFECTS (t)
12318 56 : && t != decl
12319 120 : && (TREE_CODE (t) != NOP_EXPR
12320 5 : || TREE_OPERAND (t, 0) != decl))
12321 56 : TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
12322 112 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12323 : }
12324 :
12325 6205 : if (orig_incr)
12326 177 : TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
12327 : }
12328 19836 : OMP_FOR_CLAUSES (omp_for) = clauses;
12329 :
12330 : /* For simd loops with non-static data member iterators, we could have added
12331 : OMP_CLAUSE_LINEAR clauses without OMP_CLAUSE_LINEAR_STEP. As we know the
12332 : step at this point, fill it in. */
12333 4735 : if (code == OMP_SIMD && !processing_template_decl
12334 24527 : && TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)) == 1)
12335 4619 : for (tree c = omp_find_clause (clauses, OMP_CLAUSE_LINEAR); c;
12336 561 : c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_LINEAR))
12337 561 : if (OMP_CLAUSE_LINEAR_STEP (c) == NULL_TREE)
12338 : {
12339 4 : decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0), 0);
12340 4 : gcc_assert (decl == OMP_CLAUSE_DECL (c));
12341 4 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
12342 4 : tree step, stept;
12343 4 : switch (TREE_CODE (incr))
12344 : {
12345 0 : case PREINCREMENT_EXPR:
12346 0 : case POSTINCREMENT_EXPR:
12347 : /* c_omp_for_incr_canonicalize_ptr() should have been
12348 : called to massage things appropriately. */
12349 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12350 0 : OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1);
12351 0 : break;
12352 0 : case PREDECREMENT_EXPR:
12353 0 : case POSTDECREMENT_EXPR:
12354 : /* c_omp_for_incr_canonicalize_ptr() should have been
12355 : called to massage things appropriately. */
12356 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12357 0 : OMP_CLAUSE_LINEAR_STEP (c)
12358 0 : = build_int_cst (TREE_TYPE (decl), -1);
12359 0 : break;
12360 4 : case MODIFY_EXPR:
12361 4 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12362 4 : incr = TREE_OPERAND (incr, 1);
12363 4 : switch (TREE_CODE (incr))
12364 : {
12365 4 : case PLUS_EXPR:
12366 4 : if (TREE_OPERAND (incr, 1) == decl)
12367 0 : step = TREE_OPERAND (incr, 0);
12368 : else
12369 4 : step = TREE_OPERAND (incr, 1);
12370 : break;
12371 0 : case MINUS_EXPR:
12372 0 : case POINTER_PLUS_EXPR:
12373 0 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12374 0 : step = TREE_OPERAND (incr, 1);
12375 0 : break;
12376 0 : default:
12377 0 : gcc_unreachable ();
12378 : }
12379 4 : stept = TREE_TYPE (decl);
12380 4 : if (INDIRECT_TYPE_P (stept))
12381 0 : stept = sizetype;
12382 4 : step = fold_convert (stept, step);
12383 4 : if (TREE_CODE (incr) == MINUS_EXPR)
12384 0 : step = fold_build1 (NEGATE_EXPR, stept, step);
12385 4 : OMP_CLAUSE_LINEAR_STEP (c) = step;
12386 4 : break;
12387 0 : default:
12388 0 : gcc_unreachable ();
12389 : }
12390 : }
12391 : /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
12392 : clauses, we need copy ctor for those rather than default ctor,
12393 : plus as for other lastprivates assignment op and dtor. */
12394 19836 : if (code == OMP_LOOP && !processing_template_decl)
12395 1993 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
12396 1285 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12397 204 : && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
12398 1307 : && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
12399 : false, true, true, true))
12400 0 : CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
12401 :
12402 : return omp_for;
12403 21176 : }
12404 :
12405 : /* Code walker for finish_omp_for_block: extract binding of DP->var
12406 : from its current block and move it to a new BIND_EXPR DP->b
12407 : surrounding the body of DP->omp_for. */
12408 :
12409 : struct fofb_data {
12410 : tree var;
12411 : tree b;
12412 : tree omp_for;
12413 : };
12414 :
12415 : static tree
12416 389 : finish_omp_for_block_walker (tree *tp, int *walk_subtrees, void *dp)
12417 : {
12418 389 : struct fofb_data *fofb = (struct fofb_data *)dp;
12419 389 : if (TREE_CODE (*tp) == BIND_EXPR)
12420 578 : for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
12421 : {
12422 576 : if (*p == fofb->var)
12423 : {
12424 363 : *p = DECL_CHAIN (*p);
12425 363 : if (fofb->b == NULL_TREE)
12426 : {
12427 214 : fofb->b = make_node (BLOCK);
12428 214 : fofb->b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12429 214 : OMP_FOR_BODY (fofb->omp_for), fofb->b);
12430 214 : TREE_SIDE_EFFECTS (fofb->b) = 1;
12431 214 : OMP_FOR_BODY (fofb->omp_for) = fofb->b;
12432 : }
12433 363 : DECL_CHAIN (fofb->var) = BIND_EXPR_VARS (fofb->b);
12434 363 : BIND_EXPR_VARS (fofb->b) = fofb->var;
12435 363 : BLOCK_VARS (BIND_EXPR_BLOCK (fofb->b)) = fofb->var;
12436 363 : BLOCK_VARS (BIND_EXPR_BLOCK (*tp)) = BIND_EXPR_VARS (*tp);
12437 363 : return *tp;
12438 : }
12439 : }
12440 26 : if (TREE_CODE (*tp) != BIND_EXPR && TREE_CODE (*tp) != STATEMENT_LIST)
12441 22 : *walk_subtrees = false;
12442 : return NULL_TREE;
12443 : }
12444 :
12445 : /* Fix up range for decls. Those decls were pushed into BIND's
12446 : BIND_EXPR_VARS, or that of a nested BIND_EXPR inside its body,
12447 : and need to be moved into a new BIND_EXPR surrounding OMP_FOR's body
12448 : so that processing of combined loop directives can find them. */
12449 : tree
12450 14573 : finish_omp_for_block (tree bind, tree omp_for)
12451 : {
12452 14573 : if (omp_for == NULL_TREE
12453 14526 : || !OMP_FOR_ORIG_DECLS (omp_for)
12454 28531 : || bind == NULL_TREE)
12455 615 : return bind;
12456 13958 : struct fofb_data fofb;
12457 13958 : fofb.b = NULL_TREE;
12458 13958 : fofb.omp_for = omp_for;
12459 33443 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (omp_for)); i++)
12460 19485 : if (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i)
12461 19263 : && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i))
12462 : == TREE_LIST)
12463 20316 : && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)))
12464 : {
12465 237 : tree v = TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i));
12466 602 : for (int j = 2; j < TREE_VEC_LENGTH (v); j++)
12467 : {
12468 365 : fofb.var = TREE_VEC_ELT (v, j);
12469 365 : cp_walk_tree (&bind, finish_omp_for_block_walker,
12470 : (void *)&fofb, NULL);
12471 : }
12472 : }
12473 13958 : return bind;
12474 : }
12475 :
12476 : void
12477 3345 : finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
12478 : tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
12479 : tree clauses, enum omp_memory_order mo, bool weak)
12480 : {
12481 3345 : tree orig_lhs;
12482 3345 : tree orig_rhs;
12483 3345 : tree orig_v;
12484 3345 : tree orig_lhs1;
12485 3345 : tree orig_rhs1;
12486 3345 : tree orig_r;
12487 3345 : bool dependent_p;
12488 3345 : tree stmt;
12489 :
12490 3345 : orig_lhs = lhs;
12491 3345 : orig_rhs = rhs;
12492 3345 : orig_v = v;
12493 3345 : orig_lhs1 = lhs1;
12494 3345 : orig_rhs1 = rhs1;
12495 3345 : orig_r = r;
12496 3345 : dependent_p = false;
12497 3345 : stmt = NULL_TREE;
12498 :
12499 : /* Even in a template, we can detect invalid uses of the atomic
12500 : pragma if neither LHS nor RHS is type-dependent. */
12501 3345 : if (processing_template_decl)
12502 : {
12503 600 : dependent_p = (type_dependent_expression_p (lhs)
12504 237 : || (rhs && type_dependent_expression_p (rhs))
12505 234 : || (v && type_dependent_expression_p (v))
12506 234 : || (lhs1 && type_dependent_expression_p (lhs1))
12507 234 : || (rhs1 && type_dependent_expression_p (rhs1))
12508 834 : || (r
12509 25 : && r != void_list_node
12510 16 : && type_dependent_expression_p (r)));
12511 600 : if (clauses)
12512 : {
12513 30 : gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE
12514 : && OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT
12515 : && OMP_CLAUSE_CHAIN (clauses) == NULL_TREE);
12516 30 : if (type_dependent_expression_p (OMP_CLAUSE_HINT_EXPR (clauses))
12517 30 : || TREE_CODE (OMP_CLAUSE_HINT_EXPR (clauses)) != INTEGER_CST)
12518 : dependent_p = true;
12519 : }
12520 : }
12521 576 : if (!dependent_p)
12522 : {
12523 2961 : bool swapped = false;
12524 2961 : if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs))
12525 : {
12526 143 : std::swap (rhs, rhs1);
12527 143 : swapped = !commutative_tree_code (opcode);
12528 : }
12529 2961 : if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1))
12530 : {
12531 0 : if (code == OMP_ATOMIC)
12532 0 : error ("%<#pragma omp atomic update%> uses two different "
12533 : "expressions for memory");
12534 : else
12535 0 : error ("%<#pragma omp atomic capture%> uses two different "
12536 : "expressions for memory");
12537 0 : return;
12538 : }
12539 2961 : if (lhs1 && !cp_tree_equal (lhs, lhs1))
12540 : {
12541 0 : if (code == OMP_ATOMIC)
12542 0 : error ("%<#pragma omp atomic update%> uses two different "
12543 : "expressions for memory");
12544 : else
12545 0 : error ("%<#pragma omp atomic capture%> uses two different "
12546 : "expressions for memory");
12547 0 : return;
12548 : }
12549 5922 : stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs,
12550 : v, lhs1, rhs1, r, swapped, mo, weak,
12551 2961 : processing_template_decl != 0);
12552 2961 : if (stmt == error_mark_node)
12553 : return;
12554 : }
12555 3315 : if (processing_template_decl)
12556 : {
12557 591 : if (code == OMP_ATOMIC_READ)
12558 : {
12559 167 : stmt = build_min_nt_loc (loc, OMP_ATOMIC_READ, orig_lhs);
12560 167 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12561 167 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12562 : }
12563 : else
12564 : {
12565 424 : if (opcode == NOP_EXPR)
12566 35 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
12567 389 : else if (opcode == COND_EXPR)
12568 : {
12569 124 : stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs);
12570 124 : if (orig_r)
12571 50 : stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r,
12572 : stmt);
12573 124 : stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1,
12574 : orig_lhs);
12575 124 : orig_rhs1 = NULL_TREE;
12576 : }
12577 : else
12578 265 : stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
12579 424 : if (orig_rhs1)
12580 182 : stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
12581 : COMPOUND_EXPR, orig_rhs1, stmt);
12582 424 : if (code != OMP_ATOMIC)
12583 : {
12584 233 : stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt);
12585 233 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12586 233 : OMP_ATOMIC_WEAK (stmt) = weak;
12587 233 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12588 : }
12589 : }
12590 591 : stmt = build2 (OMP_ATOMIC, void_type_node,
12591 : clauses ? clauses : integer_zero_node, stmt);
12592 591 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12593 591 : OMP_ATOMIC_WEAK (stmt) = weak;
12594 591 : SET_EXPR_LOCATION (stmt, loc);
12595 : }
12596 :
12597 : /* Avoid -Wunused-value warnings here, the whole construct has side-effects
12598 : and even if it might be wrapped from fold-const.cc or c-omp.cc wrapped
12599 : in some tree that appears to be unused, the value is not unused. */
12600 3315 : warning_sentinel w (warn_unused_value);
12601 3315 : finish_expr_stmt (stmt);
12602 3315 : }
12603 :
12604 : void
12605 359 : finish_omp_barrier (void)
12606 : {
12607 359 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
12608 359 : releasing_vec vec;
12609 359 : vec->quick_push (build_int_cst (integer_type_node, GOMP_BARRIER_EXPLICIT));
12610 359 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12611 359 : finish_expr_stmt (stmt);
12612 359 : }
12613 :
12614 : void
12615 397 : finish_omp_depobj (location_t loc, tree depobj,
12616 : enum omp_clause_depend_kind kind, tree clause)
12617 : {
12618 397 : if (!error_operand_p (depobj) && !type_dependent_expression_p (depobj))
12619 : {
12620 343 : if (!lvalue_p (depobj))
12621 : {
12622 6 : error_at (EXPR_LOC_OR_LOC (depobj, loc),
12623 : "%<depobj%> expression is not lvalue expression");
12624 6 : depobj = error_mark_node;
12625 : }
12626 : }
12627 :
12628 397 : if (processing_template_decl)
12629 : {
12630 114 : if (clause == NULL_TREE)
12631 47 : clause = build_int_cst (integer_type_node, kind);
12632 114 : add_stmt (build_min_nt_loc (loc, OMP_DEPOBJ, depobj, clause));
12633 114 : return;
12634 : }
12635 :
12636 283 : if (!error_operand_p (depobj))
12637 : {
12638 274 : tree addr = cp_build_addr_expr (depobj, tf_warning_or_error);
12639 274 : if (addr == error_mark_node)
12640 : depobj = error_mark_node;
12641 : else
12642 274 : depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR,
12643 : tf_warning_or_error);
12644 : }
12645 :
12646 283 : c_finish_omp_depobj (loc, depobj, kind, clause);
12647 : }
12648 :
12649 : void
12650 162 : finish_omp_flush (int mo)
12651 : {
12652 162 : tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
12653 162 : releasing_vec vec;
12654 162 : if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST)
12655 : {
12656 54 : fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
12657 54 : vec->quick_push (build_int_cst (integer_type_node, mo));
12658 : }
12659 162 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12660 162 : finish_expr_stmt (stmt);
12661 162 : }
12662 :
12663 : void
12664 111 : finish_omp_taskwait (void)
12665 : {
12666 111 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
12667 111 : releasing_vec vec;
12668 111 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12669 111 : finish_expr_stmt (stmt);
12670 111 : }
12671 :
12672 : void
12673 16 : finish_omp_taskyield (void)
12674 : {
12675 16 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
12676 16 : releasing_vec vec;
12677 16 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12678 16 : finish_expr_stmt (stmt);
12679 16 : }
12680 :
12681 : void
12682 596 : finish_omp_cancel (tree clauses)
12683 : {
12684 596 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
12685 596 : int mask = 0;
12686 596 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12687 : mask = 1;
12688 414 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12689 : mask = 2;
12690 285 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12691 : mask = 4;
12692 164 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12693 : mask = 8;
12694 : else
12695 : {
12696 0 : error ("%<#pragma omp cancel%> must specify one of "
12697 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12698 0 : return;
12699 : }
12700 596 : releasing_vec vec;
12701 596 : tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
12702 596 : if (ifc != NULL_TREE)
12703 : {
12704 70 : if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
12705 70 : && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
12706 6 : error_at (OMP_CLAUSE_LOCATION (ifc),
12707 : "expected %<cancel%> %<if%> clause modifier");
12708 : else
12709 : {
12710 64 : tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
12711 64 : if (ifc2 != NULL_TREE)
12712 : {
12713 3 : gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
12714 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
12715 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
12716 3 : error_at (OMP_CLAUSE_LOCATION (ifc2),
12717 : "expected %<cancel%> %<if%> clause modifier");
12718 : }
12719 : }
12720 :
12721 70 : if (!processing_template_decl)
12722 61 : ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc));
12723 : else
12724 9 : ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
12725 9 : OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK,
12726 : integer_zero_node, ERROR_MARK,
12727 : NULL_TREE, NULL, tf_warning_or_error);
12728 : }
12729 : else
12730 526 : ifc = boolean_true_node;
12731 596 : vec->quick_push (build_int_cst (integer_type_node, mask));
12732 596 : vec->quick_push (ifc);
12733 596 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12734 596 : finish_expr_stmt (stmt);
12735 596 : }
12736 :
12737 : void
12738 494 : finish_omp_cancellation_point (tree clauses)
12739 : {
12740 494 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
12741 494 : int mask = 0;
12742 494 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12743 : mask = 1;
12744 366 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12745 : mask = 2;
12746 261 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12747 : mask = 4;
12748 156 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12749 : mask = 8;
12750 : else
12751 : {
12752 3 : error ("%<#pragma omp cancellation point%> must specify one of "
12753 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12754 3 : return;
12755 : }
12756 491 : releasing_vec vec
12757 491 : = make_tree_vector_single (build_int_cst (integer_type_node, mask));
12758 491 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12759 491 : finish_expr_stmt (stmt);
12760 491 : }
12761 :
12762 : /* Begin a __transaction_atomic or __transaction_relaxed statement.
12763 : If PCOMPOUND is non-null, this is for a function-transaction-block, and we
12764 : should create an extra compound stmt. */
12765 :
12766 : tree
12767 303 : begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
12768 : {
12769 303 : tree r;
12770 :
12771 303 : if (pcompound)
12772 21 : *pcompound = begin_compound_stmt (0);
12773 :
12774 303 : r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
12775 :
12776 : /* Only add the statement to the function if support enabled. */
12777 303 : if (flag_tm)
12778 297 : add_stmt (r);
12779 : else
12780 12 : error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
12781 : ? G_("%<__transaction_relaxed%> without "
12782 : "transactional memory support enabled")
12783 : : G_("%<__transaction_atomic%> without "
12784 : "transactional memory support enabled")));
12785 :
12786 303 : TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
12787 303 : TREE_SIDE_EFFECTS (r) = 1;
12788 303 : return r;
12789 : }
12790 :
12791 : /* End a __transaction_atomic or __transaction_relaxed statement.
12792 : If COMPOUND_STMT is non-null, this is for a function-transaction-block,
12793 : and we should end the compound. If NOEX is non-NULL, we wrap the body in
12794 : a MUST_NOT_THROW_EXPR with NOEX as condition. */
12795 :
12796 : void
12797 303 : finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
12798 : {
12799 303 : TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
12800 303 : TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
12801 303 : TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
12802 303 : TRANSACTION_EXPR_IS_STMT (stmt) = 1;
12803 :
12804 : /* noexcept specifications are not allowed for function transactions. */
12805 303 : gcc_assert (!(noex && compound_stmt));
12806 303 : if (noex)
12807 : {
12808 51 : tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
12809 : noex);
12810 51 : protected_set_expr_location
12811 51 : (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
12812 51 : TREE_SIDE_EFFECTS (body) = 1;
12813 51 : TRANSACTION_EXPR_BODY (stmt) = body;
12814 : }
12815 :
12816 303 : if (compound_stmt)
12817 21 : finish_compound_stmt (compound_stmt);
12818 303 : }
12819 :
12820 : /* Build a __transaction_atomic or __transaction_relaxed expression. If
12821 : NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
12822 : condition. */
12823 :
12824 : tree
12825 116 : build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
12826 : {
12827 116 : tree ret;
12828 116 : if (noex)
12829 : {
12830 57 : expr = build_must_not_throw_expr (expr, noex);
12831 57 : protected_set_expr_location (expr, loc);
12832 57 : TREE_SIDE_EFFECTS (expr) = 1;
12833 : }
12834 116 : ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
12835 116 : if (flags & TM_STMT_ATTR_RELAXED)
12836 4 : TRANSACTION_EXPR_RELAXED (ret) = 1;
12837 116 : TREE_SIDE_EFFECTS (ret) = 1;
12838 116 : SET_EXPR_LOCATION (ret, loc);
12839 116 : return ret;
12840 : }
12841 :
12842 : void
12843 102142 : init_cp_semantics (void)
12844 : {
12845 102142 : }
12846 :
12847 :
12848 : /* Get constant string at LOCATION. Returns true if successful,
12849 : otherwise false. */
12850 :
12851 : bool
12852 11248228 : cexpr_str::type_check (location_t location, bool allow_char8_t /*=false*/)
12853 : {
12854 11248228 : tsubst_flags_t complain = tf_warning_or_error;
12855 :
12856 11248228 : if (message == NULL_TREE
12857 11248228 : || message == error_mark_node
12858 22496453 : || check_for_bare_parameter_packs (message))
12859 3 : return false;
12860 :
12861 11248225 : if (TREE_CODE (message) != STRING_CST
12862 11248225 : && !type_dependent_expression_p (message))
12863 : {
12864 1053 : message_sz
12865 1053 : = finish_class_member_access_expr (message,
12866 : get_identifier ("size"),
12867 : false, complain);
12868 1053 : if (message_sz != error_mark_node)
12869 952 : message_data
12870 952 : = finish_class_member_access_expr (message,
12871 : get_identifier ("data"),
12872 : false, complain);
12873 1053 : if (message_sz == error_mark_node || message_data == error_mark_node)
12874 : {
12875 139 : error_at (location, "constexpr string must be a string "
12876 : "literal or object with %<size%> and "
12877 : "%<data%> members");
12878 322 : return false;
12879 : }
12880 914 : releasing_vec size_args, data_args;
12881 914 : message_sz = finish_call_expr (message_sz, &size_args, false, false,
12882 : complain);
12883 914 : message_data = finish_call_expr (message_data, &data_args, false, false,
12884 : complain);
12885 914 : if (message_sz == error_mark_node || message_data == error_mark_node)
12886 : return false;
12887 800 : message_sz = build_converted_constant_expr (size_type_node, message_sz,
12888 : complain);
12889 800 : if (message_sz == error_mark_node)
12890 : {
12891 15 : error_at (location, "constexpr string %<size()%> "
12892 : "must be implicitly convertible to "
12893 : "%<std::size_t%>");
12894 15 : return false;
12895 : }
12896 :
12897 785 : if (allow_char8_t
12898 74 : && POINTER_TYPE_P (TREE_TYPE (message_data))
12899 74 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
12900 74 : == char8_type_node)
12901 805 : && (TYPE_QUALS (TREE_TYPE (TREE_TYPE (message_data)))
12902 : == TYPE_QUAL_CONST))
12903 : return true;
12904 :
12905 765 : message_data = build_converted_constant_expr (const_string_type_node,
12906 : message_data, complain);
12907 765 : if (message_data == error_mark_node)
12908 : {
12909 34 : error_at (location, "constexpr string %<data()%> "
12910 : "must be implicitly convertible to "
12911 : "%<const char*%>");
12912 34 : return false;
12913 : }
12914 914 : }
12915 : return true;
12916 : }
12917 :
12918 : /* Extract constant string at LOCATON into output string STR.
12919 : Returns true if successful, otherwise false. */
12920 :
12921 : bool
12922 405 : cexpr_str::extract (location_t location, tree &str)
12923 : {
12924 405 : const char *msg;
12925 405 : int len;
12926 405 : if (!extract (location, msg, len))
12927 : return false;
12928 343 : str = build_string (len, msg);
12929 343 : return true;
12930 : }
12931 :
12932 : /* Extract constant string at LOCATION into output string MSG with LEN.
12933 : Returns true if successful, otherwise false. */
12934 :
12935 : bool
12936 2694 : cexpr_str::extract (location_t location, const char * &msg, int &len,
12937 : const constexpr_ctx *ctx /* = NULL */,
12938 : bool *non_constant_p /* = NULL */,
12939 : bool *overflow_p /* = NULL */,
12940 : tree *jump_target /* = NULL */)
12941 : {
12942 2694 : tsubst_flags_t complain = tf_warning_or_error;
12943 :
12944 2694 : msg = NULL;
12945 2694 : if (message_sz && message_data)
12946 : {
12947 677 : tree msz;
12948 677 : if (ctx)
12949 : {
12950 110 : msz = cxx_eval_constant_expression (ctx, message_sz, vc_prvalue,
12951 : non_constant_p, overflow_p,
12952 : jump_target);
12953 110 : if (*jump_target || *non_constant_p)
12954 : return false;
12955 : }
12956 : else
12957 567 : msz = cxx_constant_value (message_sz, NULL_TREE, complain);
12958 669 : if (!tree_fits_uhwi_p (msz))
12959 : {
12960 35 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12961 35 : error_at (location,
12962 : "constexpr string %<size()%> "
12963 : "must be a constant expression");
12964 35 : return false;
12965 : }
12966 634 : else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
12967 : != tree_to_uhwi (msz))
12968 : {
12969 0 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
12970 0 : error_at (location,
12971 : "constexpr string message %<size()%> "
12972 : "%qE too large", msz);
12973 0 : return false;
12974 : }
12975 634 : len = tree_to_uhwi (msz);
12976 634 : tree data;
12977 634 : if (ctx)
12978 : {
12979 102 : data = cxx_eval_constant_expression (ctx, message_data, vc_prvalue,
12980 : non_constant_p, overflow_p,
12981 : jump_target);
12982 102 : if (*jump_target || *non_constant_p)
12983 : return false;
12984 94 : STRIP_NOPS (data);
12985 94 : if (TREE_CODE (data) != ADDR_EXPR)
12986 : {
12987 0 : unhandled:
12988 0 : if (!cxx_constexpr_quiet_p (ctx))
12989 0 : error_at (location, "unhandled return from %<data()%>");
12990 0 : return false;
12991 : }
12992 94 : tree str = TREE_OPERAND (data, 0);
12993 94 : unsigned HOST_WIDE_INT off = 0;
12994 94 : if (TREE_CODE (str) == ARRAY_REF
12995 94 : && tree_fits_uhwi_p (TREE_OPERAND (str, 1)))
12996 : {
12997 12 : off = tree_to_uhwi (TREE_OPERAND (str, 1));
12998 12 : str = TREE_OPERAND (str, 0);
12999 : }
13000 94 : str = cxx_eval_constant_expression (ctx, str, vc_prvalue,
13001 : non_constant_p, overflow_p,
13002 : jump_target);
13003 94 : if (*jump_target || *non_constant_p)
13004 : return false;
13005 94 : if (TREE_CODE (str) == STRING_CST)
13006 : {
13007 84 : if (TREE_STRING_LENGTH (str) < len
13008 84 : || (unsigned) TREE_STRING_LENGTH (str) < off
13009 168 : || (unsigned) TREE_STRING_LENGTH (str) < off + len)
13010 0 : goto unhandled;
13011 84 : msg = TREE_STRING_POINTER (str) + off;
13012 84 : goto translate;
13013 : }
13014 10 : if (TREE_CODE (str) != CONSTRUCTOR
13015 10 : || TREE_CODE (TREE_TYPE (str)) != ARRAY_TYPE)
13016 0 : goto unhandled;
13017 10 : char *b;
13018 10 : if (len < 64)
13019 10 : b = XALLOCAVEC (char, len + 1);
13020 : else
13021 : {
13022 0 : buf = XNEWVEC (char, len + 1);
13023 0 : b = buf;
13024 : }
13025 10 : msg = b;
13026 10 : memset (b, 0, len + 1);
13027 10 : tree field, value;
13028 10 : unsigned k;
13029 10 : unsigned HOST_WIDE_INT l = 0;
13030 158 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (str), k, field, value)
13031 158 : if (!tree_fits_shwi_p (value))
13032 0 : goto unhandled;
13033 158 : else if (field == NULL_TREE)
13034 : {
13035 0 : if (integer_zerop (value))
13036 : break;
13037 0 : if (l >= off && l < off + len)
13038 0 : b[l - off] = tree_to_shwi (value);
13039 0 : ++l;
13040 : }
13041 158 : else if (TREE_CODE (field) == RANGE_EXPR)
13042 : {
13043 0 : tree lo = TREE_OPERAND (field, 0);
13044 0 : tree hi = TREE_OPERAND (field, 1);
13045 0 : if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
13046 0 : goto unhandled;
13047 0 : if (integer_zerop (value))
13048 : break;
13049 0 : unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
13050 0 : for (l = tree_to_uhwi (lo); l <= m; ++l)
13051 0 : if (l >= off && l < off + len)
13052 0 : b[l - off] = tree_to_shwi (value);
13053 : }
13054 158 : else if (tree_fits_uhwi_p (field))
13055 : {
13056 158 : l = tree_to_uhwi (field);
13057 158 : if (integer_zerop (value))
13058 : break;
13059 148 : if (l >= off && l < off + len)
13060 148 : b[l - off] = tree_to_shwi (value);
13061 148 : l++;
13062 : }
13063 10 : b[len] = '\0';
13064 : }
13065 : else
13066 : {
13067 532 : data = maybe_constant_value (message_data, NULL_TREE, mce_true);
13068 532 : if (!reduced_constant_expression_p (data))
13069 96 : data = NULL_TREE;
13070 532 : if (len)
13071 : {
13072 455 : if (data)
13073 381 : msg = c_getstr (data);
13074 455 : if (msg == NULL)
13075 119 : buf = XNEWVEC (char, len);
13076 1458 : for (int i = 0; i < len; ++i)
13077 : {
13078 1033 : tree t = message_data;
13079 1033 : if (i)
13080 1156 : t = build2 (POINTER_PLUS_EXPR,
13081 578 : TREE_TYPE (message_data), message_data,
13082 578 : size_int (i));
13083 1033 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
13084 1033 : tree t2 = cxx_constant_value (t, NULL_TREE, complain);
13085 1033 : if (!tree_fits_shwi_p (t2))
13086 : {
13087 30 : error_at (location,
13088 : "constexpr string %<data()[%d]%> "
13089 : "must be a constant expression", i);
13090 30 : return false;
13091 : }
13092 1003 : if (msg == NULL)
13093 362 : buf[i] = tree_to_shwi (t2);
13094 : /* If c_getstr worked, just verify the first and
13095 : last characters using constant evaluation. */
13096 641 : else if (len > 2 && i == 0)
13097 268 : i = len - 2;
13098 : }
13099 425 : if (msg == NULL)
13100 104 : msg = buf;
13101 : }
13102 77 : else if (!data)
13103 : {
13104 : /* We don't have any function to test whether some
13105 : expression is a core constant expression. So, instead
13106 : test whether (message.data (), 0) is a constant
13107 : expression. */
13108 22 : data = build2 (COMPOUND_EXPR, integer_type_node,
13109 : message_data, integer_zero_node);
13110 22 : tree t = cxx_constant_value (data, NULL_TREE, complain);
13111 22 : if (!integer_zerop (t))
13112 : {
13113 22 : error_at (location,
13114 : "constexpr string %<data()%> "
13115 : "must be a core constant expression");
13116 22 : return false;
13117 : }
13118 : }
13119 : }
13120 : }
13121 : else
13122 : {
13123 2017 : tree eltype = TREE_TYPE (TREE_TYPE (message));
13124 2017 : int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
13125 2017 : msg = TREE_STRING_POINTER (message);
13126 2017 : len = TREE_STRING_LENGTH (message) / sz - 1;
13127 : }
13128 2591 : translate:
13129 2591 : if ((message_sz && message_data) || ctx)
13130 : {
13131 : /* Convert the string from execution charset to SOURCE_CHARSET. */
13132 768 : cpp_string istr, ostr;
13133 768 : istr.len = len;
13134 768 : istr.text = (const unsigned char *) msg;
13135 768 : enum cpp_ttype type = CPP_STRING;
13136 768 : if (message_sz && message_data)
13137 : {
13138 574 : if (POINTER_TYPE_P (TREE_TYPE (message_data))
13139 574 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
13140 574 : == char8_type_node))
13141 : type = CPP_UTF8STRING;
13142 : }
13143 194 : else if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message)))
13144 194 : == char8_type_node)
13145 768 : type = CPP_UTF8STRING;
13146 768 : if (len == 0)
13147 : ;
13148 643 : else if (!cpp_translate_string (parse_in, &istr, &ostr, type,
13149 : true))
13150 : {
13151 0 : if (type == CPP_UTF8STRING)
13152 0 : error_at (location, "could not convert constexpr string from "
13153 : "UTF-8 encoding to source character "
13154 : "set");
13155 : else
13156 0 : error_at (location, "could not convert constexpr string from "
13157 : "ordinary literal encoding to source character "
13158 : "set");
13159 0 : return false;
13160 : }
13161 : else
13162 : {
13163 643 : if (buf)
13164 104 : XDELETEVEC (buf);
13165 643 : msg = buf = const_cast <char *> ((const char *) ostr.text);
13166 643 : len = ostr.len;
13167 : }
13168 : }
13169 :
13170 : return true;
13171 : }
13172 :
13173 : /* Build a STATIC_ASSERT for a static assertion with the condition
13174 : CONDITION and the message text MESSAGE. LOCATION is the location
13175 : of the static assertion in the source code. When MEMBER_P, this
13176 : static assertion is a member of a class. If SHOW_EXPR_P is true,
13177 : print the condition (because it was instantiation-dependent).
13178 : If CONSTEVAL_BLOCK_P is true, this static assertion represents
13179 : a consteval block. */
13180 :
13181 : void
13182 11247537 : finish_static_assert (tree condition, tree message, location_t location,
13183 : bool member_p, bool show_expr_p,
13184 : bool consteval_block_p/*=false*/)
13185 : {
13186 11247537 : tsubst_flags_t complain = tf_warning_or_error;
13187 :
13188 11247537 : if (condition == NULL_TREE
13189 11247537 : || condition == error_mark_node)
13190 4761906 : return;
13191 :
13192 11247311 : if (check_for_bare_parameter_packs (condition))
13193 : return;
13194 :
13195 11247308 : cexpr_str cstr(message);
13196 11247308 : if (!cstr.type_check (location))
13197 : return;
13198 :
13199 : /* Save the condition in case it was a concept check. */
13200 11247214 : tree orig_condition = condition;
13201 :
13202 11247214 : if (instantiation_dependent_expression_p (condition)
13203 11247214 : || instantiation_dependent_expression_p (message))
13204 : {
13205 : /* We're in a template; build a STATIC_ASSERT and put it in
13206 : the right place. */
13207 4761062 : defer:
13208 4761062 : tree assertion = make_node (STATIC_ASSERT);
13209 4761062 : STATIC_ASSERT_CONDITION (assertion) = orig_condition;
13210 4761062 : STATIC_ASSERT_MESSAGE (assertion) = cstr.message;
13211 4761062 : STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
13212 4761062 : CONSTEVAL_BLOCK_P (assertion) = consteval_block_p;
13213 :
13214 4761062 : if (member_p)
13215 2439955 : maybe_add_class_template_decl_list (current_class_type,
13216 : assertion,
13217 : /*friend_p=*/0);
13218 : else
13219 2321107 : add_stmt (assertion);
13220 :
13221 4761062 : return;
13222 : }
13223 :
13224 : /* Evaluate the consteval { }. This must be done only once. */
13225 6492108 : if (consteval_block_p)
13226 : {
13227 496 : cxx_constant_value (condition);
13228 496 : return;
13229 : }
13230 :
13231 : /* Fold the expression and convert it to a boolean value. */
13232 6491612 : condition = contextual_conv_bool (condition, complain);
13233 6491612 : condition = fold_non_dependent_expr (condition, complain,
13234 : /*manifestly_const_eval=*/true);
13235 :
13236 6491610 : if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
13237 : /* Do nothing; the condition is satisfied. */
13238 : ;
13239 : else
13240 : {
13241 8799 : iloc_sentinel ils (location);
13242 :
13243 8799 : if (integer_zerop (condition))
13244 : {
13245 : /* CWG2518: static_assert failure in a template is not IFNDR. */
13246 7941 : if (processing_template_decl)
13247 5956 : goto defer;
13248 :
13249 1985 : int len;
13250 1985 : const char *msg = NULL;
13251 1985 : if (!cstr.extract (location, msg, len))
13252 25 : return;
13253 :
13254 : /* See if we can find which clause was failing (for logical AND). */
13255 1960 : tree bad = find_failing_clause (NULL, orig_condition);
13256 : /* If not, or its location is unusable, fall back to the previous
13257 : location. */
13258 1960 : location_t cloc = cp_expr_loc_or_loc (bad, location);
13259 :
13260 1960 : auto_diagnostic_group d;
13261 :
13262 : /* Report the error. */
13263 1960 : if (len == 0)
13264 1238 : error_at (cloc, "static assertion failed");
13265 : else
13266 722 : error_at (cloc, "static assertion failed: %.*s", len, msg);
13267 :
13268 1960 : diagnose_failing_condition (bad, cloc, show_expr_p);
13269 :
13270 : /* Suppress -Wreturn-type for functions with failed static_asserts.
13271 : Otherwise templates like:
13272 : if constexpr (whatever)
13273 : return something (args);
13274 : else
13275 : static_assert (false, "explanation");
13276 : get a useless extra -Wreturn-type warning. */
13277 1960 : if (current_function_decl)
13278 756 : suppress_warning (current_function_decl, OPT_Wreturn_type);
13279 1960 : }
13280 858 : else if (condition && condition != error_mark_node)
13281 : {
13282 852 : error ("non-constant condition for static assertion");
13283 852 : if (require_rvalue_constant_expression (condition))
13284 790 : cxx_constant_value (condition);
13285 : }
13286 8799 : }
13287 11247306 : }
13288 :
13289 : /* Implements the C++0x decltype keyword. Returns the type of EXPR,
13290 : suitable for use as a type-specifier.
13291 :
13292 : ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
13293 : id-expression or a class member access, FALSE when it was parsed as
13294 : a full expression. */
13295 :
13296 : tree
13297 43276183 : finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
13298 : tsubst_flags_t complain)
13299 : {
13300 43276183 : tree type = NULL_TREE;
13301 :
13302 43276183 : if (!expr || error_operand_p (expr))
13303 239562 : return error_mark_node;
13304 :
13305 43036621 : if (TYPE_P (expr)
13306 43036621 : || TREE_CODE (expr) == TYPE_DECL
13307 86073222 : || (TREE_CODE (expr) == BIT_NOT_EXPR
13308 16093 : && TYPE_P (TREE_OPERAND (expr, 0))))
13309 : {
13310 29 : if (complain & tf_error)
13311 29 : error ("argument to %<decltype%> must be an expression");
13312 29 : return error_mark_node;
13313 : }
13314 :
13315 : /* decltype is an unevaluated context. */
13316 43036592 : cp_unevaluated u;
13317 :
13318 43036592 : processing_template_decl_sentinel ptds (/*reset=*/false);
13319 :
13320 : /* Depending on the resolution of DR 1172, we may later need to distinguish
13321 : instantiation-dependent but not type-dependent expressions so that, say,
13322 : A<decltype(sizeof(T))>::U doesn't require 'typename'. */
13323 43036592 : if (instantiation_dependent_uneval_expression_p (expr))
13324 : {
13325 7271923 : dependent:
13326 7272499 : type = cxx_make_type (DECLTYPE_TYPE);
13327 7272499 : DECLTYPE_TYPE_EXPR (type) = expr;
13328 14544998 : DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
13329 7272499 : = id_expression_or_member_access_p;
13330 7272499 : SET_TYPE_STRUCTURAL_EQUALITY (type);
13331 :
13332 7272499 : return type;
13333 : }
13334 35764669 : else if (processing_template_decl)
13335 : {
13336 7382 : expr = instantiate_non_dependent_expr (expr, complain|tf_decltype);
13337 7382 : if (expr == error_mark_node)
13338 : return error_mark_node;
13339 : /* Keep processing_template_decl cleared for the rest of the function
13340 : (for sake of the call to lvalue_kind below, which handles templated
13341 : and non-templated COND_EXPR differently). */
13342 7345 : processing_template_decl = 0;
13343 : }
13344 :
13345 : /* The type denoted by decltype(e) is defined as follows: */
13346 :
13347 35764632 : expr = resolve_nondeduced_context (expr, complain);
13348 35764632 : if (!mark_single_function (expr, complain))
13349 0 : return error_mark_node;
13350 :
13351 35764632 : if (invalid_nonstatic_memfn_p (input_location, expr, complain))
13352 18 : return error_mark_node;
13353 :
13354 35764614 : if (type_unknown_p (expr))
13355 : {
13356 18 : if (complain & tf_error)
13357 6 : error ("%<decltype%> cannot resolve address of overloaded function");
13358 18 : return error_mark_node;
13359 : }
13360 :
13361 35764596 : if (id_expression_or_member_access_p)
13362 : {
13363 : /* If e is an id-expression or a class member access (5.2.5
13364 : [expr.ref]), decltype(e) is defined as the type of the entity
13365 : named by e. If there is no such entity, or e names a set of
13366 : overloaded functions, the program is ill-formed. */
13367 537660 : if (identifier_p (expr))
13368 0 : expr = lookup_name (expr);
13369 :
13370 : /* If e is a constified expression inside a contract assertion,
13371 : strip the const wrapper. Per P2900R14, "For a function f with the
13372 : return type T , the result name is an lvalue of type const T , decltype(r)
13373 : is T , and decltype((r)) is const T&." */
13374 537660 : expr = strip_contract_const_wrapper (expr);
13375 :
13376 370204 : if (REFERENCE_REF_P (expr)
13377 537665 : || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
13378 : /* This can happen when the expression is, e.g., "a.b". Just
13379 : look at the underlying operand. */
13380 373475 : expr = TREE_OPERAND (expr, 0);
13381 :
13382 537660 : if (TREE_CODE (expr) == OFFSET_REF
13383 537660 : || TREE_CODE (expr) == MEMBER_REF
13384 537660 : || TREE_CODE (expr) == SCOPE_REF)
13385 : /* We're only interested in the field itself. If it is a
13386 : BASELINK, we will need to see through it in the next
13387 : step. */
13388 0 : expr = TREE_OPERAND (expr, 1);
13389 :
13390 537660 : if (BASELINK_P (expr))
13391 : /* See through BASELINK nodes to the underlying function. */
13392 7 : expr = BASELINK_FUNCTIONS (expr);
13393 :
13394 : /* decltype of a decomposition name drops references in the tuple case
13395 : (unlike decltype of a normal variable) and keeps cv-qualifiers from
13396 : the containing object in the other cases (unlike decltype of a member
13397 : access expression). */
13398 537660 : if (DECL_DECOMPOSITION_P (expr))
13399 : {
13400 1449 : if (ptds.saved)
13401 : {
13402 275 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr)
13403 : || (DECL_CONTEXT (expr)
13404 : != current_function_decl));
13405 : /* DECL_HAS_VALUE_EXPR_P is always set if
13406 : processing_template_decl at least for structured bindings
13407 : within the template. If lookup_decomp_type
13408 : returns non-NULL, it is the tuple case. */
13409 275 : if (tree ret = lookup_decomp_type (expr))
13410 : return ret;
13411 191 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
13412 : }
13413 1365 : if (DECL_HAS_VALUE_EXPR_P (expr))
13414 : /* Expr is an array or struct subobject proxy, handle
13415 : bit-fields properly. */
13416 1021 : return unlowered_expr_type (expr);
13417 : else
13418 : /* Expr is a reference variable for the tuple case. */
13419 344 : return lookup_decomp_type (expr);
13420 : }
13421 :
13422 536211 : switch (TREE_CODE (expr))
13423 : {
13424 650 : case FIELD_DECL:
13425 650 : if (DECL_BIT_FIELD_TYPE (expr))
13426 : {
13427 : type = DECL_BIT_FIELD_TYPE (expr);
13428 : break;
13429 : }
13430 : /* Fall through for fields that aren't bitfields. */
13431 140324 : gcc_fallthrough ();
13432 :
13433 140324 : case VAR_DECL:
13434 140324 : if (is_capture_proxy (expr))
13435 : {
13436 99 : if (is_normal_capture_proxy (expr))
13437 : {
13438 21 : expr = DECL_CAPTURED_VARIABLE (expr);
13439 21 : type = TREE_TYPE (expr);
13440 : }
13441 : else
13442 : {
13443 78 : expr = DECL_VALUE_EXPR (expr);
13444 78 : gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
13445 78 : expr = TREE_OPERAND (expr, 1);
13446 78 : type = TREE_TYPE (expr);
13447 : }
13448 : break;
13449 : }
13450 : /* Fall through for variables that aren't capture proxies. */
13451 525172 : gcc_fallthrough ();
13452 :
13453 525172 : case FUNCTION_DECL:
13454 525172 : case CONST_DECL:
13455 525172 : case PARM_DECL:
13456 525172 : case RESULT_DECL:
13457 525172 : case TEMPLATE_PARM_INDEX:
13458 525172 : expr = mark_type_use (expr);
13459 525172 : type = TREE_TYPE (expr);
13460 525172 : if (VAR_P (expr) && DECL_NTTP_OBJECT_P (expr))
13461 : {
13462 : /* decltype of an NTTP object is the type of the template
13463 : parameter, which is the object type modulo cv-quals. */
13464 2643 : int quals = cp_type_quals (type);
13465 2643 : gcc_checking_assert (quals & TYPE_QUAL_CONST);
13466 2643 : type = cv_unqualified (type);
13467 : }
13468 : break;
13469 :
13470 0 : case ERROR_MARK:
13471 0 : type = error_mark_node;
13472 0 : break;
13473 :
13474 3504 : case COMPONENT_REF:
13475 3504 : case COMPOUND_EXPR:
13476 3504 : mark_type_use (expr);
13477 3504 : type = is_bitfield_expr_with_lowered_type (expr);
13478 3504 : if (!type)
13479 3467 : type = TREE_TYPE (TREE_OPERAND (expr, 1));
13480 : break;
13481 :
13482 0 : case BIT_FIELD_REF:
13483 0 : gcc_unreachable ();
13484 :
13485 3489 : case INTEGER_CST:
13486 3489 : case PTRMEM_CST:
13487 : /* We can get here when the id-expression refers to an
13488 : enumerator or non-type template parameter. */
13489 3489 : type = TREE_TYPE (expr);
13490 3489 : break;
13491 :
13492 3947 : default:
13493 : /* Handle instantiated template non-type arguments. */
13494 3947 : type = TREE_TYPE (expr);
13495 3947 : break;
13496 : }
13497 : }
13498 : else
13499 : {
13500 35226936 : tree decl = STRIP_REFERENCE_REF (expr);
13501 35226936 : tree lam = current_lambda_expr ();
13502 35226936 : if (lam && outer_automatic_var_p (decl))
13503 : {
13504 : /* [expr.prim.id.unqual]/3: If naming the entity from outside of an
13505 : unevaluated operand within S would refer to an entity captured by
13506 : copy in some intervening lambda-expression, then let E be the
13507 : innermost such lambda-expression.
13508 :
13509 : If there is such a lambda-expression and if P is in E's function
13510 : parameter scope but not its parameter-declaration-clause, then the
13511 : type of the expression is the type of a class member access
13512 : expression naming the non-static data member that would be declared
13513 : for such a capture in the object parameter of the function call
13514 : operator of E." */
13515 : /* FIXME: This transformation needs to happen for all uses of an outer
13516 : local variable inside decltype, not just decltype((x)) (PR83167).
13517 : And we don't handle nested lambdas properly, where we need to
13518 : consider the outer lambdas as well (PR112926). */
13519 1379 : tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK,
13520 : LOOK_want::HIDDEN_LAMBDA);
13521 :
13522 1379 : if (cap && is_capture_proxy (cap))
13523 467 : type = TREE_TYPE (cap);
13524 912 : else if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_COPY)
13525 : {
13526 738 : type = TREE_TYPE (decl);
13527 738 : if (TYPE_REF_P (type)
13528 738 : && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
13529 36 : type = TREE_TYPE (type);
13530 : }
13531 :
13532 1205 : if (type && !TYPE_REF_P (type))
13533 : {
13534 1121 : int quals;
13535 1121 : if (current_function_decl
13536 2104 : && LAMBDA_FUNCTION_P (current_function_decl)
13537 2104 : && DECL_XOBJ_MEMBER_FUNCTION_P (current_function_decl))
13538 : {
13539 900 : tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl));
13540 900 : if (WILDCARD_TYPE_P (non_reference (obtype)))
13541 : /* We don't know what the eventual obtype quals will be. */
13542 576 : goto dependent;
13543 648 : auto direct_type = [](tree t){
13544 324 : if (INDIRECT_TYPE_P (t))
13545 162 : return TREE_TYPE (t);
13546 : return t;
13547 : };
13548 648 : quals = (cp_type_quals (type)
13549 324 : | cp_type_quals (direct_type (obtype)));
13550 : }
13551 : else
13552 : /* We are in the parameter clause, trailing return type, or
13553 : the requires clause and have no relevant c_f_decl yet. */
13554 349 : quals = (LAMBDA_EXPR_CONST_QUAL_P (lam)
13555 221 : ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
13556 545 : type = cp_build_qualified_type (type, quals);
13557 545 : type = build_reference_type (type);
13558 : }
13559 : }
13560 35225557 : else if (error_operand_p (expr))
13561 0 : type = error_mark_node;
13562 35225557 : else if (expr == current_class_ptr)
13563 : /* If the expression is just "this", we want the
13564 : cv-unqualified pointer for the "this" type. */
13565 0 : type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
13566 :
13567 545 : if (!type)
13568 : {
13569 : /* Otherwise, where T is the type of e, if e is an lvalue,
13570 : decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
13571 35225731 : cp_lvalue_kind clk = lvalue_kind (expr);
13572 35225731 : type = unlowered_expr_type (expr);
13573 35225731 : gcc_assert (!TYPE_REF_P (type));
13574 :
13575 : /* For vector types, pick a non-opaque variant. */
13576 35225731 : if (VECTOR_TYPE_P (type))
13577 4421 : type = strip_typedefs (type);
13578 :
13579 35225731 : if (clk != clk_none && !(clk & clk_class))
13580 8894658 : type = cp_build_reference_type (type, (clk & clk_rvalueref));
13581 : }
13582 : }
13583 :
13584 : return type;
13585 43036592 : }
13586 :
13587 : /* Called from trait_expr_value to evaluate either __has_nothrow_assign or
13588 : __has_nothrow_copy, depending on assign_p. Returns true iff all
13589 : the copy {ctor,assign} fns are nothrow. */
13590 :
13591 : static bool
13592 279 : classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
13593 : {
13594 279 : tree fns = NULL_TREE;
13595 :
13596 279 : if (assign_p || TYPE_HAS_COPY_CTOR (type))
13597 276 : fns = get_class_binding (type, assign_p ? assign_op_identifier
13598 : : ctor_identifier);
13599 :
13600 279 : bool saw_copy = false;
13601 696 : for (ovl_iterator iter (fns); iter; ++iter)
13602 : {
13603 441 : tree fn = *iter;
13604 :
13605 441 : if (copy_fn_p (fn) > 0)
13606 : {
13607 423 : saw_copy = true;
13608 423 : if (!maybe_instantiate_noexcept (fn)
13609 423 : || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
13610 192 : return false;
13611 : }
13612 : }
13613 :
13614 87 : return saw_copy;
13615 : }
13616 :
13617 : /* Return true if BASE is a pointer-interconvertible base of DERIVED. */
13618 :
13619 : bool
13620 183 : pointer_interconvertible_base_of_p (tree base, tree derived,
13621 : bool explain/*=false*/)
13622 : {
13623 183 : if (base == error_mark_node || derived == error_mark_node)
13624 : return false;
13625 :
13626 183 : base = TYPE_MAIN_VARIANT (base);
13627 183 : derived = TYPE_MAIN_VARIANT (derived);
13628 183 : if (!NON_UNION_CLASS_TYPE_P (base))
13629 : {
13630 17 : if (explain)
13631 3 : inform (location_of (base),
13632 : "%qT is not a non-union class type", base);
13633 17 : return false;
13634 : }
13635 166 : if (!NON_UNION_CLASS_TYPE_P (derived))
13636 : {
13637 8 : if (explain)
13638 3 : inform (location_of (derived),
13639 : "%qT is not a non-union class type", derived);
13640 8 : return false;
13641 : }
13642 :
13643 158 : if (same_type_p (base, derived))
13644 : return true;
13645 :
13646 117 : if (!std_layout_type_p (derived))
13647 : {
13648 18 : if (explain)
13649 6 : inform (location_of (derived),
13650 : "%qT is not a standard-layout type", derived);
13651 18 : return false;
13652 : }
13653 :
13654 99 : if (!uniquely_derived_from_p (base, derived))
13655 : {
13656 18 : if (explain)
13657 : {
13658 : /* An ambiguous base should already be impossible due to
13659 : the std_layout_type_p check. */
13660 3 : gcc_checking_assert (!DERIVED_FROM_P (base, derived));
13661 3 : inform (location_of (derived),
13662 : "%qT is not a base of %qT", base, derived);
13663 : }
13664 18 : return false;
13665 : }
13666 :
13667 : return true;
13668 : }
13669 :
13670 : /* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
13671 : return true if MEMBERTYPE is the type of the first non-static data member
13672 : of TYPE or for unions of any members. */
13673 : static bool
13674 637 : first_nonstatic_data_member_p (tree type, tree membertype)
13675 : {
13676 1297 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13677 : {
13678 1222 : if (TREE_CODE (field) != FIELD_DECL)
13679 135 : continue;
13680 1087 : if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
13681 60 : continue;
13682 1027 : if (DECL_FIELD_IS_BASE (field))
13683 45 : return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
13684 982 : if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13685 : {
13686 216 : if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
13687 138 : || std_layout_type_p (TREE_TYPE (field)))
13688 294 : && first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
13689 : return true;
13690 : }
13691 766 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13692 : membertype))
13693 : return true;
13694 537 : if (TREE_CODE (type) != UNION_TYPE)
13695 : return false;
13696 : }
13697 : return false;
13698 : }
13699 :
13700 : /* Fold __builtin_is_pointer_interconvertible_with_class call. */
13701 :
13702 : tree
13703 536 : fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
13704 : tree *args)
13705 : {
13706 : /* Unless users call the builtin directly, the following 3 checks should be
13707 : ensured from std::is_pointer_interconvertible_with_class function
13708 : template. */
13709 536 : if (nargs != 1)
13710 : {
13711 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13712 : "needs a single argument");
13713 6 : return boolean_false_node;
13714 : }
13715 530 : tree arg = args[0];
13716 530 : if (error_operand_p (arg))
13717 0 : return boolean_false_node;
13718 530 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
13719 : {
13720 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13721 : "argument is not pointer to member");
13722 6 : return boolean_false_node;
13723 : }
13724 :
13725 524 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
13726 18 : return boolean_false_node;
13727 :
13728 506 : tree membertype = TREE_TYPE (TREE_TYPE (arg));
13729 506 : tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
13730 506 : if (!complete_type_or_else (basetype, NULL_TREE))
13731 3 : return boolean_false_node;
13732 :
13733 503 : if (TREE_CODE (basetype) != UNION_TYPE
13734 503 : && !std_layout_type_p (basetype))
13735 22 : return boolean_false_node;
13736 :
13737 481 : if (!first_nonstatic_data_member_p (basetype, membertype))
13738 132 : return boolean_false_node;
13739 :
13740 349 : if (TREE_CODE (arg) == PTRMEM_CST)
13741 68 : arg = cplus_expand_constant (arg);
13742 :
13743 349 : if (integer_nonzerop (arg))
13744 10 : return boolean_false_node;
13745 339 : if (integer_zerop (arg))
13746 71 : return boolean_true_node;
13747 :
13748 268 : return fold_build2 (EQ_EXPR, boolean_type_node, arg,
13749 : build_zero_cst (TREE_TYPE (arg)));
13750 : }
13751 :
13752 : /* Helper function for is_corresponding_member_aggr. Return true if
13753 : MEMBERTYPE pointer-to-data-member ARG can be found in anonymous
13754 : union or structure BASETYPE. */
13755 :
13756 : static bool
13757 90 : is_corresponding_member_union (tree basetype, tree membertype, tree arg)
13758 : {
13759 222 : for (tree field = TYPE_FIELDS (basetype); field; field = DECL_CHAIN (field))
13760 192 : if (TREE_CODE (field) != FIELD_DECL || DECL_BIT_FIELD_TYPE (field))
13761 36 : continue;
13762 156 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13763 : membertype))
13764 : {
13765 48 : if (TREE_CODE (arg) != INTEGER_CST
13766 48 : || tree_int_cst_equal (arg, byte_position (field)))
13767 48 : return true;
13768 : }
13769 108 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13770 : {
13771 18 : tree narg = arg;
13772 18 : if (TREE_CODE (basetype) != UNION_TYPE
13773 0 : && TREE_CODE (narg) == INTEGER_CST)
13774 0 : narg = size_binop (MINUS_EXPR, arg, byte_position (field));
13775 18 : if (is_corresponding_member_union (TREE_TYPE (field),
13776 : membertype, narg))
13777 : return true;
13778 : }
13779 : return false;
13780 : }
13781 :
13782 : /* Helper function for fold_builtin_is_corresponding_member call.
13783 : Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and
13784 : MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members,
13785 : boolean_true_node if they are corresponding members, or for
13786 : non-constant ARG2 the highest member offset for corresponding
13787 : members. */
13788 :
13789 : static tree
13790 550 : is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
13791 : tree arg1, tree basetype2, tree membertype2,
13792 : tree arg2)
13793 : {
13794 550 : tree field1 = TYPE_FIELDS (basetype1);
13795 550 : tree field2 = TYPE_FIELDS (basetype2);
13796 550 : tree ret = boolean_false_node;
13797 2376 : while (1)
13798 : {
13799 1463 : bool r = next_common_initial_sequence (field1, field2);
13800 1463 : if (field1 == NULL_TREE || field2 == NULL_TREE)
13801 : break;
13802 1331 : if (r
13803 1038 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field1),
13804 : membertype1)
13805 1841 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field2),
13806 : membertype2))
13807 : {
13808 504 : tree pos = byte_position (field1);
13809 504 : if (TREE_CODE (arg1) == INTEGER_CST
13810 504 : && tree_int_cst_equal (arg1, pos))
13811 : {
13812 92 : if (TREE_CODE (arg2) == INTEGER_CST)
13813 92 : return boolean_true_node;
13814 : return pos;
13815 : }
13816 412 : else if (TREE_CODE (arg1) != INTEGER_CST)
13817 1188 : ret = pos;
13818 : }
13819 1654 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field1))
13820 944 : && ANON_AGGR_TYPE_P (TREE_TYPE (field2)))
13821 : {
13822 117 : if ((!lookup_attribute ("no_unique_address",
13823 117 : DECL_ATTRIBUTES (field1)))
13824 117 : != !lookup_attribute ("no_unique_address",
13825 117 : DECL_ATTRIBUTES (field2)))
13826 : break;
13827 117 : if (!tree_int_cst_equal (bit_position (field1),
13828 117 : bit_position (field2)))
13829 : break;
13830 99 : bool overlap = true;
13831 99 : tree pos = byte_position (field1);
13832 99 : if (TREE_CODE (arg1) == INTEGER_CST)
13833 : {
13834 27 : tree off1 = fold_convert (sizetype, arg1);
13835 27 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (field1));
13836 27 : if (tree_int_cst_lt (off1, pos)
13837 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz1), off1))
13838 : overlap = false;
13839 : }
13840 99 : if (TREE_CODE (arg2) == INTEGER_CST)
13841 : {
13842 27 : tree off2 = fold_convert (sizetype, arg2);
13843 27 : tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (field2));
13844 27 : if (tree_int_cst_lt (off2, pos)
13845 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz2), off2))
13846 : overlap = false;
13847 : }
13848 87 : if (overlap
13849 87 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field1))
13850 126 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field2)))
13851 : {
13852 39 : tree narg1 = arg1;
13853 39 : if (TREE_CODE (arg1) == INTEGER_CST)
13854 9 : narg1 = size_binop (MINUS_EXPR,
13855 : fold_convert (sizetype, arg1), pos);
13856 39 : tree narg2 = arg2;
13857 39 : if (TREE_CODE (arg2) == INTEGER_CST)
13858 9 : narg2 = size_binop (MINUS_EXPR,
13859 : fold_convert (sizetype, arg2), pos);
13860 39 : tree t1 = TREE_TYPE (field1);
13861 39 : tree t2 = TREE_TYPE (field2);
13862 39 : tree nret = is_corresponding_member_aggr (loc, t1, membertype1,
13863 : narg1, t2, membertype2,
13864 : narg2);
13865 39 : if (nret != boolean_false_node)
13866 : {
13867 39 : if (nret == boolean_true_node)
13868 : return nret;
13869 30 : if (TREE_CODE (arg1) == INTEGER_CST)
13870 0 : return size_binop (PLUS_EXPR, nret, pos);
13871 30 : ret = size_binop (PLUS_EXPR, nret, pos);
13872 : }
13873 : }
13874 60 : else if (overlap
13875 48 : && TREE_CODE (TREE_TYPE (field1)) == UNION_TYPE
13876 108 : && TREE_CODE (TREE_TYPE (field2)) == UNION_TYPE)
13877 : {
13878 48 : tree narg1 = arg1;
13879 48 : if (TREE_CODE (arg1) == INTEGER_CST)
13880 6 : narg1 = size_binop (MINUS_EXPR,
13881 : fold_convert (sizetype, arg1), pos);
13882 48 : tree narg2 = arg2;
13883 48 : if (TREE_CODE (arg2) == INTEGER_CST)
13884 6 : narg2 = size_binop (MINUS_EXPR,
13885 : fold_convert (sizetype, arg2), pos);
13886 48 : if (is_corresponding_member_union (TREE_TYPE (field1),
13887 : membertype1, narg1)
13888 48 : && is_corresponding_member_union (TREE_TYPE (field2),
13889 : membertype2, narg2))
13890 : {
13891 24 : sorry_at (loc, "%<__builtin_is_corresponding_member%> "
13892 : "not well defined for anonymous unions");
13893 24 : return boolean_false_node;
13894 : }
13895 : }
13896 : }
13897 1188 : if (!r)
13898 : break;
13899 913 : field1 = DECL_CHAIN (field1);
13900 913 : field2 = DECL_CHAIN (field2);
13901 913 : }
13902 : return ret;
13903 : }
13904 :
13905 : /* Fold __builtin_is_corresponding_member call. */
13906 :
13907 : tree
13908 699 : fold_builtin_is_corresponding_member (location_t loc, int nargs,
13909 : tree *args)
13910 : {
13911 : /* Unless users call the builtin directly, the following 3 checks should be
13912 : ensured from std::is_corresponding_member function template. */
13913 699 : if (nargs != 2)
13914 : {
13915 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13916 : "needs two arguments");
13917 9 : return boolean_false_node;
13918 : }
13919 690 : tree arg1 = args[0];
13920 690 : tree arg2 = args[1];
13921 690 : if (error_operand_p (arg1) || error_operand_p (arg2))
13922 0 : return boolean_false_node;
13923 711 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg1))
13924 705 : || !TYPE_PTRMEM_P (TREE_TYPE (arg2)))
13925 : {
13926 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
13927 : "argument is not pointer to member");
13928 9 : return boolean_false_node;
13929 : }
13930 :
13931 681 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg1))
13932 681 : || !TYPE_PTRDATAMEM_P (TREE_TYPE (arg2)))
13933 15 : return boolean_false_node;
13934 :
13935 666 : tree membertype1 = TREE_TYPE (TREE_TYPE (arg1));
13936 666 : tree basetype1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg1));
13937 666 : if (!complete_type_or_else (basetype1, NULL_TREE))
13938 12 : return boolean_false_node;
13939 :
13940 654 : tree membertype2 = TREE_TYPE (TREE_TYPE (arg2));
13941 654 : tree basetype2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg2));
13942 654 : if (!complete_type_or_else (basetype2, NULL_TREE))
13943 12 : return boolean_false_node;
13944 :
13945 627 : if (!NON_UNION_CLASS_TYPE_P (basetype1)
13946 627 : || !NON_UNION_CLASS_TYPE_P (basetype2)
13947 627 : || !std_layout_type_p (basetype1)
13948 1233 : || !std_layout_type_p (basetype2))
13949 51 : return boolean_false_node;
13950 :
13951 : /* If the member types aren't layout compatible, then they
13952 : can't be corresponding members. */
13953 591 : if (!layout_compatible_type_p (membertype1, membertype2))
13954 18 : return boolean_false_node;
13955 :
13956 573 : if (TREE_CODE (arg1) == PTRMEM_CST)
13957 176 : arg1 = cplus_expand_constant (arg1);
13958 573 : if (TREE_CODE (arg2) == PTRMEM_CST)
13959 182 : arg2 = cplus_expand_constant (arg2);
13960 :
13961 573 : if (null_member_pointer_value_p (arg1)
13962 573 : || null_member_pointer_value_p (arg2))
13963 9 : return boolean_false_node;
13964 :
13965 564 : if (TREE_CODE (arg1) == INTEGER_CST
13966 182 : && TREE_CODE (arg2) == INTEGER_CST
13967 746 : && !tree_int_cst_equal (arg1, arg2))
13968 53 : return boolean_false_node;
13969 :
13970 511 : if (TREE_CODE (arg2) == INTEGER_CST
13971 129 : && TREE_CODE (arg1) != INTEGER_CST)
13972 : {
13973 : std::swap (arg1, arg2);
13974 : std::swap (membertype1, membertype2);
13975 : std::swap (basetype1, basetype2);
13976 : }
13977 :
13978 511 : tree ret = is_corresponding_member_aggr (loc, basetype1, membertype1, arg1,
13979 : basetype2, membertype2, arg2);
13980 511 : if (TREE_TYPE (ret) == boolean_type_node)
13981 : return ret;
13982 : /* If both arg1 and arg2 are INTEGER_CSTs, is_corresponding_member_aggr
13983 : already returns boolean_{true,false}_node whether those particular
13984 : members are corresponding members or not. Otherwise, if only
13985 : one of them is INTEGER_CST (canonicalized to first being INTEGER_CST
13986 : above), it returns boolean_false_node if it is certainly not a
13987 : corresponding member and otherwise we need to do a runtime check that
13988 : those two OFFSET_TYPE offsets are equal.
13989 : If neither of the operands is INTEGER_CST, is_corresponding_member_aggr
13990 : returns the largest offset at which the members would be corresponding
13991 : members, so perform arg1 <= ret && arg1 == arg2 runtime check. */
13992 304 : gcc_assert (TREE_CODE (arg2) != INTEGER_CST);
13993 304 : if (TREE_CODE (arg1) == INTEGER_CST)
13994 0 : return fold_build2 (EQ_EXPR, boolean_type_node, arg1,
13995 : fold_convert (TREE_TYPE (arg1), arg2));
13996 304 : ret = fold_build2 (LE_EXPR, boolean_type_node,
13997 : fold_convert (pointer_sized_int_node, arg1),
13998 : fold_convert (pointer_sized_int_node, ret));
13999 304 : return fold_build2 (TRUTH_AND_EXPR, boolean_type_node, ret,
14000 : fold_build2 (EQ_EXPR, boolean_type_node, arg1,
14001 : fold_convert (TREE_TYPE (arg1), arg2)));
14002 : }
14003 :
14004 : /* Fold __builtin_is_string_literal call. */
14005 :
14006 : tree
14007 4206 : fold_builtin_is_string_literal (location_t loc, int nargs, tree *args)
14008 : {
14009 : /* Unless users call the builtin directly, the following 3 checks should be
14010 : ensured from std::is_string_literal overloads. */
14011 4206 : if (nargs != 1)
14012 : {
14013 0 : error_at (loc, "%<__builtin_is_string_literal%> needs a single "
14014 : "argument");
14015 0 : return boolean_false_node;
14016 : }
14017 4206 : tree arg = args[0];
14018 4206 : if (error_operand_p (arg))
14019 0 : return boolean_false_node;
14020 4206 : if (!TYPE_PTR_P (TREE_TYPE (arg))
14021 4206 : || !TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg)))
14022 8412 : || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (arg))))
14023 : {
14024 0 : arg_invalid:
14025 0 : error_at (loc, "%<__builtin_is_string_literal%> "
14026 : "argument is not %<const char*%>, %<const wchar_t*%>, "
14027 : "%<const char8_t*%>, %<const char16_t*%> or "
14028 : "%<const char32_t*%>");
14029 0 : return boolean_false_node;
14030 : }
14031 4206 : tree chart = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg)));
14032 4206 : if (chart != char_type_node
14033 3360 : && chart != wchar_type_node
14034 2520 : && chart != char8_type_node
14035 1680 : && chart != char16_type_node
14036 840 : && chart != char32_type_node)
14037 0 : goto arg_invalid;
14038 :
14039 4206 : STRIP_NOPS (arg);
14040 8424 : while (TREE_CODE (arg) == POINTER_PLUS_EXPR)
14041 : {
14042 12 : arg = TREE_OPERAND (arg, 0);
14043 12 : STRIP_NOPS (arg);
14044 : }
14045 4206 : if (TREE_CODE (arg) != ADDR_EXPR)
14046 4150 : return boolean_false_node;
14047 56 : arg = TREE_OPERAND (arg, 0);
14048 56 : if (TREE_CODE (arg) == ARRAY_REF)
14049 24 : arg = TREE_OPERAND (arg, 0);
14050 56 : if (TREE_CODE (arg) != STRING_CST)
14051 16 : return boolean_false_node;
14052 40 : return boolean_true_node;
14053 : }
14054 :
14055 : /* [basic.types] 8. True iff TYPE is an object type. */
14056 :
14057 : static bool
14058 2905753 : object_type_p (const_tree type)
14059 : {
14060 2905753 : return (TREE_CODE (type) != FUNCTION_TYPE
14061 0 : && !TYPE_REF_P (type)
14062 2905753 : && !VOID_TYPE_P (type));
14063 : }
14064 :
14065 : /* [defns.referenceable] True iff TYPE is a referenceable type. */
14066 :
14067 : static bool
14068 3543036 : referenceable_type_p (const_tree type)
14069 : {
14070 3543036 : return (TYPE_REF_P (type)
14071 3543492 : || object_type_p (type)
14072 3543492 : || (FUNC_OR_METHOD_TYPE_P (type)
14073 385 : && type_memfn_quals (type) == TYPE_UNQUALIFIED
14074 319 : && type_memfn_rqual (type) == REF_QUAL_NONE));
14075 : }
14076 :
14077 : /* Actually evaluates the trait. */
14078 :
14079 : static bool
14080 17969294 : trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
14081 : {
14082 17969294 : enum tree_code type_code1;
14083 17969294 : tree t;
14084 :
14085 17969294 : type_code1 = TREE_CODE (type1);
14086 :
14087 17969294 : switch (kind)
14088 : {
14089 317 : case CPTK_HAS_NOTHROW_ASSIGN:
14090 317 : type1 = strip_array_types (type1);
14091 601 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
14092 601 : && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
14093 173 : || (CLASS_TYPE_P (type1)
14094 129 : && classtype_has_nothrow_assign_or_copy_p (type1,
14095 : true))));
14096 :
14097 215 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14098 215 : type1 = strip_array_types (type1);
14099 215 : return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
14100 215 : || (CLASS_TYPE_P (type1)
14101 93 : && (t = locate_ctor (type1))
14102 60 : && maybe_instantiate_noexcept (t)
14103 58 : && TYPE_NOTHROW_P (TREE_TYPE (t))));
14104 :
14105 305 : case CPTK_HAS_NOTHROW_COPY:
14106 305 : type1 = strip_array_types (type1);
14107 305 : return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
14108 305 : || (CLASS_TYPE_P (type1)
14109 150 : && classtype_has_nothrow_assign_or_copy_p (type1, false)));
14110 :
14111 517 : case CPTK_HAS_TRIVIAL_ASSIGN:
14112 : /* ??? The standard seems to be missing the "or array of such a class
14113 : type" wording for this trait. */
14114 517 : type1 = strip_array_types (type1);
14115 1016 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
14116 1001 : && (trivial_type_p (type1)
14117 307 : || (CLASS_TYPE_P (type1)
14118 222 : && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
14119 :
14120 545 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14121 545 : type1 = strip_array_types (type1);
14122 545 : return (trivial_type_p (type1)
14123 545 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
14124 :
14125 526 : case CPTK_HAS_TRIVIAL_COPY:
14126 : /* ??? The standard seems to be missing the "or array of such a class
14127 : type" wording for this trait. */
14128 526 : type1 = strip_array_types (type1);
14129 878 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14130 863 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
14131 :
14132 763 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14133 763 : type1 = strip_array_types (type1);
14134 763 : if (CLASS_TYPE_P (type1) && type_build_dtor_call (type1))
14135 : {
14136 123 : deferring_access_check_sentinel dacs (dk_no_check);
14137 123 : cp_unevaluated un;
14138 123 : tree fn = get_dtor (type1, tf_none);
14139 123 : if (!fn && !seen_error ())
14140 3 : warning (0, "checking %qs for type %qT with a destructor that "
14141 : "cannot be called", "__has_trivial_destructor", type1);
14142 123 : }
14143 1095 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14144 1092 : || (CLASS_TYPE_P (type1)
14145 285 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
14146 :
14147 60901 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14148 60901 : return type_has_unique_obj_representations (type1);
14149 :
14150 311 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14151 311 : return type_has_virtual_destructor (type1);
14152 :
14153 56208 : case CPTK_IS_ABSTRACT:
14154 56208 : return ABSTRACT_CLASS_TYPE_P (type1);
14155 :
14156 871 : case CPTK_IS_AGGREGATE:
14157 871 : return CP_AGGREGATE_TYPE_P (type1);
14158 :
14159 368121 : case CPTK_IS_ARRAY:
14160 368121 : return (type_code1 == ARRAY_TYPE
14161 : /* We don't want to report T[0] as being an array type.
14162 : This is for compatibility with an implementation of
14163 : std::is_array by template argument deduction, because
14164 : compute_array_index_type_loc rejects a zero-size array
14165 : in SFINAE context. */
14166 368121 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14167 :
14168 1022010 : case CPTK_IS_ASSIGNABLE:
14169 1022010 : return is_xible (MODIFY_EXPR, type1, type2);
14170 :
14171 512357 : case CPTK_IS_BASE_OF:
14172 512266 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14173 1005920 : && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
14174 465684 : || DERIVED_FROM_P (type1, type2)));
14175 :
14176 57926 : case CPTK_IS_BOUNDED_ARRAY:
14177 57926 : return (type_code1 == ARRAY_TYPE
14178 1662 : && TYPE_DOMAIN (type1)
14179 : /* We don't want to report T[0] as being a bounded array type.
14180 : This is for compatibility with an implementation of
14181 : std::is_bounded_array by template argument deduction, because
14182 : compute_array_index_type_loc rejects a zero-size array
14183 : in SFINAE context. */
14184 59460 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14185 :
14186 533834 : case CPTK_IS_CLASS:
14187 533834 : return NON_UNION_CLASS_TYPE_P (type1);
14188 :
14189 584475 : case CPTK_IS_CONST:
14190 584475 : return CP_TYPE_CONST_P (type1);
14191 :
14192 2378610 : case CPTK_IS_CONSTRUCTIBLE:
14193 2378610 : return is_xible (INIT_EXPR, type1, type2);
14194 :
14195 3147768 : case CPTK_IS_CONVERTIBLE:
14196 3147768 : return is_convertible (type1, type2);
14197 :
14198 3311 : case CPTK_IS_DESTRUCTIBLE:
14199 3311 : return is_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14200 :
14201 216590 : case CPTK_IS_EMPTY:
14202 216590 : return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
14203 :
14204 667461 : case CPTK_IS_ENUM:
14205 667461 : return type_code1 == ENUMERAL_TYPE;
14206 :
14207 431230 : case CPTK_IS_FINAL:
14208 431230 : return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
14209 :
14210 47790 : case CPTK_IS_FUNCTION:
14211 47790 : return type_code1 == FUNCTION_TYPE;
14212 :
14213 1247 : case CPTK_IS_IMPLICIT_LIFETIME:
14214 1247 : return implicit_lifetime_type_p (type1);
14215 :
14216 48849 : case CPTK_IS_INVOCABLE:
14217 48849 : return !error_operand_p (build_invoke (type1, type2, tf_none));
14218 :
14219 221 : case CPTK_IS_LAYOUT_COMPATIBLE:
14220 221 : return layout_compatible_type_p (type1, type2);
14221 :
14222 197 : case CPTK_IS_LITERAL_TYPE:
14223 197 : return literal_type_p (type1);
14224 :
14225 48674 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14226 48674 : return TYPE_PTRMEMFUNC_P (type1);
14227 :
14228 48661 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14229 48661 : return TYPE_PTRDATAMEM_P (type1);
14230 :
14231 10924 : case CPTK_IS_MEMBER_POINTER:
14232 10924 : return TYPE_PTRMEM_P (type1);
14233 :
14234 459252 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14235 459252 : return is_nothrow_xible (MODIFY_EXPR, type1, type2);
14236 :
14237 925460 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14238 925460 : return is_nothrow_xible (INIT_EXPR, type1, type2);
14239 :
14240 683 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14241 683 : return is_nothrow_convertible (type1, type2);
14242 :
14243 23990 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14244 23990 : return is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14245 :
14246 43805 : case CPTK_IS_NOTHROW_INVOCABLE:
14247 43805 : return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
14248 :
14249 1122954 : case CPTK_IS_OBJECT:
14250 1122954 : return object_type_p (type1);
14251 :
14252 168 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14253 168 : return pointer_interconvertible_base_of_p (type1, type2);
14254 :
14255 11420 : case CPTK_IS_POD:
14256 11420 : return pod_type_p (type1);
14257 :
14258 151701 : case CPTK_IS_POINTER:
14259 151701 : return TYPE_PTR_P (type1);
14260 :
14261 289 : case CPTK_IS_POLYMORPHIC:
14262 289 : return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
14263 :
14264 711629 : case CPTK_IS_REFERENCE:
14265 711629 : return type_code1 == REFERENCE_TYPE;
14266 :
14267 2658757 : case CPTK_IS_SAME:
14268 2658757 : return same_type_p (type1, type2);
14269 :
14270 373 : case CPTK_IS_SCOPED_ENUM:
14271 373 : return SCOPED_ENUM_P (type1);
14272 :
14273 62781 : case CPTK_IS_STD_LAYOUT:
14274 62781 : return std_layout_type_p (type1);
14275 :
14276 58340 : case CPTK_IS_TRIVIAL:
14277 58340 : return trivial_type_p (type1);
14278 :
14279 12636 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14280 12636 : return is_trivially_xible (MODIFY_EXPR, type1, type2);
14281 :
14282 74693 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14283 74693 : return is_trivially_xible (INIT_EXPR, type1, type2);
14284 :
14285 118304 : case CPTK_IS_TRIVIALLY_COPYABLE:
14286 118304 : return trivially_copyable_p (type1);
14287 :
14288 27160 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14289 27160 : return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14290 :
14291 97528 : case CPTK_IS_UNBOUNDED_ARRAY:
14292 97528 : return array_of_unknown_bound_p (type1);
14293 :
14294 271756 : case CPTK_IS_UNION:
14295 271756 : return type_code1 == UNION_TYPE;
14296 :
14297 751 : case CPTK_IS_VIRTUAL_BASE_OF:
14298 683 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14299 1415 : && lookup_base (type2, type1, ba_require_virtual,
14300 : NULL, tf_none) != NULL_TREE);
14301 :
14302 608626 : case CPTK_IS_VOLATILE:
14303 608626 : return CP_TYPE_VOLATILE_P (type1);
14304 :
14305 220049 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14306 220049 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
14307 :
14308 54105 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14309 54105 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/false);
14310 :
14311 85 : case CPTK_IS_DEDUCIBLE:
14312 85 : return type_targs_deducible_from (type1, type2);
14313 :
14314 264 : case CPTK_IS_STRUCTURAL:
14315 264 : return structural_type_p (type1);
14316 :
14317 : /* __array_rank, __builtin_type_order and __builtin_structured_binding_size
14318 : are handled in finish_trait_expr. */
14319 0 : case CPTK_RANK:
14320 0 : case CPTK_TYPE_ORDER:
14321 0 : case CPTK_STRUCTURED_BINDING_SIZE:
14322 0 : gcc_unreachable ();
14323 :
14324 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14325 : case CPTK_##CODE:
14326 : #include "cp-trait.def"
14327 : #undef DEFTRAIT_TYPE
14328 : /* Type-yielding traits are handled in finish_trait_type. */
14329 : break;
14330 : }
14331 :
14332 0 : gcc_unreachable ();
14333 : }
14334 :
14335 : /* Returns true if TYPE meets the requirements for the specified KIND,
14336 : false otherwise.
14337 :
14338 : When KIND == 1, TYPE must be an array of unknown bound,
14339 : or (possibly cv-qualified) void, or a complete type.
14340 :
14341 : When KIND == 2, TYPE must be a complete type, or array of complete type,
14342 : or (possibly cv-qualified) void.
14343 :
14344 : When KIND == 3:
14345 : If TYPE is a non-union class type, it must be complete.
14346 :
14347 : When KIND == 4:
14348 : If TYPE is a class type, it must be complete.
14349 :
14350 : If COMPLAIN is not tf_none, we permerror and return false if that doesn't
14351 : produce a hard error. */
14352 :
14353 : static bool
14354 18894937 : check_trait_type (tree type, int kind, tsubst_flags_t complain)
14355 : {
14356 18894937 : if (type == NULL_TREE)
14357 : return true;
14358 :
14359 18894937 : if (TREE_CODE (type) == TREE_VEC)
14360 : {
14361 6168228 : for (tree arg : tree_vec_range (type))
14362 2701398 : if (!check_trait_type (arg, kind, complain))
14363 123 : return false;
14364 3466830 : return true;
14365 : }
14366 :
14367 15427984 : if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
14368 : return true; // Array of unknown bound. Don't care about completeness.
14369 :
14370 15427126 : if (kind == 3 && !NON_UNION_CLASS_TYPE_P (type))
14371 : return true; // Not a non-union class type. Don't care about completeness.
14372 :
14373 15312470 : if (kind == 4 && TREE_CODE (type) == ARRAY_TYPE)
14374 : return true; // Not a class type. Don't care about completeness.
14375 :
14376 15311939 : if (VOID_TYPE_P (type))
14377 : return true;
14378 :
14379 15310298 : type = complete_type (strip_array_types (type));
14380 15310298 : if (!COMPLETE_TYPE_P (type)
14381 : /* If we're not emitting error messages, always return false for
14382 : incomplete types. */
14383 15310298 : && (complain == tf_none
14384 181 : || (cxx_incomplete_type_diagnostic (NULL_TREE, type,
14385 : diagnostics::kind::permerror)
14386 181 : && !flag_permissive)))
14387 886 : return false;
14388 : return true;
14389 : }
14390 :
14391 : /* True iff the conversion (if any) would be a direct reference
14392 : binding, not requiring complete types. This is LWG2939. */
14393 :
14394 : static bool
14395 6620386 : same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2)
14396 : {
14397 6620386 : tree from, to;
14398 6620386 : switch (kind)
14399 : {
14400 : /* These put the target type first. */
14401 : case CPTK_IS_CONSTRUCTIBLE:
14402 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14403 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14404 : case CPTK_IS_INVOCABLE:
14405 : case CPTK_IS_NOTHROW_INVOCABLE:
14406 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14407 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14408 : to = type1;
14409 : from = type2;
14410 : break;
14411 :
14412 : /* These put it second. */
14413 3148523 : case CPTK_IS_CONVERTIBLE:
14414 3148523 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14415 3148523 : to = type2;
14416 3148523 : from = type1;
14417 3148523 : break;
14418 :
14419 0 : default:
14420 0 : gcc_unreachable ();
14421 : }
14422 :
14423 6620386 : if (TREE_CODE (to) != REFERENCE_TYPE || !from)
14424 : return false;
14425 898291 : if (TREE_CODE (from) == TREE_VEC && TREE_VEC_LENGTH (from) == 1)
14426 62217 : from = TREE_VEC_ELT (from, 0);
14427 898291 : return (TYPE_P (from)
14428 1786458 : && (same_type_ignoring_top_level_qualifiers_p
14429 888167 : (non_reference (to), non_reference (from))));
14430 : }
14431 :
14432 : /* Helper for finish_trait_expr and tsubst_expr. Handle
14433 : CPTK_STRUCTURED_BINDING_SIZE in possibly SFINAE-friendly
14434 : way. */
14435 :
14436 : tree
14437 273 : finish_structured_binding_size (location_t loc, tree type,
14438 : tsubst_flags_t complain)
14439 : {
14440 273 : if (TYPE_REF_P (type))
14441 : {
14442 105 : if (complain & tf_error)
14443 99 : error_at (loc, "%qs argument %qT is a reference",
14444 : "__builtin_structured_binding_size", type);
14445 105 : return error_mark_node;
14446 : }
14447 168 : HOST_WIDE_INT ret = cp_decomp_size (loc, type, complain);
14448 168 : if (ret == -1)
14449 63 : return error_mark_node;
14450 105 : return maybe_wrap_with_location (build_int_cst (size_type_node, ret), loc);
14451 : }
14452 :
14453 : /* Process a trait expression. */
14454 :
14455 : tree
14456 21323189 : finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2,
14457 : tsubst_flags_t complain/*=tf_warning_or_error*/)
14458 : {
14459 21323189 : if (type1 == error_mark_node
14460 21323186 : || type2 == error_mark_node)
14461 : return error_mark_node;
14462 :
14463 21323186 : if (processing_template_decl)
14464 : {
14465 3353089 : tree trait_expr = make_node (TRAIT_EXPR);
14466 3353089 : if (kind == CPTK_RANK || kind == CPTK_STRUCTURED_BINDING_SIZE)
14467 31482 : TREE_TYPE (trait_expr) = size_type_node;
14468 3321607 : else if (kind == CPTK_TYPE_ORDER)
14469 : {
14470 4500 : tree val = type_order_value (type1, type1);
14471 4500 : if (val != error_mark_node)
14472 4500 : TREE_TYPE (trait_expr) = TREE_TYPE (val);
14473 : }
14474 : else
14475 3317107 : TREE_TYPE (trait_expr) = boolean_type_node;
14476 3353089 : TRAIT_EXPR_TYPE1 (trait_expr) = type1;
14477 3353089 : TRAIT_EXPR_TYPE2 (trait_expr) = type2;
14478 3353089 : TRAIT_EXPR_KIND (trait_expr) = kind;
14479 3353089 : TRAIT_EXPR_LOCATION (trait_expr) = loc;
14480 3353089 : return trait_expr;
14481 : }
14482 :
14483 17970097 : switch (kind)
14484 : {
14485 56902 : case CPTK_HAS_NOTHROW_ASSIGN:
14486 56902 : case CPTK_HAS_TRIVIAL_ASSIGN:
14487 56902 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14488 56902 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14489 56902 : case CPTK_HAS_NOTHROW_COPY:
14490 56902 : case CPTK_HAS_TRIVIAL_COPY:
14491 56902 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14492 56902 : case CPTK_IS_DESTRUCTIBLE:
14493 56902 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14494 56902 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14495 56902 : if (!check_trait_type (type1, /*kind=*/1, complain))
14496 57 : return error_mark_node;
14497 : break;
14498 :
14499 312340 : case CPTK_IS_LITERAL_TYPE:
14500 312340 : case CPTK_IS_POD:
14501 312340 : case CPTK_IS_STD_LAYOUT:
14502 312340 : case CPTK_IS_TRIVIAL:
14503 312340 : case CPTK_IS_TRIVIALLY_COPYABLE:
14504 312340 : case CPTK_IS_STRUCTURAL:
14505 312340 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14506 312340 : if (!check_trait_type (type1, /* kind = */ 2, complain))
14507 133 : return error_mark_node;
14508 : break;
14509 :
14510 273437 : case CPTK_IS_ABSTRACT:
14511 273437 : case CPTK_IS_EMPTY:
14512 273437 : case CPTK_IS_POLYMORPHIC:
14513 273437 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14514 273437 : if (!check_trait_type (type1, /* kind = */ 3, complain))
14515 39 : return error_mark_node;
14516 : break;
14517 :
14518 : /* N.B. std::is_aggregate is kind=2 but we don't need a complete element
14519 : type to know whether an array is an aggregate, so use kind=4 here. */
14520 433403 : case CPTK_IS_AGGREGATE:
14521 433403 : case CPTK_IS_FINAL:
14522 433403 : case CPTK_IS_IMPLICIT_LIFETIME:
14523 433403 : if (!check_trait_type (type1, /* kind = */ 4, complain))
14524 55 : return error_mark_node;
14525 : break;
14526 :
14527 6620386 : case CPTK_IS_CONSTRUCTIBLE:
14528 6620386 : case CPTK_IS_CONVERTIBLE:
14529 6620386 : case CPTK_IS_INVOCABLE:
14530 6620386 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14531 6620386 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14532 6620386 : case CPTK_IS_NOTHROW_INVOCABLE:
14533 6620386 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14534 6620386 : /* Don't check completeness for direct reference binding. */;
14535 6620386 : if (same_type_ref_bind_p (kind, type1, type2))
14536 : break;
14537 7558923 : gcc_fallthrough ();
14538 :
14539 7558923 : case CPTK_IS_ASSIGNABLE:
14540 7558923 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14541 7558923 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14542 7558923 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14543 7558923 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14544 7558923 : if (!check_trait_type (type1, /*kind=*/1, complain)
14545 7558923 : || !check_trait_type (type2, /*kind=*/1, complain))
14546 602 : return error_mark_node;
14547 : break;
14548 :
14549 512552 : case CPTK_IS_BASE_OF:
14550 512552 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14551 512447 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14552 493739 : && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
14553 978371 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14554 : /* We already issued an error. */
14555 27 : return error_mark_node;
14556 : break;
14557 :
14558 778 : case CPTK_IS_VIRTUAL_BASE_OF:
14559 710 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14560 1469 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14561 : /* We already issued an error. */
14562 27 : return error_mark_node;
14563 : break;
14564 :
14565 : case CPTK_IS_ARRAY:
14566 : case CPTK_IS_BOUNDED_ARRAY:
14567 : case CPTK_IS_CLASS:
14568 : case CPTK_IS_CONST:
14569 : case CPTK_IS_ENUM:
14570 : case CPTK_IS_FUNCTION:
14571 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14572 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14573 : case CPTK_IS_MEMBER_POINTER:
14574 : case CPTK_IS_OBJECT:
14575 : case CPTK_IS_POINTER:
14576 : case CPTK_IS_REFERENCE:
14577 : case CPTK_IS_SAME:
14578 : case CPTK_IS_SCOPED_ENUM:
14579 : case CPTK_IS_UNBOUNDED_ARRAY:
14580 : case CPTK_IS_UNION:
14581 : case CPTK_IS_VOLATILE:
14582 : break;
14583 :
14584 : case CPTK_RANK:
14585 : {
14586 : size_t rank = 0;
14587 122 : for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
14588 80 : ++rank;
14589 42 : return maybe_wrap_with_location (build_int_cst (size_type_node, rank),
14590 : loc);
14591 : }
14592 :
14593 460 : case CPTK_TYPE_ORDER:
14594 460 : return maybe_wrap_with_location (type_order_value (type1, type2), loc);
14595 :
14596 144 : case CPTK_STRUCTURED_BINDING_SIZE:
14597 144 : return finish_structured_binding_size (loc, type1, complain);
14598 :
14599 242 : case CPTK_IS_LAYOUT_COMPATIBLE:
14600 242 : if (!array_of_unknown_bound_p (type1)
14601 223 : && TREE_CODE (type1) != VOID_TYPE
14602 456 : && !complete_type_or_maybe_complain (type1, NULL_TREE, complain))
14603 : /* We already issued an error. */
14604 12 : return error_mark_node;
14605 230 : if (!array_of_unknown_bound_p (type2)
14606 203 : && TREE_CODE (type2) != VOID_TYPE
14607 424 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14608 : /* We already issued an error. */
14609 9 : return error_mark_node;
14610 : break;
14611 :
14612 85 : case CPTK_IS_DEDUCIBLE:
14613 85 : if (!DECL_TYPE_TEMPLATE_P (type1))
14614 : {
14615 0 : error ("%qD is not a class or alias template", type1);
14616 0 : return error_mark_node;
14617 : }
14618 : break;
14619 :
14620 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14621 : case CPTK_##CODE:
14622 : #include "cp-trait.def"
14623 : #undef DEFTRAIT_TYPE
14624 : /* Type-yielding traits are handled in finish_trait_type. */
14625 0 : gcc_unreachable ();
14626 : }
14627 :
14628 17968490 : tree val = (trait_expr_value (kind, type1, type2)
14629 17968490 : ? boolean_true_node : boolean_false_node);
14630 17968490 : return maybe_wrap_with_location (val, loc);
14631 : }
14632 :
14633 : /* Process a trait type. */
14634 :
14635 : tree
14636 7928412 : finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
14637 : tsubst_flags_t complain)
14638 : {
14639 7928412 : if (type1 == error_mark_node
14640 7928409 : || type2 == error_mark_node)
14641 : return error_mark_node;
14642 :
14643 7928409 : if (processing_template_decl)
14644 : {
14645 231008 : tree type = cxx_make_type (TRAIT_TYPE);
14646 231008 : TRAIT_TYPE_TYPE1 (type) = type1;
14647 231008 : TRAIT_TYPE_TYPE2 (type) = type2;
14648 231008 : TRAIT_TYPE_KIND_RAW (type) = build_int_cstu (integer_type_node, kind);
14649 : /* These traits are intended to be used in the definition of the ::type
14650 : member of the corresponding standard library type trait and aren't
14651 : mangleable (and thus won't appear directly in template signatures),
14652 : so structural equality should suffice. */
14653 231008 : SET_TYPE_STRUCTURAL_EQUALITY (type);
14654 231008 : return type;
14655 : }
14656 :
14657 7697401 : switch (kind)
14658 : {
14659 1236725 : case CPTK_ADD_LVALUE_REFERENCE:
14660 : /* [meta.trans.ref]. */
14661 1236725 : if (referenceable_type_p (type1))
14662 1236638 : return cp_build_reference_type (type1, /*rval=*/false);
14663 : return type1;
14664 :
14665 637007 : case CPTK_ADD_POINTER:
14666 : /* [meta.trans.ptr]. */
14667 637007 : if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
14668 : {
14669 636975 : if (TYPE_REF_P (type1))
14670 635781 : type1 = TREE_TYPE (type1);
14671 636975 : return build_pointer_type (type1);
14672 : }
14673 : return type1;
14674 :
14675 1669328 : case CPTK_ADD_RVALUE_REFERENCE:
14676 : /* [meta.trans.ref]. */
14677 1669328 : if (referenceable_type_p (type1))
14678 1669270 : return cp_build_reference_type (type1, /*rval=*/true);
14679 : return type1;
14680 :
14681 237634 : case CPTK_DECAY:
14682 237634 : if (TYPE_REF_P (type1))
14683 43032 : type1 = TREE_TYPE (type1);
14684 :
14685 237634 : if (TREE_CODE (type1) == ARRAY_TYPE)
14686 728 : return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
14687 728 : complain);
14688 236906 : else if (TREE_CODE (type1) == FUNCTION_TYPE)
14689 209 : return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
14690 : else
14691 236697 : return cv_unqualified (type1);
14692 :
14693 223 : case CPTK_REMOVE_ALL_EXTENTS:
14694 223 : return strip_array_types (type1);
14695 :
14696 990401 : case CPTK_REMOVE_CV:
14697 990401 : return cv_unqualified (type1);
14698 :
14699 472490 : case CPTK_REMOVE_CVREF:
14700 472490 : if (TYPE_REF_P (type1))
14701 180546 : type1 = TREE_TYPE (type1);
14702 472490 : return cv_unqualified (type1);
14703 :
14704 66239 : case CPTK_REMOVE_EXTENT:
14705 66239 : if (TREE_CODE (type1) == ARRAY_TYPE)
14706 9415 : type1 = TREE_TYPE (type1);
14707 : return type1;
14708 :
14709 44660 : case CPTK_REMOVE_POINTER:
14710 44660 : if (TYPE_PTR_P (type1))
14711 41782 : type1 = TREE_TYPE (type1);
14712 : return type1;
14713 :
14714 2182281 : case CPTK_REMOVE_REFERENCE:
14715 2182281 : if (TYPE_REF_P (type1))
14716 1322962 : type1 = TREE_TYPE (type1);
14717 : return type1;
14718 :
14719 112092 : case CPTK_TYPE_PACK_ELEMENT:
14720 112092 : return finish_type_pack_element (type1, type2, complain);
14721 :
14722 48321 : case CPTK_UNDERLYING_TYPE:
14723 48321 : return finish_underlying_type (type1);
14724 :
14725 : #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
14726 : case CPTK_##CODE:
14727 : #include "cp-trait.def"
14728 : #undef DEFTRAIT_EXPR
14729 : /* Expression-yielding traits are handled in finish_trait_expr. */
14730 : case CPTK_BASES:
14731 : case CPTK_DIRECT_BASES:
14732 : /* BASES and DIRECT_BASES are handled in finish_bases. */
14733 : break;
14734 : }
14735 :
14736 0 : gcc_unreachable ();
14737 : }
14738 :
14739 : /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
14740 : which is ignored for C++. */
14741 :
14742 : void
14743 0 : set_float_const_decimal64 (void)
14744 : {
14745 0 : }
14746 :
14747 : void
14748 0 : clear_float_const_decimal64 (void)
14749 : {
14750 0 : }
14751 :
14752 : bool
14753 1854618 : float_const_decimal64_p (void)
14754 : {
14755 1854618 : return 0;
14756 : }
14757 :
14758 :
14759 : /* Return true if T designates the implied `this' parameter. */
14760 :
14761 : bool
14762 6555601 : is_this_parameter (tree t)
14763 : {
14764 6555601 : if (!DECL_P (t) || DECL_NAME (t) != this_identifier)
14765 : return false;
14766 3847666 : gcc_assert (TREE_CODE (t) == PARM_DECL
14767 : || (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
14768 : || (cp_binding_oracle && VAR_P (t)));
14769 : return true;
14770 : }
14771 :
14772 : /* As above, or a C++23 explicit object parameter. */
14773 :
14774 : bool
14775 456 : is_object_parameter (tree t)
14776 : {
14777 456 : if (is_this_parameter (t))
14778 : return true;
14779 91 : if (TREE_CODE (t) != PARM_DECL)
14780 : return false;
14781 34 : tree ctx = DECL_CONTEXT (t);
14782 34 : return (ctx && DECL_XOBJ_MEMBER_FUNCTION_P (ctx)
14783 62 : && t == DECL_ARGUMENTS (ctx));
14784 : }
14785 :
14786 : /* Insert the deduced return type for an auto function. */
14787 :
14788 : void
14789 1061446 : apply_deduced_return_type (tree fco, tree return_type)
14790 : {
14791 1061446 : tree result;
14792 :
14793 1061446 : if (return_type == error_mark_node)
14794 : return;
14795 :
14796 1061443 : if (DECL_CONV_FN_P (fco))
14797 42 : DECL_NAME (fco) = make_conv_op_name (return_type);
14798 :
14799 1061443 : TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
14800 :
14801 1061443 : maybe_update_postconditions (fco);
14802 :
14803 : /* Apply the type to the result object. */
14804 :
14805 1061443 : result = DECL_RESULT (fco);
14806 1061443 : if (result == NULL_TREE)
14807 : return;
14808 1049067 : if (TREE_TYPE (result) == return_type)
14809 : return;
14810 :
14811 1049064 : if (!processing_template_decl && !VOID_TYPE_P (return_type)
14812 1940436 : && !complete_type_or_else (return_type, NULL_TREE))
14813 : return;
14814 :
14815 : /* We already have a DECL_RESULT from start_preparsed_function.
14816 : Now we need to redo the work it and allocate_struct_function
14817 : did to reflect the new type. */
14818 1049064 : result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
14819 1049064 : TYPE_MAIN_VARIANT (return_type));
14820 1049064 : DECL_ARTIFICIAL (result) = 1;
14821 1049064 : DECL_IGNORED_P (result) = 1;
14822 1049064 : cp_apply_type_quals_to_decl (cp_type_quals (return_type),
14823 : result);
14824 1049064 : DECL_RESULT (fco) = result;
14825 :
14826 1049064 : if (!uses_template_parms (fco))
14827 1049064 : if (function *fun = DECL_STRUCT_FUNCTION (fco))
14828 : {
14829 1048085 : bool aggr = aggregate_value_p (result, fco);
14830 : #ifdef PCC_STATIC_STRUCT_RETURN
14831 : fun->returns_pcc_struct = aggr;
14832 : #endif
14833 1048085 : fun->returns_struct = aggr;
14834 : }
14835 : }
14836 :
14837 : /* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true,
14838 : this is a right unary fold. Otherwise it is a left unary fold. */
14839 :
14840 : static tree
14841 838853 : finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir)
14842 : {
14843 : /* Build a pack expansion (assuming expr has pack type). */
14844 838853 : if (!uses_parameter_packs (expr))
14845 : {
14846 3 : error_at (location_of (expr), "operand of fold expression has no "
14847 : "unexpanded parameter packs");
14848 3 : return error_mark_node;
14849 : }
14850 838850 : tree pack = make_pack_expansion (expr);
14851 :
14852 : /* Build the fold expression. */
14853 838850 : tree code = build_int_cstu (integer_type_node, abs (op));
14854 838850 : tree fold = build_min_nt_loc (loc, dir, code, pack);
14855 838850 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14856 838850 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14857 838850 : FOLD_EXPR_OP (fold),
14858 838850 : FOLD_EXPR_MODIFY_P (fold));
14859 838850 : return fold;
14860 : }
14861 :
14862 : tree
14863 25767 : finish_left_unary_fold_expr (location_t loc, tree expr, int op)
14864 : {
14865 25767 : return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR);
14866 : }
14867 :
14868 : tree
14869 813086 : finish_right_unary_fold_expr (location_t loc, tree expr, int op)
14870 : {
14871 813086 : return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR);
14872 : }
14873 :
14874 : /* Build a binary fold expression over EXPR1 and EXPR2. The
14875 : associativity of the fold is determined by EXPR1 and EXPR2 (whichever
14876 : has an unexpanded parameter pack). */
14877 :
14878 : static tree
14879 195721 : finish_binary_fold_expr (location_t loc, tree pack, tree init,
14880 : int op, tree_code dir)
14881 : {
14882 195721 : pack = make_pack_expansion (pack);
14883 195721 : tree code = build_int_cstu (integer_type_node, abs (op));
14884 195721 : tree fold = build_min_nt_loc (loc, dir, code, pack, init);
14885 195721 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14886 195721 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14887 195721 : FOLD_EXPR_OP (fold),
14888 195721 : FOLD_EXPR_MODIFY_P (fold));
14889 195721 : return fold;
14890 : }
14891 :
14892 : tree
14893 195721 : finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op)
14894 : {
14895 : // Determine which expr has an unexpanded parameter pack and
14896 : // set the pack and initial term.
14897 195721 : bool pack1 = uses_parameter_packs (expr1);
14898 195721 : bool pack2 = uses_parameter_packs (expr2);
14899 195721 : if (pack1 && !pack2)
14900 1079 : return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
14901 194642 : else if (pack2 && !pack1)
14902 194642 : return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
14903 : else
14904 : {
14905 0 : if (pack1)
14906 0 : error ("both arguments in binary fold have unexpanded parameter packs");
14907 : else
14908 0 : error ("no unexpanded parameter packs in binary fold");
14909 : }
14910 0 : return error_mark_node;
14911 : }
14912 :
14913 : /* Finish __builtin_launder (arg). */
14914 :
14915 : tree
14916 13909 : finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain)
14917 : {
14918 13909 : tree orig_arg = arg;
14919 13909 : if (!type_dependent_expression_p (arg))
14920 84 : arg = decay_conversion (arg, complain);
14921 13909 : if (error_operand_p (arg))
14922 0 : return error_mark_node;
14923 13909 : if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
14924 : {
14925 24 : error_at (loc, "type %qT of argument to %<__builtin_launder%> "
14926 24 : "is not a pointer to object type", TREE_TYPE (arg));
14927 24 : return error_mark_node;
14928 : }
14929 13885 : if (processing_template_decl)
14930 13825 : arg = orig_arg;
14931 13885 : return build_call_expr_internal_loc (loc, IFN_LAUNDER,
14932 27770 : TREE_TYPE (arg), 1, arg);
14933 : }
14934 :
14935 : /* Finish __builtin_convertvector (arg, type). */
14936 :
14937 : tree
14938 462 : cp_build_vec_convert (tree arg, location_t loc, tree type,
14939 : tsubst_flags_t complain)
14940 : {
14941 462 : if (error_operand_p (type))
14942 9 : return error_mark_node;
14943 453 : if (error_operand_p (arg))
14944 0 : return error_mark_node;
14945 :
14946 453 : tree ret = NULL_TREE;
14947 453 : if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
14948 415 : ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg),
14949 : decay_conversion (arg, complain),
14950 : loc, type, (complain & tf_error) != 0);
14951 :
14952 453 : if (!processing_template_decl)
14953 : return ret;
14954 :
14955 80 : return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg);
14956 : }
14957 :
14958 : /* Finish __builtin_bit_cast (type, arg). */
14959 :
14960 : tree
14961 290588 : cp_build_bit_cast (location_t loc, tree type, tree arg,
14962 : tsubst_flags_t complain)
14963 : {
14964 290588 : if (error_operand_p (type))
14965 0 : return error_mark_node;
14966 290588 : if (!dependent_type_p (type))
14967 : {
14968 210647 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
14969 9 : return error_mark_node;
14970 210638 : if (TREE_CODE (type) == ARRAY_TYPE)
14971 : {
14972 : /* std::bit_cast for destination ARRAY_TYPE is not possible,
14973 : as functions may not return an array, so don't bother trying
14974 : to support this (and then deal with VLAs etc.). */
14975 9 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14976 : "is an array type", type);
14977 9 : return error_mark_node;
14978 : }
14979 210629 : if (!trivially_copyable_p (type))
14980 : {
14981 18 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
14982 : "is not trivially copyable", type);
14983 18 : return error_mark_node;
14984 : }
14985 210611 : if (consteval_only_p (type) || consteval_only_p (arg))
14986 : {
14987 8 : error_at (loc, "%<__builtin_bit_cast%> cannot be used with "
14988 : "consteval-only types");
14989 8 : return error_mark_node;
14990 : }
14991 : }
14992 :
14993 290544 : if (error_operand_p (arg))
14994 0 : return error_mark_node;
14995 :
14996 290544 : if (!type_dependent_expression_p (arg))
14997 : {
14998 114188 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
14999 : {
15000 : /* Don't perform array-to-pointer conversion. */
15001 375 : arg = mark_rvalue_use (arg, loc, true);
15002 375 : if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
15003 0 : return error_mark_node;
15004 : }
15005 : else
15006 113813 : arg = decay_conversion (arg, complain);
15007 :
15008 114188 : if (error_operand_p (arg))
15009 12 : return error_mark_node;
15010 :
15011 114176 : if (!trivially_copyable_p (TREE_TYPE (arg)))
15012 : {
15013 9 : error_at (cp_expr_loc_or_loc (arg, loc),
15014 : "%<__builtin_bit_cast%> source type %qT "
15015 9 : "is not trivially copyable", TREE_TYPE (arg));
15016 9 : return error_mark_node;
15017 : }
15018 114167 : if (!dependent_type_p (type)
15019 190342 : && !cp_tree_equal (TYPE_SIZE_UNIT (type),
15020 76175 : TYPE_SIZE_UNIT (TREE_TYPE (arg))))
15021 : {
15022 18 : error_at (loc, "%<__builtin_bit_cast%> source size %qE "
15023 : "not equal to destination type size %qE",
15024 18 : TYPE_SIZE_UNIT (TREE_TYPE (arg)),
15025 18 : TYPE_SIZE_UNIT (type));
15026 18 : return error_mark_node;
15027 : }
15028 : }
15029 :
15030 290505 : tree ret = build_min (BIT_CAST_EXPR, type, arg);
15031 290505 : SET_EXPR_LOCATION (ret, loc);
15032 :
15033 290505 : if (!processing_template_decl && CLASS_TYPE_P (type))
15034 872 : ret = get_target_expr (ret, complain);
15035 :
15036 : return ret;
15037 : }
15038 :
15039 : /* Diagnose invalid #pragma GCC unroll argument and adjust
15040 : it if needed. */
15041 :
15042 : tree
15043 24111 : cp_check_pragma_unroll (location_t loc, tree unroll)
15044 : {
15045 24111 : HOST_WIDE_INT lunroll = 0;
15046 24111 : if (type_dependent_expression_p (unroll))
15047 : ;
15048 48150 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll))
15049 48104 : || (!value_dependent_expression_p (unroll)
15050 23999 : && (!tree_fits_shwi_p (unroll)
15051 23973 : || (lunroll = tree_to_shwi (unroll)) < 0
15052 23958 : || lunroll >= USHRT_MAX)))
15053 : {
15054 90 : error_at (loc, "%<#pragma GCC unroll%> requires an"
15055 : " assignment-expression that evaluates to a non-negative"
15056 : " integral constant less than %u", USHRT_MAX);
15057 90 : unroll = integer_one_node;
15058 : }
15059 23985 : else if (TREE_CODE (unroll) == INTEGER_CST)
15060 : {
15061 23955 : unroll = fold_convert (integer_type_node, unroll);
15062 23955 : if (integer_zerop (unroll))
15063 12 : unroll = integer_one_node;
15064 : }
15065 24111 : return unroll;
15066 : }
15067 :
15068 : #include "gt-cp-semantics.h"
|