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 24592967550 : push_deferring_access_checks (deferring_kind deferring)
146 : {
147 : /* For context like template instantiation, access checking
148 : disabling applies to all nested context. */
149 24592967550 : if (deferred_access_no_check || deferring == dk_no_check)
150 316259773 : deferred_access_no_check++;
151 : else
152 : {
153 24276707777 : deferred_access e = {NULL, deferring};
154 24276707777 : vec_safe_push (deferred_access_stack, e);
155 : }
156 24592967550 : }
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 395152716 : reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
163 : {
164 395152716 : push_deferring_access_checks (dk_deferred);
165 395152716 : if (!deferred_access_no_check)
166 387276094 : deferred_access_stack->last().deferred_access_checks = checks;
167 395152716 : }
168 :
169 : /* Resume deferring access checks again after we stopped doing
170 : this previously. */
171 :
172 : void
173 187584680 : resume_deferring_access_checks (void)
174 : {
175 187584680 : if (!deferred_access_no_check)
176 187564307 : deferred_access_stack->last().deferring_access_checks_kind = dk_deferred;
177 187584680 : }
178 :
179 : /* Stop deferring access checks. */
180 :
181 : void
182 525999056 : stop_deferring_access_checks (void)
183 : {
184 525999056 : if (!deferred_access_no_check)
185 525938736 : deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred;
186 525999056 : }
187 :
188 : /* Discard the current deferred access checks and restore the
189 : previous states. */
190 :
191 : void
192 15248122807 : pop_deferring_access_checks (void)
193 : {
194 15248122807 : if (deferred_access_no_check)
195 242440730 : deferred_access_no_check--;
196 : else
197 15005682077 : deferred_access_stack->pop ();
198 15248122807 : }
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 1316126204 : get_deferred_access_checks (void)
207 : {
208 1316126204 : if (deferred_access_no_check)
209 : return NULL;
210 : else
211 1299914571 : 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 9344706652 : pop_to_parent_deferring_access_checks (void)
220 : {
221 9344706652 : if (deferred_access_no_check)
222 73819037 : deferred_access_no_check--;
223 : else
224 : {
225 9270887615 : vec<deferred_access_check, va_gc> *checks;
226 9270887615 : deferred_access *ptr;
227 :
228 9270887615 : checks = (deferred_access_stack->last ().deferred_access_checks);
229 :
230 9270887615 : deferred_access_stack->pop ();
231 9270887615 : ptr = &deferred_access_stack->last ();
232 9270887615 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
233 : {
234 : /* Check access. */
235 584844046 : 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 8893532229 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
244 : {
245 112754360 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe)
246 : {
247 10011814 : if (probe->binfo == chk->binfo &&
248 7914804 : probe->decl == chk->decl &&
249 1002724 : probe->diag_decl == chk->diag_decl)
250 1001784 : goto found;
251 : }
252 : /* Insert into parent's checks. */
253 102742546 : vec_safe_push (ptr->deferred_access_checks, *chk);
254 103744330 : found:;
255 : }
256 : }
257 : }
258 9344706652 : }
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 427643548 : enforce_access (tree basetype_path, tree decl, tree diag_decl,
334 : tsubst_flags_t complain, access_failure_info *afi = NULL)
335 : {
336 427643548 : gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
337 :
338 427643548 : if (flag_new_inheriting_ctors
339 540403974 : && 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 63352 : decl = strip_inheriting_ctors (decl);
345 63352 : basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl),
346 : ba_any, NULL, complain);
347 : }
348 :
349 427643548 : tree cs = current_scope ();
350 427643548 : if (in_template_context
351 427643548 : && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
352 42637156 : 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 42388865 : 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 385254683 : if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true))
382 : {
383 22493 : if (flag_new_inheriting_ctors)
384 22463 : diag_decl = strip_inheriting_ctors (diag_decl);
385 22493 : if (complain & tf_error)
386 : {
387 1159 : 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 1159 : 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 1159 : 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 1159 : 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 1159 : complain_about_access (decl, diag_decl, diag_location, true,
413 : access_failure_reason);
414 : }
415 22493 : if (afi)
416 412 : afi->record_access_failure (basetype_path, decl, diag_decl);
417 : 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 1120803798 : perform_access_checks (vec<deferred_access_check, va_gc> *checks,
431 : tsubst_flags_t complain)
432 : {
433 1120803798 : int i;
434 1120803798 : deferred_access_check *chk;
435 1120803798 : location_t loc = input_location;
436 1120803798 : bool ok = true;
437 :
438 1120803798 : if (!checks)
439 : return true;
440 :
441 130153331 : FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
442 : {
443 72445228 : input_location = chk->loc;
444 72445228 : ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain);
445 : }
446 :
447 57708103 : input_location = loc;
448 57708103 : 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 292846185 : perform_deferred_access_checks (tsubst_flags_t complain)
469 : {
470 292846185 : 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 642439277 : perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl,
480 : tsubst_flags_t complain,
481 : access_failure_info *afi)
482 : {
483 642439277 : int i;
484 642439277 : deferred_access *ptr;
485 642439277 : deferred_access_check *chk;
486 :
487 : /* Exit if we are in a context that no access checking is performed. */
488 642439277 : if (deferred_access_no_check)
489 : return true;
490 :
491 611463833 : gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
492 :
493 611463833 : ptr = &deferred_access_stack->last ();
494 :
495 : /* If we are not supposed to defer access checks, just check now. */
496 611463833 : if (ptr->deferring_access_checks_kind == dk_no_deferred)
497 : {
498 355198320 : bool ok = enforce_access (binfo, decl, diag_decl, complain, afi);
499 355198320 : return (complain & tf_error) ? true : ok;
500 : }
501 :
502 : /* See if we are already going to perform this check. */
503 311730957 : FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk)
504 : {
505 72812604 : if (chk->decl == decl && chk->binfo == binfo &&
506 17348239 : chk->diag_decl == diag_decl)
507 : {
508 : return true;
509 : }
510 : }
511 : /* If not, record the check. */
512 238918353 : deferred_access_check new_access = {binfo, decl, diag_decl, input_location};
513 238918353 : vec_safe_push (ptr->deferred_access_checks, new_access);
514 :
515 238918353 : 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 1430387391 : stmts_are_full_exprs_p (void)
524 : {
525 1430387391 : 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 1330841419 : add_stmt (tree t)
534 : {
535 1330841419 : enum tree_code code = TREE_CODE (t);
536 :
537 1330841419 : if (EXPR_P (t) && code != LABEL_EXPR)
538 : {
539 1279712396 : if (!EXPR_HAS_LOCATION (t))
540 204685749 : 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 1279712396 : if (STATEMENT_CODE_P (TREE_CODE (t)))
545 333018284 : STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
546 : }
547 :
548 1330841419 : if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
549 6051905 : 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 1330841419 : gcc_checking_assert (!stmt_list_stack->is_empty ());
554 1330841419 : append_to_statement_list_force (t, &cur_stmt_list);
555 :
556 1330841419 : return t;
557 : }
558 :
559 : /* Returns the stmt_tree to which statements are currently being added. */
560 :
561 : stmt_tree
562 7771078847 : current_stmt_tree (void)
563 : {
564 7771078847 : return (cfun
565 7747044999 : ? &cfun->language->base.x_stmt_tree
566 7771078847 : : &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 331666 : maybe_cleanup_point_expr (tree expr)
573 : {
574 331666 : if (!processing_template_decl && stmts_are_full_exprs_p ())
575 318261 : expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr);
576 331666 : 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 329863752 : maybe_cleanup_point_expr_void (tree expr)
586 : {
587 329863752 : if (!processing_template_decl && stmts_are_full_exprs_p ())
588 110463065 : expr = fold_build_cleanup_point_expr (void_type_node, expr);
589 329863752 : return expr;
590 : }
591 :
592 :
593 :
594 : /* Create a declaration statement for the declaration given by the DECL. */
595 :
596 : void
597 111443761 : add_decl_expr (tree decl)
598 : {
599 111443761 : tree r = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl);
600 111443761 : if (DECL_INITIAL (decl)
601 111443761 : || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl))))
602 19792343 : r = maybe_cleanup_point_expr_void (r);
603 111443761 : add_stmt (r);
604 111443761 : }
605 :
606 : /* Set EXPR_LOCATION on one cleanup T to LOC. */
607 :
608 : static void
609 5935197 : set_one_cleanup_loc (tree t, location_t loc)
610 : {
611 5935197 : if (!t)
612 : return;
613 :
614 5935197 : if (TREE_CODE (t) != POSTCONDITION_STMT)
615 5935197 : 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 5935197 : if (TREE_CODE (t) == NOP_EXPR
622 0 : && TREE_TYPE (t) == void_type_node
623 5935197 : && 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 1256325621 : set_cleanup_locs (tree stmts, location_t loc)
631 : {
632 1262260818 : if (TREE_CODE (stmts) == CLEANUP_STMT)
633 : {
634 5935197 : set_one_cleanup_loc (CLEANUP_EXPR (stmts), loc);
635 5935197 : set_cleanup_locs (CLEANUP_BODY (stmts), loc);
636 : }
637 1256325621 : else if (TREE_CODE (stmts) == STATEMENT_LIST)
638 1117028047 : for (tree stmt : tsi_range (stmts))
639 865122292 : set_cleanup_locs (stmt, loc);
640 1256325621 : }
641 :
642 : /* True iff the innermost block scope is a try block. */
643 :
644 : static bool
645 391203329 : at_try_scope ()
646 : {
647 391203329 : cp_binding_level *b = current_binding_level;
648 391203778 : while (b && b->kind == sk_cleanup)
649 449 : b = b->level_chain;
650 391203329 : return b && b->kind == sk_try;
651 : }
652 :
653 : /* Finish a scope. */
654 :
655 : tree
656 391203329 : do_poplevel (tree stmt_list)
657 : {
658 391203329 : tree block = NULL;
659 :
660 391203329 : bool was_try = at_try_scope ();
661 :
662 391203329 : if (stmts_are_full_exprs_p ())
663 391140375 : block = poplevel (kept_level_p (), 1, 0);
664 :
665 : /* This needs to come after poplevel merges sk_cleanup statement_lists. */
666 391203329 : maybe_splice_retval_cleanup (stmt_list, was_try);
667 :
668 391203329 : stmt_list = pop_stmt_list (stmt_list);
669 :
670 : /* input_location is the last token of the scope, usually a }. */
671 391203329 : set_cleanup_locs (stmt_list, input_location);
672 :
673 391203329 : if (!processing_template_decl)
674 : {
675 119967046 : stmt_list = c_build_bind_expr (input_location, block, stmt_list);
676 : /* ??? See c_end_compound_stmt re statement expressions. */
677 : }
678 :
679 391203329 : return stmt_list;
680 : }
681 :
682 : /* Begin a new scope. */
683 :
684 : tree
685 391165395 : do_pushlevel (scope_kind sk)
686 : {
687 391165395 : tree ret = push_stmt_list ();
688 391165395 : if (stmts_are_full_exprs_p ())
689 391140429 : begin_scope (sk, NULL);
690 391165395 : 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 5935126 : push_cleanup (tree decl, tree cleanup, bool eh_only)
700 : {
701 5935126 : tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl);
702 5935126 : CLEANUP_EH_ONLY (stmt) = eh_only;
703 5935126 : add_stmt (stmt);
704 5935126 : CLEANUP_BODY (stmt) = push_stmt_list ();
705 5935126 : }
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 18714606 : begin_maybe_infinite_loop (tree cond)
716 : {
717 : /* Only track this while parsing a function, not during instantiation. */
718 18714606 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
719 2737494 : && !processing_template_decl))
720 : return;
721 15976614 : bool maybe_infinite = true;
722 15976614 : if (cond)
723 : {
724 15663537 : cond = fold_non_dependent_expr (cond);
725 15663537 : maybe_infinite = integer_nonzerop (cond);
726 : }
727 31640151 : vec_safe_push (cp_function_chain->infinite_loops,
728 15976614 : 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 1574309 : break_maybe_infinite_loop (void)
736 : {
737 1574309 : if (!cfun)
738 : return;
739 1574309 : 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 18714606 : end_maybe_infinite_loop (tree cond)
747 : {
748 18714606 : if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl)
749 2737494 : && !processing_template_decl))
750 : return;
751 15976614 : tree current = cp_function_chain->infinite_loops->pop();
752 15976614 : if (current != NULL_TREE)
753 : {
754 5179973 : cond = fold_non_dependent_expr (cond);
755 5179973 : if (integer_nonzerop (cond))
756 336854 : 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 90445210 : begin_cond (tree *cond_p)
767 : {
768 90445210 : if (processing_template_decl)
769 64208734 : *cond_p = push_stmt_list ();
770 90445210 : }
771 :
772 : /* Finish such a conditional. */
773 :
774 : static void
775 90445210 : finish_cond (tree *cond_p, tree expr)
776 : {
777 90445210 : if (processing_template_decl)
778 : {
779 64208734 : tree cond = pop_stmt_list (*cond_p);
780 :
781 64208734 : if (expr == NULL_TREE)
782 : /* Empty condition in 'for'. */
783 292228 : gcc_assert (empty_expr_stmt_p (cond));
784 63916506 : else if (check_for_bare_parameter_packs (expr))
785 0 : expr = error_mark_node;
786 63916506 : else if (!empty_expr_stmt_p (cond))
787 990904 : expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr);
788 : }
789 90445210 : *cond_p = expr;
790 90445210 : }
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 12607064 : adjust_loop_decl_cond (tree *body_p, tree *prep_p, tree *cleanup_p)
809 : {
810 12607064 : if (!TREE_SIDE_EFFECTS (*body_p))
811 12597271 : return;
812 :
813 9793 : gcc_assert (!processing_template_decl);
814 9793 : *prep_p = *body_p;
815 9793 : 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 9793 : current_binding_level->keep = true;
840 9793 : 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 9793 : if (tsi_end_p (iter))
847 : *body_p = NULL_TREE;
848 : else
849 9702 : *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 9793 : finish_loop_cond_prep (tree *body_p, tree *prep_p, tree cleanup)
862 : {
863 9793 : *prep_p = do_poplevel (*prep_p);
864 9793 : gcc_assert (TREE_CODE (*prep_p) == BIND_EXPR);
865 9793 : 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 9775 : tree stmt_list = BIND_EXPR_BODY (*prep_p);
872 9775 : gcc_assert (TREE_CODE (stmt_list) == STATEMENT_LIST);
873 9775 : 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 9684 : tree_stmt_iterator iter = tsi_start (stmt_list);
893 9916 : while (tsi_stmt (iter) != *body_p)
894 232 : tsi_next (&iter);
895 9684 : *body_p = tsi_split_stmt_list (input_location, iter);
896 : }
897 :
898 : /* Finish a goto-statement. */
899 :
900 : tree
901 2764 : finish_goto_stmt (tree destination)
902 : {
903 2764 : if (identifier_p (destination))
904 2618 : 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 2764 : if (TREE_CODE (destination) == LABEL_DECL)
909 2618 : TREE_USED (destination) = 1;
910 : else
911 : {
912 146 : destination = mark_rvalue_use (destination);
913 146 : if (!processing_template_decl)
914 : {
915 126 : destination = cp_convert (ptr_type_node, destination,
916 : tf_warning_or_error);
917 126 : if (error_operand_p (destination))
918 : return NULL_TREE;
919 117 : destination
920 117 : = fold_build_cleanup_point_expr (TREE_TYPE (destination),
921 : destination);
922 : }
923 : }
924 :
925 2755 : add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN));
926 :
927 2755 : tree stmt = build_stmt (input_location, GOTO_EXPR, destination);
928 2755 : check_goto (&TREE_OPERAND (stmt, 0));
929 :
930 2755 : return add_stmt (stmt);
931 : }
932 :
933 : /* Returns true if T corresponds to an assignment operator expression. */
934 :
935 : static bool
936 882073 : is_assignment_op_expr_p (tree t)
937 : {
938 882073 : if (t == NULL_TREE)
939 : return false;
940 :
941 882073 : if (TREE_CODE (t) == MODIFY_EXPR
942 882073 : || (TREE_CODE (t) == MODOP_EXPR
943 336 : && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR))
944 : return true;
945 :
946 881386 : tree call = extract_call_expr (t);
947 881386 : if (call == NULL_TREE
948 129912 : || call == error_mark_node
949 1011298 : || !CALL_EXPR_OPERATOR_SYNTAX (call))
950 : return false;
951 :
952 4678 : tree fndecl = cp_get_callee_fndecl_nofold (call);
953 4678 : return fndecl != NULL_TREE
954 4580 : && DECL_ASSIGNMENT_OPERATOR_P (fndecl)
955 4729 : && 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 8 : 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 93441749 : maybe_warn_unparenthesized_assignment (tree t, bool nested_p,
1019 : tsubst_flags_t complain)
1020 : {
1021 93441749 : tree type = TREE_TYPE (t);
1022 93441749 : t = STRIP_REFERENCE_REF (t);
1023 :
1024 93441749 : if ((complain & tf_warning)
1025 93379928 : && warn_parentheses
1026 882073 : && 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 93442096 : && (!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 93441749 : }
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 55177083 : annotate_saver::annotate_saver (tree *cond) : m_annotations (nullptr)
1072 : {
1073 55177083 : tree *t = cond;
1074 55187505 : while (TREE_CODE (*t) == ANNOTATE_EXPR)
1075 10422 : t = &TREE_OPERAND (*t, 0);
1076 :
1077 55177083 : if (t != cond)
1078 : {
1079 10419 : m_annotations = *cond;
1080 10419 : *cond = *t;
1081 10419 : m_inner = t;
1082 : }
1083 55177083 : }
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 55177083 : annotate_saver::restore (tree new_inner)
1092 : {
1093 55177083 : 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 10419 : 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 10419 : *m_inner = new_inner;
1118 10419 : 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 95534761 : maybe_convert_cond (tree cond)
1127 : {
1128 : /* Empty conditions remain empty. */
1129 95534761 : if (!cond)
1130 : return NULL_TREE;
1131 :
1132 : /* Wait until we instantiate templates before doing conversion. */
1133 95161462 : if (type_dependent_expression_p (cond))
1134 39984379 : return cond;
1135 :
1136 : /* Strip any ANNOTATE_EXPRs from COND. */
1137 55177083 : 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 NON_LVALUE_EXPR, pick it up from there. */
1143 386298 : if (DECL_DECOMPOSITION_P (cond)
1144 228 : && DECL_DECOMP_IS_BASE (cond)
1145 228 : && DECL_DECOMP_BASE (cond)
1146 55177308 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == NON_LVALUE_EXPR)
1147 59 : cond = TREE_OPERAND (DECL_DECOMP_BASE (cond), 0);
1148 :
1149 55177083 : if (warn_sequence_point && !processing_template_decl)
1150 328157 : verify_sequence_points (cond);
1151 :
1152 55177083 : maybe_warn_unparenthesized_assignment (cond, /*nested_p=*/false,
1153 : tf_warning_or_error);
1154 :
1155 : /* Do the conversion. */
1156 55177083 : cond = convert_from_reference (cond);
1157 55177083 : cond = condition_conversion (cond);
1158 :
1159 : /* Restore any ANNOTATE_EXPRs around COND. */
1160 55177083 : return annotations.restore (cond);
1161 : }
1162 :
1163 : /* Finish an expression-statement, whose EXPRESSION is as indicated. */
1164 :
1165 : tree
1166 169280765 : finish_expr_stmt (tree expr)
1167 : {
1168 169280765 : tree r = NULL_TREE;
1169 169280765 : location_t loc = EXPR_LOCATION (expr);
1170 :
1171 169092812 : if (expr != NULL_TREE)
1172 : {
1173 : /* If we ran into a problem, make sure we complained. */
1174 169280604 : gcc_assert (expr != error_mark_node || seen_error ());
1175 :
1176 169280604 : if (!processing_template_decl)
1177 : {
1178 61653402 : if (warn_sequence_point)
1179 819377 : verify_sequence_points (expr);
1180 61653402 : expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1181 : }
1182 107627202 : else if (!type_dependent_expression_p (expr))
1183 23443989 : convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
1184 :
1185 169280601 : 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 169280601 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
1192 : {
1193 169280422 : if (TREE_CODE (expr) != EXPR_STMT
1194 166745461 : && !STATEMENT_CLASS_P (expr)
1195 166741310 : && TREE_CODE (expr) != STATEMENT_LIST)
1196 166585049 : expr = build_stmt (loc, EXPR_STMT, expr);
1197 169280422 : expr = maybe_cleanup_point_expr_void (expr);
1198 : }
1199 :
1200 169280601 : r = add_stmt (expr);
1201 : }
1202 :
1203 169280762 : return r;
1204 : }
1205 :
1206 :
1207 : /* Begin an if-statement. Returns a newly created IF_STMT if
1208 : appropriate. */
1209 :
1210 : tree
1211 77096779 : begin_if_stmt (void)
1212 : {
1213 77096779 : tree r, scope;
1214 77096779 : scope = do_pushlevel (sk_cond);
1215 77096779 : r = build_stmt (input_location, IF_STMT, NULL_TREE,
1216 : NULL_TREE, NULL_TREE, scope);
1217 77096779 : current_binding_level->this_entity = r;
1218 77096779 : begin_cond (&IF_COND (r));
1219 77096779 : 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 254246 : is_std_constant_evaluated_p (tree fn)
1227 : {
1228 : /* std::is_constant_evaluated takes no arguments. */
1229 254246 : if (call_expr_nargs (fn) != 0)
1230 : return false;
1231 :
1232 90715 : tree fndecl = cp_get_callee_fndecl_nofold (fn);
1233 90715 : if (fndecl == NULL_TREE)
1234 : return false;
1235 :
1236 28360 : if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
1237 : BUILT_IN_FRONTEND))
1238 : return true;
1239 :
1240 28331 : if (!decl_in_std_namespace_p (fndecl))
1241 : return false;
1242 :
1243 12992 : tree name = DECL_NAME (fndecl);
1244 12992 : 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 4713238 : find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *)
1252 : {
1253 4713238 : tree t = *tp;
1254 :
1255 4713238 : if (TYPE_P (t) || TREE_CONSTANT (t))
1256 : {
1257 835800 : *walk_subtrees = false;
1258 835800 : return NULL_TREE;
1259 : }
1260 :
1261 3877438 : switch (TREE_CODE (t))
1262 : {
1263 254246 : case CALL_EXPR:
1264 254246 : if (is_std_constant_evaluated_p (t))
1265 2396 : 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 77182581 : maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if,
1284 : bool trivial_infinite)
1285 : {
1286 77182581 : if (!warn_tautological_compare)
1287 : return;
1288 :
1289 : /* Suppress warning for std::is_constant_evaluated if the conditional
1290 : comes from a macro. */
1291 1438024 : if (from_macro_expansion_at (EXPR_LOCATION (cond)))
1292 : return;
1293 :
1294 607213 : cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r,
1295 : NULL);
1296 607213 : if (cond)
1297 : {
1298 2396 : 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 2362 : 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 2354 : 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 4632 : 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 77096779 : finish_if_stmt_cond (tree orig_cond, tree if_stmt)
1330 : {
1331 77096779 : tree cond = maybe_convert_cond (orig_cond);
1332 77096779 : maybe_warn_for_constant_evaluated (cond, IF_STMT_CONSTEXPR_P (if_stmt),
1333 : /*trivial_infinite=*/false);
1334 77096779 : if (IF_STMT_CONSTEXPR_P (if_stmt)
1335 16270505 : && !type_dependent_expression_p (cond)
1336 11157894 : && require_constant_expression (cond)
1337 11157863 : && !instantiation_dependent_expression_p (cond)
1338 : /* Wait until instantiation time, since only then COND has been
1339 : converted to bool. */
1340 83101833 : && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node)
1341 : {
1342 6005054 : cond = instantiate_non_dependent_expr (cond);
1343 6005054 : cond = cxx_constant_value (cond);
1344 : }
1345 71091725 : else if (processing_template_decl)
1346 53353692 : cond = orig_cond;
1347 77096779 : finish_cond (&IF_COND (if_stmt), cond);
1348 77096779 : add_stmt (if_stmt);
1349 77096779 : THEN_CLAUSE (if_stmt) = push_stmt_list ();
1350 77096779 : 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 77088965 : finish_then_clause (tree if_stmt)
1358 : {
1359 77088965 : THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt));
1360 77088965 : return if_stmt;
1361 : }
1362 :
1363 : /* Begin the else-clause of an if-statement. */
1364 :
1365 : void
1366 28723300 : begin_else_clause (tree if_stmt)
1367 : {
1368 28723300 : ELSE_CLAUSE (if_stmt) = push_stmt_list ();
1369 28723300 : }
1370 :
1371 : /* Finish the else-clause of an if-statement, which may be given by
1372 : IF_STMT. */
1373 :
1374 : void
1375 28723262 : finish_else_clause (tree if_stmt)
1376 : {
1377 28723262 : ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt));
1378 28723262 : }
1379 :
1380 : /* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as
1381 : read. */
1382 :
1383 : static tree
1384 885768432 : maybe_mark_exp_read_r (tree *tp, int *, void *)
1385 : {
1386 885768432 : tree t = *tp;
1387 885768432 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
1388 51857267 : mark_exp_read (t);
1389 885768432 : return NULL_TREE;
1390 : }
1391 :
1392 : /* Finish an if-statement. */
1393 :
1394 : void
1395 77088965 : finish_if_stmt (tree if_stmt)
1396 : {
1397 77088965 : tree scope = IF_SCOPE (if_stmt);
1398 77088965 : IF_SCOPE (if_stmt) = NULL;
1399 77088965 : 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 16262691 : cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt),
1405 : maybe_mark_exp_read_r, NULL);
1406 16262691 : cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt),
1407 : maybe_mark_exp_read_r, NULL);
1408 : }
1409 77088965 : add_stmt (do_poplevel (scope));
1410 77088965 : }
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 18061392 : finish_loop_cond (tree *condp, tree body)
1421 : {
1422 18061392 : if (TREE_CODE (*condp) == INTEGER_CST)
1423 : return;
1424 12943453 : bool trivially_empty = expr_first (body) == NULL_TREE;
1425 12943453 : bool trivial_infinite = false;
1426 12943453 : if (trivially_empty)
1427 : {
1428 100107 : tree c = fold_non_dependent_expr (*condp, tf_none,
1429 : /*manifestly_const_eval=*/true);
1430 100107 : trivial_infinite = c && integer_nonzerop (c);
1431 : }
1432 12943453 : if (warn_tautological_compare)
1433 : {
1434 86004 : tree cond = *condp;
1435 86371 : while (TREE_CODE (cond) == ANNOTATE_EXPR)
1436 367 : cond = TREE_OPERAND (cond, 0);
1437 86004 : if (trivial_infinite
1438 86068 : && !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1439 64 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1440 : /*trivial_infinite=*/true);
1441 85940 : else if (!trivially_empty
1442 375 : || !processing_template_decl
1443 86344 : || DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
1444 85738 : maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false,
1445 : /*trivial_infinite=*/false);
1446 : }
1447 12943453 : 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 4940360 : begin_while_stmt (void)
1459 : {
1460 4940360 : tree r;
1461 4940360 : r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1462 : NULL_TREE, NULL_TREE);
1463 4940360 : add_stmt (r);
1464 4940360 : WHILE_BODY (r) = do_pushlevel (sk_block);
1465 4940360 : begin_cond (&WHILE_COND (r));
1466 4940360 : return r;
1467 : }
1468 :
1469 : /* Process the COND of a while-statement, which may be given by
1470 : WHILE_STMT. */
1471 :
1472 : void
1473 4940360 : finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep,
1474 : tree unroll, bool novector)
1475 : {
1476 4940360 : cond = maybe_convert_cond (cond);
1477 4940360 : finish_cond (&WHILE_COND (while_stmt), cond);
1478 4940360 : begin_maybe_infinite_loop (cond);
1479 4940360 : 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 4940360 : if (unroll && cond != error_mark_node)
1487 28020 : WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR,
1488 14010 : TREE_TYPE (WHILE_COND (while_stmt)),
1489 14010 : WHILE_COND (while_stmt),
1490 : build_int_cst (integer_type_node,
1491 : annot_expr_unroll_kind),
1492 : unroll);
1493 4940360 : 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 4940360 : adjust_loop_decl_cond (&WHILE_BODY (while_stmt),
1501 : &WHILE_COND_PREP (while_stmt),
1502 : &WHILE_COND_CLEANUP (while_stmt));
1503 4940360 : }
1504 :
1505 : /* Finish a while-statement, which may be given by WHILE_STMT. */
1506 :
1507 : void
1508 4940360 : finish_while_stmt (tree while_stmt)
1509 : {
1510 4940360 : end_maybe_infinite_loop (boolean_true_node);
1511 4940360 : if (WHILE_COND_PREP (while_stmt))
1512 9619 : finish_loop_cond_prep (&WHILE_BODY (while_stmt),
1513 : &WHILE_COND_PREP (while_stmt),
1514 9619 : WHILE_COND_CLEANUP (while_stmt));
1515 : else
1516 4930741 : WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
1517 4940360 : finish_loop_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt));
1518 4940360 : }
1519 :
1520 : /* Begin a do-statement. Returns a newly created DO_STMT if
1521 : appropriate. */
1522 :
1523 : tree
1524 5827627 : begin_do_stmt (void)
1525 : {
1526 5827627 : tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE,
1527 : NULL_TREE);
1528 5827627 : begin_maybe_infinite_loop (boolean_true_node);
1529 5827627 : add_stmt (r);
1530 5827627 : DO_BODY (r) = push_stmt_list ();
1531 5827627 : return r;
1532 : }
1533 :
1534 : /* Finish the body of a do-statement, which may be given by DO_STMT. */
1535 :
1536 : void
1537 5827627 : finish_do_body (tree do_stmt)
1538 : {
1539 5827627 : tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt));
1540 :
1541 5827627 : if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body))
1542 546091 : body = STATEMENT_LIST_TAIL (body)->stmt;
1543 :
1544 5827627 : if (IS_EMPTY_STMT (body))
1545 30 : warning (OPT_Wempty_body,
1546 : "suggest explicit braces around empty body in %<do%> statement");
1547 5827627 : }
1548 :
1549 : /* Finish a do-statement, which may be given by DO_STMT, and whose
1550 : COND is as indicated. */
1551 :
1552 : void
1553 5827627 : finish_do_stmt (tree cond, tree do_stmt, bool ivdep, tree unroll,
1554 : bool novector)
1555 : {
1556 5827627 : cond = maybe_convert_cond (cond);
1557 5827627 : 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 5827627 : if (check_for_bare_parameter_packs (cond))
1562 3 : cond = error_mark_node;
1563 5827627 : 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 5827627 : 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 5827627 : 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 5827627 : DO_COND (do_stmt) = cond;
1576 5827627 : tree do_body = DO_BODY (do_stmt);
1577 5827597 : if (CONVERT_EXPR_P (do_body)
1578 30 : && integer_zerop (TREE_OPERAND (do_body, 0))
1579 5827657 : && VOID_TYPE_P (TREE_TYPE (do_body)))
1580 : do_body = NULL_TREE;
1581 5827627 : finish_loop_cond (&DO_COND (do_stmt), do_body);
1582 5827627 : }
1583 :
1584 : /* Finish a return-statement. The EXPRESSION returned, if any, is as
1585 : indicated. */
1586 :
1587 : tree
1588 133530392 : finish_return_stmt (tree expr)
1589 : {
1590 133530392 : tree r;
1591 133530392 : bool no_warning;
1592 133530392 : bool dangling;
1593 :
1594 133530392 : expr = check_return_expr (expr, &no_warning, &dangling);
1595 :
1596 133530392 : if (error_operand_p (expr)
1597 133530392 : || (flag_openmp && !check_omp_return ()))
1598 : {
1599 : /* Suppress -Wreturn-type for this function. */
1600 1356 : if (warn_return_type)
1601 1350 : suppress_warning (current_function_decl, OPT_Wreturn_type);
1602 1356 : return error_mark_node;
1603 : }
1604 :
1605 133529036 : if (!processing_template_decl)
1606 : {
1607 46576384 : if (warn_sequence_point)
1608 1039452 : verify_sequence_points (expr);
1609 : }
1610 :
1611 133529036 : r = build_stmt (input_location, RETURN_EXPR, expr);
1612 133529036 : RETURN_EXPR_LOCAL_ADDR_P (r) = dangling;
1613 133529036 : if (no_warning)
1614 33 : suppress_warning (r, OPT_Wreturn_type);
1615 133529036 : r = maybe_cleanup_point_expr_void (r);
1616 133529036 : r = add_stmt (r);
1617 :
1618 133529036 : 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 7946619 : begin_for_scope (tree *init)
1627 : {
1628 7946619 : tree scope = do_pushlevel (sk_for);
1629 :
1630 7946619 : if (processing_template_decl)
1631 6313159 : *init = push_stmt_list ();
1632 : else
1633 1633460 : *init = NULL_TREE;
1634 :
1635 7946619 : 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 7666704 : begin_for_stmt (tree scope, tree init)
1644 : {
1645 7666704 : tree r;
1646 :
1647 7666704 : 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 7666704 : if (scope == NULL_TREE)
1652 : {
1653 1383283 : gcc_assert (!init);
1654 1383283 : scope = begin_for_scope (&init);
1655 : }
1656 :
1657 7666704 : FOR_INIT_STMT (r) = init;
1658 7666704 : FOR_SCOPE (r) = scope;
1659 :
1660 7666704 : 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 7666704 : finish_init_stmt (tree for_stmt)
1668 : {
1669 7666704 : if (processing_template_decl)
1670 6033244 : FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt));
1671 7666704 : add_stmt (for_stmt);
1672 7666704 : FOR_BODY (for_stmt) = do_pushlevel (sk_block);
1673 7666704 : begin_cond (&FOR_COND (for_stmt));
1674 7666704 : }
1675 :
1676 : /* Finish the COND of a for-statement, which may be given by
1677 : FOR_STMT. */
1678 :
1679 : void
1680 7666704 : finish_for_cond (tree cond, tree for_stmt, bool ivdep, tree unroll,
1681 : bool novector)
1682 : {
1683 7666704 : cond = maybe_convert_cond (cond);
1684 7666704 : finish_cond (&FOR_COND (for_stmt), cond);
1685 7666704 : begin_maybe_infinite_loop (cond);
1686 7666704 : 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 7666704 : 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 7666704 : 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 7666704 : adjust_loop_decl_cond (&FOR_BODY (for_stmt), &FOR_COND_PREP (for_stmt),
1708 : &FOR_COND_CLEANUP (for_stmt));
1709 7666704 : }
1710 :
1711 : /* Finish the increment-EXPRESSION in a for-statement, which may be
1712 : given by FOR_STMT. */
1713 :
1714 : void
1715 7654275 : finish_for_expr (tree expr, tree for_stmt)
1716 : {
1717 7654275 : 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 7190293 : if (type_unknown_p (expr))
1722 : {
1723 6 : cxx_incomplete_type_error (expr, TREE_TYPE (expr));
1724 6 : expr = error_mark_node;
1725 : }
1726 7190293 : if (!processing_template_decl)
1727 : {
1728 1558876 : if (warn_sequence_point)
1729 15015 : verify_sequence_points (expr);
1730 1558876 : expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
1731 : tf_warning_or_error);
1732 : }
1733 5631417 : else if (!type_dependent_expression_p (expr))
1734 2029499 : convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error);
1735 7190293 : expr = maybe_cleanup_point_expr_void (expr);
1736 7190293 : if (check_for_bare_parameter_packs (expr))
1737 0 : expr = error_mark_node;
1738 7190293 : 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 7946732 : find_range_for_decls (tree range_for_decl[3])
1749 : {
1750 7946732 : 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 31786928 : for (int i = 0; i < 3; i++)
1756 : {
1757 23840196 : tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i];
1758 23840196 : if (IDENTIFIER_BINDING (id)
1759 23840196 : && IDENTIFIER_BINDING (id)->scope == current_binding_level)
1760 : {
1761 277765 : range_for_decl[i] = IDENTIFIER_BINDING (id)->value;
1762 277765 : gcc_assert (VAR_P (range_for_decl[i])
1763 : && DECL_ARTIFICIAL (range_for_decl[i]));
1764 : }
1765 : }
1766 7946732 : }
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 7946619 : finish_for_stmt (tree for_stmt)
1775 : {
1776 7946619 : end_maybe_infinite_loop (boolean_true_node);
1777 :
1778 7946619 : if (TREE_CODE (for_stmt) == RANGE_FOR_STMT)
1779 279915 : RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt));
1780 : else
1781 : {
1782 7666704 : 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 7666530 : FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt));
1788 7666704 : if (FOR_COND (for_stmt))
1789 7293405 : finish_loop_cond (&FOR_COND (for_stmt),
1790 7293405 : FOR_EXPR (for_stmt) ? integer_one_node
1791 144191 : : FOR_BODY (for_stmt));
1792 : }
1793 :
1794 : /* Pop the scope for the body of the loop. */
1795 7946619 : tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT
1796 7946619 : ? &RANGE_FOR_SCOPE (for_stmt)
1797 7666704 : : &FOR_SCOPE (for_stmt));
1798 7946619 : tree scope = *scope_ptr;
1799 7946619 : *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 7946619 : tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
1806 7946619 : find_range_for_decls (range_for_decl);
1807 :
1808 7946619 : 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 7946619 : if (!stmts_are_full_exprs_p ())
1813 12429 : return;
1814 :
1815 31736760 : for (int i = 0; i < 3; i++)
1816 23802570 : if (range_for_decl[i])
1817 277649 : DECL_NAME (range_for_decl[i])
1818 277649 : = 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 279915 : begin_range_for_stmt (tree scope, tree init)
1828 : {
1829 279915 : begin_maybe_infinite_loop (boolean_false_node);
1830 :
1831 279915 : tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE,
1832 : NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
1833 :
1834 279915 : 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 279915 : RANGE_FOR_INIT_STMT (r) = init;
1842 279915 : RANGE_FOR_SCOPE (r) = scope;
1843 :
1844 279915 : 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 279915 : finish_range_for_decl (tree range_for_stmt, tree decl, tree expr)
1853 : {
1854 279915 : if (processing_template_decl)
1855 559830 : RANGE_FOR_INIT_STMT (range_for_stmt)
1856 559830 : = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt));
1857 279915 : RANGE_FOR_DECL (range_for_stmt) = decl;
1858 279915 : RANGE_FOR_EXPR (range_for_stmt) = expr;
1859 279915 : add_stmt (range_for_stmt);
1860 279915 : RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block);
1861 279915 : }
1862 :
1863 : /* Begin the scope of an expansion-statement. */
1864 :
1865 : tree
1866 2324 : begin_template_for_scope (tree *init)
1867 : {
1868 2324 : tree scope = do_pushlevel (sk_template_for);
1869 :
1870 2324 : if (processing_template_decl)
1871 547 : *init = push_stmt_list ();
1872 : else
1873 1777 : *init = NULL_TREE;
1874 :
1875 2324 : return scope;
1876 : }
1877 :
1878 : /* Finish a break-statement. */
1879 :
1880 : tree
1881 4952867 : 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 4952867 : if (!block_may_fallthru (cur_stmt_list))
1891 921 : return void_node;
1892 4951946 : note_break_stmt ();
1893 4951946 : return add_stmt (build_stmt (input_location, BREAK_STMT, NULL_TREE));
1894 : }
1895 :
1896 : /* Finish a continue-statement. */
1897 :
1898 : tree
1899 253975 : finish_continue_stmt (void)
1900 : {
1901 253975 : 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 741367 : begin_switch_stmt (void)
1909 : {
1910 741367 : tree r, scope;
1911 :
1912 741367 : scope = do_pushlevel (sk_cond);
1913 741367 : r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE,
1914 : scope, NULL_TREE);
1915 :
1916 741367 : begin_cond (&SWITCH_STMT_COND (r));
1917 :
1918 741367 : return r;
1919 : }
1920 :
1921 : /* Finish the cond of a switch-statement. */
1922 :
1923 : void
1924 741367 : finish_switch_cond (tree cond, tree switch_stmt)
1925 : {
1926 741367 : tree orig_type = NULL;
1927 :
1928 741367 : if (!processing_template_decl)
1929 : {
1930 : /* Convert the condition to an integer or enumeration type. */
1931 302825 : 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 NON_LVALUE_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 302879 : && TREE_CODE (DECL_DECOMP_BASE (cond)) == NON_LVALUE_EXPR)
1940 18 : cond = TREE_OPERAND (DECL_DECOMP_BASE (cond), 0);
1941 302825 : cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
1942 302825 : 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 302825 : orig_type = unlowered_expr_type (cond);
1950 302825 : if (TREE_CODE (orig_type) != ENUMERAL_TYPE)
1951 208279 : orig_type = TREE_TYPE (cond);
1952 302825 : if (cond != error_mark_node)
1953 : {
1954 : /* [stmt.switch]
1955 :
1956 : Integral promotions are performed. */
1957 302792 : cond = perform_integral_promotions (cond);
1958 302792 : cond = maybe_cleanup_point_expr (cond);
1959 : }
1960 : }
1961 741367 : if (check_for_bare_parameter_packs (cond))
1962 0 : cond = error_mark_node;
1963 741367 : else if (!processing_template_decl && warn_sequence_point)
1964 2853 : verify_sequence_points (cond);
1965 :
1966 741367 : finish_cond (&SWITCH_STMT_COND (switch_stmt), cond);
1967 741367 : SWITCH_STMT_TYPE (switch_stmt) = orig_type;
1968 741367 : add_stmt (switch_stmt);
1969 741367 : push_switch (switch_stmt);
1970 741367 : SWITCH_STMT_BODY (switch_stmt) = push_stmt_list ();
1971 741367 : }
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 741367 : finish_switch_stmt (tree switch_stmt)
1978 : {
1979 741367 : tree scope;
1980 :
1981 1482734 : SWITCH_STMT_BODY (switch_stmt) =
1982 741367 : pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
1983 741367 : pop_switch ();
1984 :
1985 741367 : scope = SWITCH_STMT_SCOPE (switch_stmt);
1986 741367 : SWITCH_STMT_SCOPE (switch_stmt) = NULL;
1987 741367 : add_stmt (do_poplevel (scope));
1988 741367 : }
1989 :
1990 : /* Begin a try-block. Returns a newly-created TRY_BLOCK if
1991 : appropriate. */
1992 :
1993 : tree
1994 1215491 : begin_try_block (void)
1995 : {
1996 1215491 : tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE);
1997 1215491 : add_stmt (r);
1998 1215491 : TRY_STMTS (r) = push_stmt_list ();
1999 1215491 : 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 2224 : begin_function_try_block (tree *compound_stmt)
2008 : {
2009 2224 : 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 2224 : *compound_stmt = begin_compound_stmt (0);
2013 2224 : current_binding_level->artificial = 1;
2014 2224 : r = begin_try_block ();
2015 2224 : FN_TRY_BLOCK_P (r) = 1;
2016 2224 : return r;
2017 : }
2018 :
2019 : /* Finish a try-block, which may be given by TRY_BLOCK. */
2020 :
2021 : void
2022 1215491 : finish_try_block (tree try_block)
2023 : {
2024 1215491 : TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block));
2025 1215491 : TRY_HANDLERS (try_block) = push_stmt_list ();
2026 1215491 : }
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 2224 : finish_function_try_block (tree try_block)
2051 : {
2052 2224 : finish_try_block (try_block);
2053 : /* FIXME : something queer about CTOR_INITIALIZER somehow following
2054 : the try block, but moving it inside. */
2055 2224 : in_function_try_handler = 1;
2056 2224 : }
2057 :
2058 : /* Finish a handler-sequence for a try-block, which may be given by
2059 : TRY_BLOCK. */
2060 :
2061 : void
2062 1215491 : finish_handler_sequence (tree try_block)
2063 : {
2064 1215491 : TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block));
2065 1215491 : check_handlers (TRY_HANDLERS (try_block));
2066 1215491 : }
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 2224 : finish_function_handler_sequence (tree try_block, tree compound_stmt)
2074 : {
2075 2224 : in_function_try_handler = 0;
2076 2224 : finish_handler_sequence (try_block);
2077 2224 : finish_compound_stmt (compound_stmt);
2078 2224 : }
2079 :
2080 : /* Begin a handler. Returns a HANDLER if appropriate. */
2081 :
2082 : tree
2083 1695377 : begin_handler (void)
2084 : {
2085 1695377 : tree r;
2086 :
2087 1695377 : r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE);
2088 1695377 : add_stmt (r);
2089 :
2090 : /* Create a binding level for the eh_info and the exception object
2091 : cleanup. */
2092 1695377 : HANDLER_BODY (r) = do_pushlevel (sk_catch);
2093 :
2094 1695377 : 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 1695377 : finish_handler_parms (tree decl, tree handler)
2103 : {
2104 1695377 : tree type = NULL_TREE;
2105 1695377 : if (processing_template_decl)
2106 : {
2107 1548282 : if (decl)
2108 : {
2109 503639 : decl = pushdecl (decl);
2110 503639 : decl = push_template_decl (decl);
2111 503639 : HANDLER_PARMS (handler) = decl;
2112 503639 : type = TREE_TYPE (decl);
2113 : }
2114 : }
2115 : else
2116 : {
2117 147095 : type = expand_start_catch_block (decl);
2118 147095 : if (warn_catch_value
2119 2116 : && type != NULL_TREE
2120 711 : && type != error_mark_node
2121 147806 : && !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 1695377 : HANDLER_TYPE (handler) = type;
2143 1695377 : }
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 1695377 : finish_handler (tree handler)
2150 : {
2151 1695377 : if (!processing_template_decl)
2152 147095 : expand_end_catch_block ();
2153 1695377 : HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler));
2154 1695377 : }
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 296389674 : begin_compound_stmt (unsigned int flags)
2165 : {
2166 296389674 : tree r;
2167 :
2168 296389674 : if (flags & BCS_NO_SCOPE)
2169 : {
2170 5662850 : r = push_stmt_list ();
2171 5662850 : 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 5662850 : keep_next_level (false);
2178 : }
2179 : else
2180 : {
2181 290726824 : scope_kind sk = sk_block;
2182 290726824 : if (flags & BCS_TRY_BLOCK)
2183 : sk = sk_try;
2184 289511585 : else if (flags & BCS_TRANSACTION)
2185 : sk = sk_transaction;
2186 289511350 : else if (flags & BCS_STMT_EXPR)
2187 29154 : sk = sk_stmt_expr;
2188 290726824 : 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 296389674 : if (processing_template_decl)
2198 : {
2199 198880087 : r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
2200 198880087 : BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
2201 198880087 : BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
2202 198880087 : TREE_SIDE_EFFECTS (r) = 1;
2203 : }
2204 :
2205 296389674 : return r;
2206 : }
2207 :
2208 : /* Finish a compound-statement, which is given by STMT. */
2209 :
2210 : void
2211 296389635 : finish_compound_stmt (tree stmt)
2212 : {
2213 296389635 : if (TREE_CODE (stmt) == BIND_EXPR)
2214 : {
2215 198880087 : 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 198880087 : if (TREE_CODE (body) == STATEMENT_LIST
2220 180882262 : && STATEMENT_LIST_HEAD (body) == NULL
2221 12017747 : && !BIND_EXPR_BODY_BLOCK (stmt)
2222 210372923 : && !BIND_EXPR_TRY_BLOCK (stmt))
2223 : stmt = body;
2224 : else
2225 187387348 : BIND_EXPR_BODY (stmt) = body;
2226 : }
2227 97509548 : else if (STATEMENT_LIST_NO_SCOPE (stmt))
2228 5624862 : stmt = pop_stmt_list (stmt);
2229 : else
2230 : {
2231 : /* Destroy any ObjC "super" receivers that may have been
2232 : created. */
2233 91884686 : objc_clear_super_receiver ();
2234 :
2235 91884686 : stmt = do_poplevel (stmt);
2236 : }
2237 :
2238 : /* ??? See c_end_compound_stmt wrt statement expressions. */
2239 296389635 : add_stmt (stmt);
2240 296389635 : }
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 55224 : finish_asm_string_expression (location_t loc, tree string)
2248 : {
2249 55224 : if (string == error_mark_node
2250 55211 : || 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 32616 : 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 32616 : tree r;
2277 32616 : tree t;
2278 32616 : int ninputs = list_length (input_operands);
2279 32616 : int noutputs = list_length (output_operands);
2280 :
2281 32616 : if (!processing_template_decl)
2282 : {
2283 12790 : const char *constraint;
2284 12790 : const char **oconstraints;
2285 12790 : bool allows_mem, allows_reg, is_inout;
2286 12790 : tree operand;
2287 12790 : int i;
2288 :
2289 12790 : oconstraints = XALLOCAVEC (const char *, noutputs);
2290 :
2291 25478 : string = finish_asm_string_expression (cp_expr_loc_or_loc (string, loc),
2292 : string);
2293 12790 : if (string == error_mark_node)
2294 109 : return error_mark_node;
2295 38088 : for (int i = 0; i < 2; ++i)
2296 61794 : for (t = i ? input_operands : output_operands; t; t = TREE_CHAIN (t))
2297 : {
2298 36417 : tree s = TREE_VALUE (TREE_PURPOSE (t));
2299 72816 : s = finish_asm_string_expression (cp_expr_loc_or_loc (s, loc), s);
2300 36417 : if (s == error_mark_node)
2301 : return error_mark_node;
2302 36387 : TREE_VALUE (TREE_PURPOSE (t)) = s;
2303 : }
2304 18098 : 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 12681 : string = resolve_asm_operand_names (string, output_operands,
2312 : input_operands, labels);
2313 :
2314 44404 : for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i)
2315 : {
2316 19042 : 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 19042 : STRIP_NOPS (operand);
2325 :
2326 19042 : operand = mark_lvalue_use (operand);
2327 :
2328 19042 : if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
2329 9 : operand = error_mark_node;
2330 :
2331 19042 : if (operand != error_mark_node
2332 19042 : && (TREE_READONLY (operand)
2333 19027 : || CP_TYPE_CONST_P (TREE_TYPE (operand))
2334 : /* Functions are not modifiable, even though they are
2335 : lvalues. */
2336 19027 : || 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 19027 : || (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 19042 : tree *op = &operand;
2344 19049 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2345 7 : op = &TREE_OPERAND (*op, 1);
2346 19042 : 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 19042 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2359 19042 : oconstraints[i] = constraint;
2360 :
2361 19042 : 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 19033 : if (!allows_reg && !cxx_mark_addressable (*op))
2368 0 : operand = error_mark_node;
2369 19033 : 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 715 : 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 19021 : 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 19042 : TREE_VALUE (t) = operand;
2415 : }
2416 :
2417 30021 : for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t))
2418 : {
2419 17340 : constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
2420 17340 : bool constraint_parsed
2421 17340 : = 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 17340 : if (constraint_parsed && !allows_reg && allows_mem)
2427 579 : operand = mark_lvalue_use (TREE_VALUE (t));
2428 : else
2429 16761 : 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 17340 : 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 17340 : if (constraint_parsed)
2444 : {
2445 : /* If the operand is going to end up in memory,
2446 : mark it addressable. */
2447 17319 : 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 579 : STRIP_NOPS (operand);
2452 :
2453 579 : tree *op = &operand;
2454 586 : while (TREE_CODE (*op) == COMPOUND_EXPR)
2455 7 : op = &TREE_OPERAND (*op, 1);
2456 579 : 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 579 : if (!cxx_mark_addressable (*op))
2469 0 : operand = error_mark_node;
2470 : }
2471 16740 : 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 17319 : 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 17319 : 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 17340 : 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 17223 : 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 17340 : TREE_VALUE (t) = operand;
2551 : }
2552 : }
2553 :
2554 32507 : r = build_stmt (loc, ASM_EXPR, string,
2555 : output_operands, input_operands,
2556 : clobbers, labels);
2557 32507 : ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
2558 32507 : ASM_INLINE_P (r) = inline_p;
2559 32507 : if (toplev_p)
2560 : {
2561 99 : symtab->finalize_toplevel_asm (r);
2562 99 : return r;
2563 : }
2564 32408 : r = maybe_cleanup_point_expr_void (r);
2565 32408 : return add_stmt (r);
2566 : }
2567 :
2568 : /* Finish a label with the indicated NAME. Returns the new label. */
2569 :
2570 : tree
2571 2539 : finish_label_stmt (tree name)
2572 : {
2573 2539 : tree decl = define_label (input_location, name);
2574 :
2575 2539 : if (decl == error_mark_node)
2576 : return error_mark_node;
2577 :
2578 2533 : add_stmt (build_stmt (input_location, LABEL_EXPR, decl));
2579 :
2580 2533 : 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 3635455 : finish_decl_cleanup (tree decl, tree cleanup)
2603 : {
2604 3635455 : push_cleanup (decl, cleanup, false);
2605 3635455 : }
2606 :
2607 : /* If the current scope exits with an exception, run CLEANUP. */
2608 :
2609 : void
2610 2289851 : finish_eh_cleanup (tree cleanup)
2611 : {
2612 2289851 : push_cleanup (NULL, cleanup, true);
2613 2289851 : }
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 21104579 : 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 21104579 : mem_inits = nreverse (mem_inits);
2625 :
2626 21104579 : if (processing_template_decl)
2627 : {
2628 : tree mem;
2629 :
2630 35693397 : 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 21119994 : if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION
2638 21119994 : && check_for_bare_parameter_packs (TREE_VALUE (mem)))
2639 3 : TREE_VALUE (mem) = error_mark_node;
2640 : }
2641 :
2642 14573403 : add_stmt (build_min_nt_loc (UNKNOWN_LOCATION,
2643 : CTOR_INITIALIZER, mem_inits));
2644 : }
2645 : else
2646 6531176 : emit_mem_initializers (mem_inits);
2647 21104579 : }
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 46600464 : force_paren_expr (tree expr, bool even_uneval /* = false */)
2655 : {
2656 : /* This is only needed for decltype(auto) in C++14. */
2657 46600464 : 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 45953714 : if (cp_unevaluated_operand && !even_uneval)
2663 : return expr;
2664 :
2665 38195952 : if (TREE_CODE (expr) == COMPONENT_REF
2666 38133646 : || TREE_CODE (expr) == SCOPE_REF
2667 76322672 : || REFERENCE_REF_P (expr))
2668 627784 : REF_PARENTHESIZED_P (expr) = true;
2669 37568168 : else if (DECL_P (tree_strip_any_location_wrapper (expr)))
2670 : {
2671 1800130 : location_t loc = cp_expr_location (expr);
2672 1800130 : const tree_code code = processing_template_decl ? PAREN_EXPR
2673 : : VIEW_CONVERT_EXPR;
2674 1800130 : expr = build1_loc (loc, code, TREE_TYPE (expr), expr);
2675 1800130 : 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 1028977959 : maybe_undo_parenthesized_ref (tree t)
2686 : {
2687 1028977959 : if (cxx_dialect < cxx14)
2688 : return t;
2689 :
2690 1018783859 : if ((TREE_CODE (t) == PAREN_EXPR || TREE_CODE (t) == VIEW_CONVERT_EXPR)
2691 1129657348 : && REF_PARENTHESIZED_P (t))
2692 206115 : t = TREE_OPERAND (t, 0);
2693 :
2694 : return t;
2695 : }
2696 :
2697 : /* Finish a parenthesized expression EXPR. */
2698 :
2699 : cp_expr
2700 34673706 : finish_parenthesized_expr (cp_expr expr)
2701 : {
2702 34673706 : if (EXPR_P (expr))
2703 : {
2704 : /* This inhibits warnings in maybe_warn_unparenthesized_assignment
2705 : and c_common_truthvalue_conversion. */
2706 68933284 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wparentheses);
2707 : /* And maybe_warn_sizeof_array_div. */
2708 68933284 : suppress_warning (STRIP_REFERENCE_REF (*expr), OPT_Wsizeof_array_div);
2709 : }
2710 :
2711 34673706 : if (TREE_CODE (expr) == OFFSET_REF
2712 34673706 : || 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 31925 : PTRMEM_OK_P (expr) = 0;
2716 :
2717 34673706 : tree stripped_expr = tree_strip_any_location_wrapper (expr);
2718 34673706 : if (TREE_CODE (stripped_expr) == STRING_CST)
2719 890406 : PAREN_STRING_LITERAL_P (stripped_expr) = 1;
2720 33783300 : else if (TREE_CODE (stripped_expr) == PACK_INDEX_EXPR)
2721 1472 : PACK_INDEX_PARENTHESIZED_P (stripped_expr) = true;
2722 :
2723 34673706 : expr = cp_expr (force_paren_expr (expr), expr.get_location ());
2724 :
2725 34673706 : 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 80055281 : finish_non_static_data_member (tree decl, tree object, tree qualifying_scope,
2733 : tsubst_flags_t complain /* = tf_warning_or_error */)
2734 : {
2735 80055281 : gcc_assert (TREE_CODE (decl) == FIELD_DECL);
2736 80055281 : bool try_omp_private = !object && omp_private_member_map;
2737 69542421 : tree ret;
2738 :
2739 69542421 : if (!object)
2740 : {
2741 69542421 : tree scope = qualifying_scope;
2742 69542421 : if (scope == NULL_TREE)
2743 : {
2744 69530192 : scope = context_for_name_lookup (decl);
2745 69530192 : 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 69542418 : object = maybe_dummy_object (scope, NULL);
2753 : }
2754 :
2755 80055278 : object = maybe_resolve_dummy (object, true);
2756 80055278 : 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 80055275 : if (is_dummy_object (object)
2762 36251 : && !cp_unevaluated_operand
2763 80055381 : && (!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 80055184 : if (current_class_ptr)
2788 79723037 : TREE_USED (current_class_ptr) = 1;
2789 80055184 : if (processing_template_decl)
2790 : {
2791 63697338 : tree type = TREE_TYPE (decl);
2792 :
2793 63697338 : if (TYPE_REF_P (type))
2794 : /* Quals on the object don't matter. */;
2795 61264870 : else if (PACK_EXPANSION_P (type))
2796 : /* Don't bother trying to represent this. */
2797 : type = NULL_TREE;
2798 61261850 : 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 61257302 : int quals = cp_type_quals (TREE_TYPE (object));
2812 :
2813 61257302 : if (DECL_MUTABLE_P (decl))
2814 245212 : quals &= ~TYPE_QUAL_CONST;
2815 :
2816 61257302 : quals |= cp_type_quals (TREE_TYPE (decl));
2817 61257302 : type = cp_build_qualified_type (type, quals);
2818 : }
2819 :
2820 63697338 : if (qualifying_scope)
2821 : /* Wrap this in a SCOPE_REF for now. */
2822 9551 : ret = build_qualified_name (type, qualifying_scope, decl,
2823 : /*template_p=*/false);
2824 : else
2825 63687787 : ret = (convert_from_reference
2826 63687787 : (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 16357846 : tree access_type = TREE_TYPE (object);
2833 :
2834 16357846 : 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 16357846 : if (qualifying_scope)
2841 : {
2842 2631 : tree binfo = NULL_TREE;
2843 2631 : object = build_scoped_ref (object, qualifying_scope,
2844 : &binfo);
2845 : }
2846 :
2847 16357846 : ret = build_class_member_access_expr (object, decl,
2848 : /*access_path=*/NULL_TREE,
2849 : /*preserve_reference=*/false,
2850 : complain);
2851 : }
2852 80055184 : 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 5020654733 : 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 5020654733 : if (deferred_access_no_check)
2876 : return true;
2877 :
2878 : /* Determine the SCOPE of DECL. */
2879 5009379171 : tree scope = context_for_name_lookup (decl);
2880 : /* If the SCOPE is not a type, then DECL is not a member. */
2881 5009379171 : 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 5009379171 : || dependent_type_p (scope))
2886 : return true;
2887 :
2888 479584846 : tree qualifying_type = NULL_TREE;
2889 : /* Compute the scope through which DECL is being accessed. */
2890 479584846 : 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 101948 : && CLASS_TYPE_P (object_type)
2900 479686777 : && 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 101922 : if (tree open = currently_open_class (object_type))
2905 : qualifying_type = open;
2906 : else
2907 : qualifying_type = object_type;
2908 : }
2909 479482924 : 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 638908187 : if (DECL_NONSTATIC_MEMBER_P (decl)
2915 319507056 : && current_class_ptr)
2916 42107 : if (tree current = current_nonlambda_class_type ())
2917 : {
2918 42062 : 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 4199 : 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 160028829 : qualifying_type = currently_open_derived_class (scope);
2938 :
2939 479483017 : 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 479546983 : && CLASS_TYPE_P (qualifying_type))
2943 451170352 : return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl,
2944 451170352 : 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 86522806 : 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 86522806 : gcc_assert (TYPE_P (qualifying_class));
2967 :
2968 86522806 : if (error_operand_p (expr))
2969 21 : return error_mark_node;
2970 :
2971 86522785 : if (DECL_P (expr)
2972 : /* Functions are marked after overload resolution; avoid redundant
2973 : warnings. */
2974 79210396 : && TREE_CODE (expr) != FUNCTION_DECL
2975 165733157 : && !mark_used (expr, complain))
2976 0 : return error_mark_node;
2977 :
2978 86522785 : if (template_p)
2979 : {
2980 263948 : 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 263939 : 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 86522785 : if (address_p && done
2994 164081 : && TREE_CODE (qualifying_class) != ENUMERAL_TYPE)
2995 : {
2996 164079 : if (TREE_CODE (expr) == SCOPE_REF)
2997 0 : expr = TREE_OPERAND (expr, 1);
2998 164079 : expr = build_offset_ref (qualifying_class, expr,
2999 : /*address_p=*/true, complain);
3000 164079 : return expr;
3001 : }
3002 :
3003 : /* No need to check access within an enum. */
3004 86358706 : if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE
3005 3817664 : && 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 82541045 : 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 82538381 : else if (TREE_CODE (expr) == FIELD_DECL)
3015 : {
3016 12229 : push_deferring_access_checks (dk_no_check);
3017 12229 : expr = finish_non_static_data_member (expr, NULL_TREE,
3018 : qualifying_class, complain);
3019 12229 : pop_deferring_access_checks ();
3020 : }
3021 82526152 : 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 6822939 : if (!shared_member_p (expr)
3026 455360 : && current_class_ptr
3027 7277612 : && DERIVED_FROM_P (qualifying_class,
3028 : current_nonlambda_class_type ()))
3029 454359 : expr = (build_class_member_access_expr
3030 454359 : (maybe_dummy_object (qualifying_class, NULL),
3031 : expr,
3032 454359 : BASELINK_ACCESS_BINFO (expr),
3033 : /*preserve_reference=*/false,
3034 : complain));
3035 6368580 : else if (done)
3036 : /* The expression is a qualified name whose address is not
3037 : being taken. */
3038 3585 : expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
3039 : complain);
3040 : }
3041 75703213 : else if (!template_p
3042 75489291 : && TREE_CODE (expr) == TEMPLATE_DECL
3043 75703297 : && !DECL_FUNCTION_TEMPLATE_P (expr))
3044 : {
3045 84 : if (complain & tf_error)
3046 5 : error ("%qE missing template arguments", expr);
3047 84 : 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 75703129 : if (processing_template_decl
3057 75703129 : && (!currently_open_class (qualifying_class)
3058 10673 : || TREE_CODE (expr) == IDENTIFIER_NODE
3059 10673 : || TREE_CODE (expr) == TEMPLATE_ID_EXPR
3060 82 : || TREE_CODE (expr) == BIT_NOT_EXPR))
3061 11151322 : expr = build_qualified_name (TREE_TYPE (expr),
3062 : qualifying_class, expr,
3063 : template_p);
3064 64551807 : else if (tree wrap = maybe_get_tls_wrapper_call (expr))
3065 9 : expr = wrap;
3066 :
3067 75703129 : 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 5684274 : begin_stmt_expr (void)
3078 : {
3079 5684274 : 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 29107 : finish_stmt_expr_expr (tree expr, tree stmt_expr)
3089 : {
3090 29107 : 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 29104 : if (expr)
3101 : {
3102 29089 : tree type = TREE_TYPE (expr);
3103 :
3104 29089 : 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 29074 : 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 28905 : 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 28874 : expr = force_rvalue (expr, tf_warning_or_error);
3131 28874 : if (error_operand_p (expr))
3132 0 : return error_mark_node;
3133 :
3134 : /* Update for array-to-pointer decay. */
3135 28874 : type = TREE_TYPE (expr);
3136 :
3137 : /* This TARGET_EXPR will initialize the outer one added by
3138 : finish_stmt_expr. */
3139 28874 : 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 28874 : if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
3145 28874 : expr = maybe_cleanup_point_expr (expr);
3146 28874 : add_stmt (expr);
3147 : }
3148 :
3149 : /* The type of the statement-expression is the type of the last
3150 : expression. */
3151 29074 : 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 5684274 : finish_stmt_expr (tree stmt_expr, bool has_no_scope)
3163 : {
3164 5684274 : tree type;
3165 5684274 : tree result;
3166 :
3167 5684274 : if (error_operand_p (stmt_expr))
3168 : {
3169 18 : pop_stmt_list (stmt_expr);
3170 18 : return error_mark_node;
3171 : }
3172 :
3173 5684256 : gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST);
3174 :
3175 5684256 : type = TREE_TYPE (stmt_expr);
3176 5684256 : result = pop_stmt_list (stmt_expr);
3177 5684256 : TREE_TYPE (result) = type;
3178 :
3179 5684256 : if (processing_template_decl)
3180 : {
3181 38181 : result = build_min (STMT_EXPR, type, result);
3182 38181 : TREE_SIDE_EFFECTS (result) = 1;
3183 38181 : STMT_EXPR_NO_SCOPE (result) = has_no_scope;
3184 : }
3185 5646075 : 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 64208906 : empty_expr_stmt_p (tree expr_stmt)
3221 : {
3222 64208911 : tree body = NULL_TREE;
3223 :
3224 64208911 : if (expr_stmt == void_node)
3225 : return true;
3226 :
3227 64208908 : if (expr_stmt)
3228 : {
3229 64208908 : if (TREE_CODE (expr_stmt) == EXPR_STMT)
3230 5 : body = EXPR_STMT_EXPR (expr_stmt);
3231 64208903 : else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
3232 : body = expr_stmt;
3233 : }
3234 :
3235 5 : if (body)
3236 : {
3237 63217868 : if (TREE_CODE (body) == STATEMENT_LIST)
3238 63217863 : 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 19380267 : perform_koenig_lookup (cp_expr fn_expr, vec<tree, va_gc> *args,
3251 : tsubst_flags_t complain)
3252 : {
3253 19380267 : tree identifier = NULL_TREE;
3254 19380267 : tree functions = NULL_TREE;
3255 19380267 : tree tmpl_args = NULL_TREE;
3256 19380267 : bool template_id = false;
3257 19380267 : location_t loc = fn_expr.get_location ();
3258 19380267 : tree fn = fn_expr.get_value ();
3259 :
3260 19380267 : STRIP_ANY_LOCATION_WRAPPER (fn);
3261 :
3262 19380267 : if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
3263 : {
3264 : /* Use a separate flag to handle null args. */
3265 3727878 : template_id = true;
3266 3727878 : tmpl_args = TREE_OPERAND (fn, 1);
3267 3727878 : fn = TREE_OPERAND (fn, 0);
3268 : }
3269 :
3270 : /* Find the name of the overloaded function. */
3271 19380267 : if (identifier_p (fn))
3272 : identifier = fn;
3273 : else
3274 : {
3275 27387180 : functions = fn;
3276 19179693 : 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 19380267 : if (!any_type_dependent_arguments_p (args)
3284 19380267 : && !any_dependent_template_arguments_p (tmpl_args))
3285 : {
3286 18502499 : fn = lookup_arg_dependent (identifier, functions, args);
3287 18502499 : if (!fn)
3288 : {
3289 : /* The unqualified name could not be resolved. */
3290 59530 : if (complain & tf_error)
3291 391 : fn = unqualified_fn_lookup_error (cp_expr (identifier, loc));
3292 : else
3293 : fn = identifier;
3294 : }
3295 : }
3296 :
3297 19380267 : if (fn && template_id && fn != error_mark_node)
3298 3727865 : fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args);
3299 :
3300 19380267 : return cp_expr (fn, loc);
3301 : }
3302 :
3303 : /* Analyze call to a front-end builtin FN with arguments *ARGS. Return true
3304 : if the call is correct, false if erroneous. */
3305 :
3306 : static bool
3307 129114 : check_frontend_builtin (tree fn, vec<tree, va_gc> **args,
3308 : tsubst_flags_t complain)
3309 : {
3310 129114 : tree arg, ptype, type;
3311 129114 : switch (DECL_UNCHECKED_FUNCTION_CODE (fn))
3312 : {
3313 860 : case CP_BUILT_IN_IS_WITHIN_LIFETIME:
3314 860 : case CP_BUILT_IN_START_LIFETIME:
3315 : /* Unless users call the builtin directly, the following 2 checks
3316 : should be ensured from std::is_within_lifetime or
3317 : std::start_lifetime template. */
3318 860 : if (vec_safe_length (*args) != 1)
3319 : {
3320 14 : if (complain & tf_error)
3321 14 : error ("%qE needs a single argument", DECL_NAME (fn));
3322 : return false;
3323 : }
3324 846 : arg = (**args)[0];
3325 846 : if (error_operand_p (arg))
3326 : return false;
3327 846 : ptype = TREE_TYPE (arg);
3328 846 : if (!POINTER_TYPE_P (ptype))
3329 : {
3330 13 : if (complain & tf_error)
3331 13 : error ("%qE argument type %qT is not pointer type",
3332 13 : DECL_NAME (fn), ptype);
3333 : return false;
3334 : }
3335 833 : if (DECL_UNCHECKED_FUNCTION_CODE (fn) == CP_BUILT_IN_IS_WITHIN_LIFETIME)
3336 : return true;
3337 343 : type = TREE_TYPE (ptype);
3338 343 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
3339 : return false;
3340 343 : if (!CP_AGGREGATE_TYPE_P (type))
3341 : {
3342 10 : if (complain & tf_error)
3343 10 : error ("%qE argument type %qT is not a pointer to aggregate type",
3344 10 : DECL_NAME (fn), ptype);
3345 : return false;
3346 : }
3347 333 : if (!implicit_lifetime_type_p (type))
3348 : {
3349 4 : if (complain & tf_error)
3350 4 : error ("%qE argument type %qT is not a pointer to "
3351 4 : "implicit-lifetime type", DECL_NAME (fn), ptype);
3352 : return false;
3353 : }
3354 : return true;
3355 : default:
3356 : return true;
3357 : }
3358 : }
3359 :
3360 : /* Generate an expression for `FN (ARGS)'. This may change the
3361 : contents of ARGS.
3362 :
3363 : If DISALLOW_VIRTUAL is true, the call to FN will be not generated
3364 : as a virtual call, even if FN is virtual. (This flag is set when
3365 : encountering an expression where the function name is explicitly
3366 : qualified. For example a call to `X::f' never generates a virtual
3367 : call.)
3368 :
3369 : Returns code for the call. */
3370 :
3371 : tree
3372 377103330 : finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
3373 : bool koenig_p, tsubst_flags_t complain)
3374 : {
3375 377103330 : tree result;
3376 377103330 : tree orig_fn;
3377 377103330 : vec<tree, va_gc> *orig_args = *args;
3378 377103330 : tsubst_flags_t orig_complain = complain;
3379 :
3380 377103330 : if (fn == error_mark_node)
3381 : return error_mark_node;
3382 :
3383 377102262 : complain &= ~tf_any_viable;
3384 377102262 : gcc_assert (!TYPE_P (fn));
3385 :
3386 : /* If FN may be a FUNCTION_DECL obfuscated by force_paren_expr, undo
3387 : it so that we can tell this is a call to a known function. */
3388 377102262 : fn = maybe_undo_parenthesized_ref (fn);
3389 :
3390 377102262 : STRIP_ANY_LOCATION_WRAPPER (fn);
3391 :
3392 377102262 : orig_fn = fn;
3393 :
3394 377102262 : if (concept_check_p (fn))
3395 : {
3396 6 : error_at (EXPR_LOC_OR_LOC (fn, input_location),
3397 : "cannot call a concept as a function");
3398 6 : return error_mark_node;
3399 : }
3400 :
3401 377102256 : if (processing_template_decl)
3402 : {
3403 : /* If FN is a local extern declaration (or set thereof) in a template,
3404 : look it up again at instantiation time. */
3405 243220069 : if (is_overloaded_fn (fn))
3406 : {
3407 149088179 : tree ifn = get_first_fn (fn);
3408 149088179 : if (TREE_CODE (ifn) == FUNCTION_DECL
3409 149088179 : && dependent_local_decl_p (ifn))
3410 41203 : orig_fn = DECL_NAME (ifn);
3411 : }
3412 :
3413 : /* If the call expression is dependent, build a CALL_EXPR node
3414 : with no type; type_dependent_expression_p recognizes
3415 : expressions with no type as being dependent. */
3416 243220069 : if (type_dependent_expression_p (fn)
3417 243220069 : || any_type_dependent_arguments_p (*args))
3418 : {
3419 221153977 : if (koenig_p
3420 10793615 : && TREE_CODE (orig_fn) == FUNCTION_DECL
3421 224545280 : && !fndecl_built_in_p (orig_fn))
3422 : /* For an ADL-enabled call where unqualified lookup found a
3423 : single non-template function, wrap it in an OVERLOAD so that
3424 : later substitution doesn't overeagerly mark the function as
3425 : used. */
3426 881027 : orig_fn = ovl_make (orig_fn, NULL_TREE);
3427 221153977 : result = build_min_nt_call_vec (orig_fn, *args);
3428 300609113 : SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
3429 221153977 : KOENIG_LOOKUP_P (result) = koenig_p;
3430 : /* Disable the std::move warnings since this call was dependent
3431 : (c++/89780, c++/107363). This also suppresses the
3432 : -Wredundant-move warning. */
3433 221153977 : suppress_warning (result, OPT_Wpessimizing_move);
3434 :
3435 221153977 : if (cfun && cp_function_chain && !cp_unevaluated_operand)
3436 : {
3437 192609693 : bool abnormal = true;
3438 192895064 : for (lkp_iterator iter (maybe_get_fns (fn)); iter; ++iter)
3439 : {
3440 106924812 : tree fndecl = STRIP_TEMPLATE (*iter);
3441 106924812 : if (TREE_CODE (fndecl) != FUNCTION_DECL
3442 106924734 : || !TREE_THIS_VOLATILE (fndecl))
3443 : {
3444 : abnormal = false;
3445 : break;
3446 : }
3447 : }
3448 : /* FIXME: Stop warning about falling off end of non-void
3449 : function. But this is wrong. Even if we only see
3450 : no-return fns at this point, we could select a
3451 : future-defined return fn during instantiation. Or
3452 : vice-versa. */
3453 192609693 : if (abnormal)
3454 85970252 : current_function_returns_abnormally = 1;
3455 : }
3456 221153977 : if (TREE_CODE (fn) == COMPONENT_REF)
3457 102338450 : maybe_generic_this_capture (TREE_OPERAND (fn, 0),
3458 102338450 : TREE_OPERAND (fn, 1));
3459 : return result;
3460 : }
3461 22066092 : orig_args = make_tree_vector_copy (*args);
3462 : }
3463 :
3464 155948279 : if (TREE_CODE (fn) == COMPONENT_REF)
3465 : {
3466 29806479 : tree member = TREE_OPERAND (fn, 1);
3467 29806479 : if (BASELINK_P (member))
3468 : {
3469 29615932 : tree object = TREE_OPERAND (fn, 0);
3470 58816227 : return build_new_method_call (object, member,
3471 : args, NULL_TREE,
3472 : (disallow_virtual
3473 : ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL
3474 : : LOOKUP_NORMAL),
3475 : /*fn_p=*/NULL,
3476 29615932 : complain);
3477 : }
3478 : }
3479 :
3480 : /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */
3481 126332347 : if (TREE_CODE (fn) == ADDR_EXPR
3482 126332347 : && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD)
3483 9 : fn = TREE_OPERAND (fn, 0);
3484 :
3485 126332347 : if (is_overloaded_fn (fn))
3486 117387728 : fn = baselink_for_fns (fn);
3487 :
3488 126332347 : result = NULL_TREE;
3489 126332347 : if (BASELINK_P (fn))
3490 : {
3491 14350570 : tree object;
3492 :
3493 : /* A call to a member function. From [over.call.func]:
3494 :
3495 : If the keyword this is in scope and refers to the class of
3496 : that member function, or a derived class thereof, then the
3497 : function call is transformed into a qualified function call
3498 : using (*this) as the postfix-expression to the left of the
3499 : . operator.... [Otherwise] a contrived object of type T
3500 : becomes the implied object argument.
3501 :
3502 : In this situation:
3503 :
3504 : struct A { void f(); };
3505 : struct B : public A {};
3506 : struct C : public A { void g() { B::f(); }};
3507 :
3508 : "the class of that member function" refers to `A'. But 11.2
3509 : [class.access.base] says that we need to convert 'this' to B* as
3510 : part of the access, so we pass 'B' to maybe_dummy_object. */
3511 :
3512 14350570 : if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn)))
3513 : {
3514 : /* A constructor call always uses a dummy object. (This constructor
3515 : call which has the form A::A () is actually invalid and we are
3516 : going to reject it later in build_new_method_call.) */
3517 39 : object = build_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)));
3518 : }
3519 : else
3520 14350531 : object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
3521 : NULL);
3522 :
3523 16382785 : result = build_new_method_call (object, fn, args, NULL_TREE,
3524 : (disallow_virtual
3525 : ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
3526 : : LOOKUP_NORMAL),
3527 : /*fn_p=*/NULL,
3528 : complain);
3529 : }
3530 111981777 : else if (is_overloaded_fn (fn))
3531 : {
3532 : /* If the function is an overloaded builtin, resolve it. */
3533 103037158 : if (TREE_CODE (fn) == FUNCTION_DECL
3534 103037158 : && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
3535 19198828 : || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
3536 9699588 : result = resolve_overloaded_builtin (input_location, fn, *args,
3537 : complain & tf_error);
3538 :
3539 9699588 : if (!result)
3540 : {
3541 102689477 : tree alloc_size_attr = NULL_TREE;
3542 102689477 : if (warn_calloc_transposed_args
3543 715291 : && TREE_CODE (fn) == FUNCTION_DECL
3544 102689477 : && (alloc_size_attr
3545 432590 : = lookup_attribute ("alloc_size",
3546 432590 : TYPE_ATTRIBUTES (TREE_TYPE (fn)))))
3547 3399 : if (TREE_VALUE (alloc_size_attr) == NULL_TREE
3548 3399 : || TREE_CHAIN (TREE_VALUE (alloc_size_attr)) == NULL_TREE)
3549 : alloc_size_attr = NULL_TREE;
3550 100947243 : if ((warn_sizeof_pointer_memaccess || alloc_size_attr)
3551 1742294 : && (complain & tf_warning)
3552 1521450 : && !vec_safe_is_empty (*args)
3553 103856942 : && !processing_template_decl)
3554 : {
3555 : location_t sizeof_arg_loc[6];
3556 : tree sizeof_arg[6];
3557 : unsigned int i;
3558 8390716 : for (i = 0; i < (alloc_size_attr ? 6 : 3); i++)
3559 : {
3560 3146721 : tree t;
3561 :
3562 3146721 : sizeof_arg_loc[i] = UNKNOWN_LOCATION;
3563 3146721 : sizeof_arg[i] = NULL_TREE;
3564 3146721 : if (i >= (*args)->length ())
3565 657443 : continue;
3566 2489278 : t = (**args)[i];
3567 2489278 : if (TREE_CODE (t) != SIZEOF_EXPR)
3568 2482603 : continue;
3569 6675 : if (SIZEOF_EXPR_TYPE_P (t))
3570 2663 : sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
3571 : else
3572 4012 : sizeof_arg[i] = TREE_OPERAND (t, 0);
3573 6675 : sizeof_arg_loc[i] = EXPR_LOCATION (t);
3574 : }
3575 1048847 : if (warn_sizeof_pointer_memaccess)
3576 : {
3577 1048787 : auto same_p = same_type_ignoring_top_level_qualifiers_p;
3578 1048787 : sizeof_pointer_memaccess_warning (sizeof_arg_loc, fn, *args,
3579 : sizeof_arg, same_p);
3580 : }
3581 1048847 : if (alloc_size_attr)
3582 60 : warn_for_calloc (sizeof_arg_loc, fn, *args, sizeof_arg,
3583 : alloc_size_attr);
3584 : }
3585 :
3586 102689477 : if ((complain & tf_warning)
3587 56735943 : && TREE_CODE (fn) == FUNCTION_DECL
3588 27146415 : && fndecl_built_in_p (fn, BUILT_IN_MEMSET)
3589 147845 : && vec_safe_length (*args) == 3
3590 102837322 : && !any_type_dependent_arguments_p (*args))
3591 : {
3592 147845 : tree arg0 = (*orig_args)[0];
3593 147845 : tree arg1 = (*orig_args)[1];
3594 147845 : tree arg2 = (*orig_args)[2];
3595 147845 : int literal_mask = ((literal_integer_zerop (arg1) << 1)
3596 147845 : | (literal_integer_zerop (arg2) << 2));
3597 147845 : warn_for_memset (input_location, arg0, arg2, literal_mask);
3598 : }
3599 :
3600 102689477 : if (TREE_CODE (fn) == FUNCTION_DECL
3601 27273683 : && fndecl_built_in_p (fn, BUILT_IN_FRONTEND)
3602 102818591 : && !check_frontend_builtin (fn, args, complain))
3603 41 : return error_mark_node;
3604 :
3605 : /* A call to a namespace-scope function. */
3606 102689436 : result = build_new_function_call (fn, args, orig_complain);
3607 : }
3608 : }
3609 8944619 : else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
3610 : {
3611 162250 : if (!vec_safe_is_empty (*args))
3612 0 : error ("arguments to destructor are not allowed");
3613 : /* C++20/DR: If the postfix-expression names a pseudo-destructor (in
3614 : which case the postfix-expression is a possibly-parenthesized class
3615 : member access), the function call destroys the object of scalar type
3616 : denoted by the object expression of the class member access. */
3617 162250 : tree ob = TREE_OPERAND (fn, 0);
3618 162250 : if (obvalue_p (ob))
3619 162232 : result = build_trivial_dtor_call (ob, true);
3620 : else
3621 : /* No location to clobber. */
3622 18 : result = convert_to_void (ob, ICV_STATEMENT, complain);
3623 : }
3624 8782369 : else if (CLASS_TYPE_P (TREE_TYPE (fn)))
3625 : /* If the "function" is really an object of class type, it might
3626 : have an overloaded `operator ()'. */
3627 2645913 : result = build_op_call (fn, args, complain);
3628 :
3629 119834651 : if (!result)
3630 : /* A call where the function is unknown. */
3631 6136456 : result = cp_build_function_call_vec (fn, args, complain);
3632 :
3633 126318788 : if (processing_template_decl && result != error_mark_node)
3634 : {
3635 16895580 : if (INDIRECT_REF_P (result))
3636 1149880 : result = TREE_OPERAND (result, 0);
3637 :
3638 : /* Prune all but the selected function from the original overload
3639 : set so that we can avoid some duplicate work at instantiation time. */
3640 16895580 : if (TREE_CODE (result) == CALL_EXPR
3641 16885789 : && really_overloaded_fn (orig_fn))
3642 : {
3643 6236561 : tree sel_fn = CALL_EXPR_FN (result);
3644 6236561 : if (TREE_CODE (sel_fn) == COMPONENT_REF)
3645 : {
3646 : /* The non-dependent result of build_new_method_call. */
3647 262778 : sel_fn = TREE_OPERAND (sel_fn, 1);
3648 262778 : gcc_assert (BASELINK_P (sel_fn));
3649 : }
3650 5973783 : else if (TREE_CODE (sel_fn) == ADDR_EXPR)
3651 : /* Our original callee wasn't wrapped in an ADDR_EXPR,
3652 : so strip this ADDR_EXPR added by build_over_call. */
3653 5973783 : sel_fn = TREE_OPERAND (sel_fn, 0);
3654 : orig_fn = sel_fn;
3655 : }
3656 :
3657 16895580 : tree r = build_call_vec (TREE_TYPE (result), orig_fn, orig_args);
3658 16895580 : SET_EXPR_LOCATION (r, input_location);
3659 16895580 : KOENIG_LOOKUP_P (r) = koenig_p;
3660 16895580 : TREE_NO_WARNING (r) = TREE_NO_WARNING (result);
3661 16895580 : release_tree_vector (orig_args);
3662 16895580 : result = convert_from_reference (r);
3663 : }
3664 :
3665 : return result;
3666 : }
3667 :
3668 : /* Finish a call to a postfix increment or decrement or EXPR. (Which
3669 : is indicated by CODE, which should be POSTINCREMENT_EXPR or
3670 : POSTDECREMENT_EXPR.) */
3671 :
3672 : cp_expr
3673 2706024 : finish_increment_expr (cp_expr expr, enum tree_code code)
3674 : {
3675 : /* input_location holds the location of the trailing operator token.
3676 : Build a location of the form:
3677 : expr++
3678 : ~~~~^~
3679 : with the caret at the operator token, ranging from the start
3680 : of EXPR to the end of the operator token. */
3681 2706024 : location_t combined_loc = make_location (input_location,
3682 : expr.get_start (),
3683 : get_finish (input_location));
3684 2706024 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3685 2706024 : NULL_TREE, tf_warning_or_error);
3686 : /* TODO: build_x_unary_op doesn't honor the location, so set it here. */
3687 2706024 : result.set_location (combined_loc);
3688 2706024 : return result;
3689 : }
3690 :
3691 : /* Finish a use of `this'. Returns an expression for `this'. */
3692 :
3693 : tree
3694 37409854 : finish_this_expr (void)
3695 : {
3696 37409854 : tree result = NULL_TREE;
3697 :
3698 74819584 : if (current_class_ref && !LAMBDA_TYPE_P (TREE_TYPE (current_class_ref)))
3699 37107820 : result = current_class_ptr;
3700 604052 : else if (current_class_type && LAMBDA_TYPE_P (current_class_type))
3701 301958 : result = (lambda_expr_this_capture
3702 301958 : (CLASSTYPE_LAMBDA_EXPR (current_class_type), /*add*/true));
3703 : else
3704 76 : gcc_checking_assert (!current_class_ptr);
3705 :
3706 37409778 : if (result)
3707 : /* The keyword 'this' is a prvalue expression. */
3708 37409775 : return rvalue (result);
3709 :
3710 79 : tree fn = current_nonlambda_function ();
3711 79 : if (fn && DECL_XOBJ_MEMBER_FUNCTION_P (fn))
3712 : {
3713 6 : auto_diagnostic_group d;
3714 6 : error ("%<this%> is unavailable for explicit object member "
3715 : "functions");
3716 6 : tree xobj_parm = DECL_ARGUMENTS (fn);
3717 6 : gcc_assert (xobj_parm);
3718 6 : tree parm_name = DECL_NAME (xobj_parm);
3719 :
3720 6 : static tree remembered_fn = NULL_TREE;
3721 : /* Only output this diagnostic once per function. */
3722 6 : if (remembered_fn == fn)
3723 : /* Early escape. */;
3724 6 : else if (parm_name)
3725 6 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3726 : "use explicit object parameter %qs instead",
3727 3 : IDENTIFIER_POINTER (parm_name));
3728 : else
3729 3 : inform (DECL_SOURCE_LOCATION (xobj_parm),
3730 : "name the explicit object parameter");
3731 :
3732 6 : remembered_fn = fn;
3733 6 : }
3734 73 : else if (fn && DECL_STATIC_FUNCTION_P (fn))
3735 3 : error ("%<this%> is unavailable for static member functions");
3736 70 : else if (fn && processing_contract_condition && DECL_CONSTRUCTOR_P (fn))
3737 0 : error ("invalid use of %<this%> in a constructor %<pre%> condition");
3738 70 : else if (fn && processing_contract_condition && DECL_DESTRUCTOR_P (fn))
3739 0 : error ("invalid use of %<this%> in a destructor %<post%> condition");
3740 70 : else if (fn)
3741 22 : error ("invalid use of %<this%> in non-member function");
3742 : else
3743 48 : error ("invalid use of %<this%> at top level");
3744 79 : return error_mark_node;
3745 : }
3746 :
3747 : /* Finish a pseudo-destructor expression. If SCOPE is NULL, the
3748 : expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
3749 : the TYPE for the type given. If SCOPE is non-NULL, the expression
3750 : was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
3751 :
3752 : tree
3753 162301 : finish_pseudo_destructor_expr (tree object, tree scope, tree destructor,
3754 : location_t loc, tsubst_flags_t complain)
3755 : {
3756 162301 : if (object == error_mark_node || destructor == error_mark_node)
3757 : return error_mark_node;
3758 :
3759 162292 : gcc_assert (TYPE_P (destructor));
3760 :
3761 162292 : if (!processing_template_decl)
3762 : {
3763 162271 : if (scope == error_mark_node)
3764 : {
3765 0 : if (complain & tf_error)
3766 0 : error_at (loc, "invalid qualifying scope in pseudo-destructor name");
3767 0 : return error_mark_node;
3768 : }
3769 162271 : if (is_auto (destructor))
3770 3 : destructor = TREE_TYPE (object);
3771 162271 : if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor))
3772 : {
3773 3 : if (complain & tf_error)
3774 3 : error_at (loc,
3775 : "qualified type %qT does not match destructor name ~%qT",
3776 : scope, destructor);
3777 3 : return error_mark_node;
3778 : }
3779 :
3780 :
3781 : /* [expr.pseudo] says both:
3782 :
3783 : The type designated by the pseudo-destructor-name shall be
3784 : the same as the object type.
3785 :
3786 : and:
3787 :
3788 : The cv-unqualified versions of the object type and of the
3789 : type designated by the pseudo-destructor-name shall be the
3790 : same type.
3791 :
3792 : We implement the more generous second sentence, since that is
3793 : what most other compilers do. */
3794 162268 : if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
3795 : destructor))
3796 : {
3797 12 : if (complain & tf_error)
3798 9 : error_at (loc, "%qE is not of type %qT", object, destructor);
3799 12 : return error_mark_node;
3800 : }
3801 : }
3802 :
3803 162277 : tree type = (type_dependent_expression_p (object)
3804 162277 : ? NULL_TREE : void_type_node);
3805 :
3806 162277 : return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object,
3807 162277 : scope, destructor);
3808 : }
3809 :
3810 : /* Finish an expression of the form CODE EXPR. */
3811 :
3812 : cp_expr
3813 39716587 : finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr,
3814 : tsubst_flags_t complain)
3815 : {
3816 : /* Build a location of the form:
3817 : ++expr
3818 : ^~~~~~
3819 : with the caret at the operator token, ranging from the start
3820 : of the operator token to the end of EXPR. */
3821 39716587 : location_t combined_loc = make_location (op_loc,
3822 : op_loc, expr.get_finish ());
3823 39716587 : cp_expr result = build_x_unary_op (combined_loc, code, expr,
3824 39716587 : NULL_TREE, complain);
3825 : /* TODO: build_x_unary_op doesn't always honor the location. */
3826 39716587 : result.set_location (combined_loc);
3827 :
3828 39716587 : if (result == error_mark_node)
3829 : return result;
3830 :
3831 39716084 : if (!(complain & tf_warning))
3832 : return result;
3833 :
3834 : /* These will never fold into a constant, so no need to check for
3835 : overflow for them. */
3836 39716084 : if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
3837 : return result;
3838 :
3839 21474606 : tree result_ovl = result;
3840 21474606 : tree expr_ovl = expr;
3841 :
3842 21474606 : if (!processing_template_decl)
3843 1873984 : expr_ovl = cp_fully_fold (expr_ovl);
3844 :
3845 21474606 : if (!CONSTANT_CLASS_P (expr_ovl)
3846 21474606 : || TREE_OVERFLOW_P (expr_ovl))
3847 : return result;
3848 :
3849 261863 : if (!processing_template_decl)
3850 252173 : result_ovl = cp_fully_fold (result_ovl);
3851 :
3852 261863 : if (CONSTANT_CLASS_P (result_ovl) && TREE_OVERFLOW_P (result_ovl))
3853 9 : overflow_warning (combined_loc, result_ovl);
3854 :
3855 : return result;
3856 : }
3857 :
3858 : /* Return true if CONSTRUCTOR EXPR after pack expansion could have no
3859 : elements. */
3860 :
3861 : static bool
3862 12 : maybe_zero_constructor_nelts (tree expr)
3863 : {
3864 12 : if (CONSTRUCTOR_NELTS (expr) == 0)
3865 : return true;
3866 12 : if (!processing_template_decl)
3867 : return false;
3868 30 : for (constructor_elt &elt : CONSTRUCTOR_ELTS (expr))
3869 21 : if (!PACK_EXPANSION_P (elt.value))
3870 : return false;
3871 : return true;
3872 : }
3873 :
3874 : /* Finish a compound-literal expression or C++11 functional cast with aggregate
3875 : initializer. TYPE is the type to which the CONSTRUCTOR in COMPOUND_LITERAL
3876 : is being cast. */
3877 :
3878 : tree
3879 10088610 : finish_compound_literal (tree type, tree compound_literal,
3880 : tsubst_flags_t complain,
3881 : fcl_t fcl_context)
3882 : {
3883 10088610 : if (type == error_mark_node)
3884 : return error_mark_node;
3885 :
3886 10088558 : if (TYPE_REF_P (type))
3887 : {
3888 12 : compound_literal
3889 12 : = finish_compound_literal (TREE_TYPE (type), compound_literal,
3890 : complain, fcl_context);
3891 : /* The prvalue is then used to direct-initialize the reference. */
3892 12 : tree r = (perform_implicit_conversion_flags
3893 12 : (type, compound_literal, complain, LOOKUP_NORMAL));
3894 12 : return convert_from_reference (r);
3895 : }
3896 :
3897 10088546 : if (!TYPE_OBJ_P (type))
3898 : {
3899 : /* DR2351 */
3900 60 : if (VOID_TYPE_P (type) && CONSTRUCTOR_NELTS (compound_literal) == 0)
3901 : {
3902 12 : if (!processing_template_decl)
3903 9 : return void_node;
3904 3 : TREE_TYPE (compound_literal) = type;
3905 3 : TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
3906 3 : CONSTRUCTOR_IS_DEPENDENT (compound_literal) = 0;
3907 3 : return compound_literal;
3908 : }
3909 21 : else if (VOID_TYPE_P (type)
3910 15 : && processing_template_decl
3911 33 : && maybe_zero_constructor_nelts (compound_literal))
3912 : /* If there are only packs in compound_literal, it could
3913 : be void{} after pack expansion. */;
3914 : else
3915 : {
3916 12 : if (complain & tf_error)
3917 9 : error ("compound literal of non-object type %qT", type);
3918 12 : return error_mark_node;
3919 : }
3920 : }
3921 :
3922 10088522 : if (template_placeholder_p (type))
3923 : {
3924 194991 : type = do_auto_deduction (type, compound_literal, type, complain,
3925 : adc_variable_type);
3926 194991 : if (type == error_mark_node)
3927 : return error_mark_node;
3928 : }
3929 : /* C++23 auto{x}. */
3930 9893531 : else if (is_auto (type)
3931 162 : && !AUTO_IS_DECLTYPE (type)
3932 9893690 : && CONSTRUCTOR_NELTS (compound_literal) == 1)
3933 : {
3934 150 : if (is_constrained_auto (type))
3935 : {
3936 3 : if (complain & tf_error)
3937 3 : error ("%<auto{x}%> cannot be constrained");
3938 3 : return error_mark_node;
3939 : }
3940 147 : else if (cxx_dialect < cxx23)
3941 : {
3942 1 : if ((complain & tf_warning_or_error) == 0)
3943 0 : return error_mark_node;
3944 1 : pedwarn (input_location, OPT_Wc__23_extensions,
3945 : "%<auto{x}%> only available with "
3946 : "%<-std=c++23%> or %<-std=gnu++23%>");
3947 : }
3948 147 : type = do_auto_deduction (type, compound_literal, type, complain,
3949 : adc_variable_type);
3950 147 : if (type == error_mark_node)
3951 : return error_mark_node;
3952 : }
3953 :
3954 : /* Used to hold a copy of the compound literal in a template. */
3955 10088375 : tree orig_cl = NULL_TREE;
3956 :
3957 10088375 : if (processing_template_decl)
3958 : {
3959 5278034 : const bool dependent_p
3960 5278034 : = (instantiation_dependent_expression_p (compound_literal)
3961 5278034 : || dependent_type_p (type));
3962 1744684 : if (dependent_p)
3963 : /* We're about to return, no need to copy. */
3964 : orig_cl = compound_literal;
3965 : else
3966 : /* We're going to need a copy. */
3967 1744684 : orig_cl = unshare_constructor (compound_literal);
3968 5278034 : TREE_TYPE (orig_cl) = type;
3969 : /* Mark the expression as a compound literal. */
3970 5278034 : TREE_HAS_CONSTRUCTOR (orig_cl) = 1;
3971 : /* And as instantiation-dependent. */
3972 5278034 : CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p;
3973 5278034 : if (fcl_context == fcl_c99)
3974 130 : CONSTRUCTOR_C99_COMPOUND_LITERAL (orig_cl) = 1;
3975 : /* If the compound literal is dependent, we're done for now. */
3976 5278034 : if (dependent_p)
3977 : return orig_cl;
3978 : /* Otherwise, do go on to e.g. check narrowing. */
3979 : }
3980 :
3981 6555025 : type = complete_type (type);
3982 :
3983 6555025 : if (TYPE_NON_AGGREGATE_CLASS (type))
3984 : {
3985 : /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST
3986 : everywhere that deals with function arguments would be a pain, so
3987 : just wrap it in a TREE_LIST. The parser set a flag so we know
3988 : that it came from T{} rather than T({}). */
3989 1088564 : CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
3990 1088564 : compound_literal = build_tree_list (NULL_TREE, compound_literal);
3991 1088564 : return build_functional_cast (input_location, type,
3992 1088564 : compound_literal, complain);
3993 : }
3994 :
3995 5466461 : if (TREE_CODE (type) == ARRAY_TYPE
3996 5466461 : && check_array_initializer (NULL_TREE, type, compound_literal))
3997 9 : return error_mark_node;
3998 5466452 : compound_literal = reshape_init (type, compound_literal, complain);
3999 5466452 : if (SCALAR_TYPE_P (type)
4000 756340 : && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
4001 218660 : && !check_narrowing (type, compound_literal, complain))
4002 131 : return error_mark_node;
4003 5466321 : if (TREE_CODE (type) == ARRAY_TYPE
4004 5466321 : && TYPE_DOMAIN (type) == NULL_TREE)
4005 : {
4006 1253 : cp_complete_array_type_or_error (&type, compound_literal,
4007 : false, complain);
4008 1253 : if (type == error_mark_node)
4009 : return error_mark_node;
4010 : }
4011 5466318 : if (abstract_virtuals_error (ACU_UNKNOWN, type, complain))
4012 7 : return error_mark_node;
4013 5466311 : compound_literal = digest_init_flags (type, compound_literal,
4014 : LOOKUP_NORMAL | LOOKUP_NO_NARROWING,
4015 : complain);
4016 5466311 : if (compound_literal == error_mark_node)
4017 : return error_mark_node;
4018 :
4019 : /* If we're in a template, return the original compound literal. */
4020 5465647 : if (orig_cl)
4021 : return orig_cl;
4022 :
4023 3809837 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
4024 : {
4025 3110424 : TREE_HAS_CONSTRUCTOR (compound_literal) = true;
4026 3110424 : if (fcl_context == fcl_c99)
4027 37961 : CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1;
4028 : }
4029 :
4030 : /* Put static/constant array temporaries in static variables. */
4031 : /* FIXME all C99 compound literals should be variables rather than C++
4032 : temporaries, unless they are used as an aggregate initializer. */
4033 5021330 : if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
4034 2607159 : && fcl_context == fcl_c99
4035 83 : && TREE_CODE (type) == ARRAY_TYPE
4036 31 : && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
4037 3809868 : && initializer_constant_valid_p (compound_literal, type))
4038 : {
4039 31 : tree decl = create_temporary_var (type);
4040 31 : DECL_CONTEXT (decl) = NULL_TREE;
4041 31 : DECL_INITIAL (decl) = compound_literal;
4042 31 : TREE_STATIC (decl) = 1;
4043 31 : if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
4044 : {
4045 : /* 5.19 says that a constant expression can include an
4046 : lvalue-rvalue conversion applied to "a glvalue of literal type
4047 : that refers to a non-volatile temporary object initialized
4048 : with a constant expression". Rather than try to communicate
4049 : that this VAR_DECL is a temporary, just mark it constexpr. */
4050 24 : DECL_DECLARED_CONSTEXPR_P (decl) = true;
4051 24 : DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
4052 24 : TREE_CONSTANT (decl) = true;
4053 : }
4054 31 : cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
4055 31 : decl = pushdecl_top_level (decl);
4056 31 : DECL_NAME (decl) = make_anon_name ();
4057 31 : SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
4058 : /* Make sure the destructor is callable. */
4059 31 : tree clean = cxx_maybe_build_cleanup (decl, complain);
4060 31 : if (clean == error_mark_node)
4061 : return error_mark_node;
4062 31 : return decl;
4063 : }
4064 :
4065 : /* Represent other compound literals with TARGET_EXPR so we produce
4066 : a prvalue, and can elide copies. */
4067 3809806 : if (!VECTOR_TYPE_P (type)
4068 3769239 : && (TREE_CODE (compound_literal) == CONSTRUCTOR
4069 699407 : || TREE_CODE (compound_literal) == VEC_INIT_EXPR))
4070 : {
4071 : /* The CONSTRUCTOR is now an initializer, not a compound literal. */
4072 3069832 : if (TREE_CODE (compound_literal) == CONSTRUCTOR)
4073 3069832 : TREE_HAS_CONSTRUCTOR (compound_literal) = false;
4074 3069832 : compound_literal = get_target_expr (compound_literal, complain);
4075 : }
4076 : else
4077 : /* For e.g. int{42} just make sure it's a prvalue. */
4078 739974 : compound_literal = rvalue (compound_literal);
4079 :
4080 : return compound_literal;
4081 : }
4082 :
4083 : /* Return the declaration for the function-name variable indicated by
4084 : ID. */
4085 :
4086 : tree
4087 306079 : finish_fname (tree id)
4088 : {
4089 306079 : tree decl = fname_decl (input_location, C_RID_CODE (id), id);
4090 : /* [expr.prim.lambda.closure]/16 "Unless the compound-statement is that
4091 : of a consteval-block-declaration, a variable __func__ is implicitly
4092 : defined...". We could be in a consteval block in a function, though,
4093 : and then we shouldn't warn. */
4094 306079 : if (current_function_decl
4095 306079 : && !current_nonlambda_function (/*only_skip_consteval_block_p=*/true))
4096 8 : pedwarn (input_location, 0, "%qD is not defined outside of function scope",
4097 : decl);
4098 306079 : if (processing_template_decl && current_function_decl
4099 227357 : && decl != error_mark_node)
4100 227357 : decl = DECL_NAME (decl);
4101 306079 : return decl;
4102 : }
4103 :
4104 : /* Finish a translation unit. */
4105 :
4106 : void
4107 99885 : finish_translation_unit (void)
4108 : {
4109 : /* In case there were missing closebraces,
4110 : get us back to the global binding level. */
4111 99885 : pop_everything ();
4112 199770 : while (current_namespace != global_namespace)
4113 0 : pop_namespace ();
4114 :
4115 : /* Do file scope __FUNCTION__ et al. */
4116 99885 : finish_fname_decls ();
4117 :
4118 99885 : if (vec_safe_length (scope_chain->omp_declare_target_attribute))
4119 : {
4120 12 : cp_omp_declare_target_attr
4121 12 : a = scope_chain->omp_declare_target_attribute->pop ();
4122 12 : if (!errorcount)
4123 9 : error ("%qs without corresponding %qs",
4124 : a.device_type >= 0 ? "#pragma omp begin declare target"
4125 : : "#pragma omp declare target",
4126 : "#pragma omp end declare target");
4127 24 : vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0);
4128 : }
4129 99885 : if (vec_safe_length (scope_chain->omp_declare_variant_attribute))
4130 : {
4131 0 : if (!errorcount)
4132 0 : error ("%<omp begin declare variant%> without corresponding "
4133 : "%<omp end declare variant%>");
4134 0 : vec_safe_truncate (scope_chain->omp_declare_variant_attribute, 0);
4135 : }
4136 99885 : if (vec_safe_length (scope_chain->omp_begin_assumes))
4137 : {
4138 3 : if (!errorcount)
4139 3 : error ("%qs without corresponding %qs",
4140 : "#pragma omp begin assumes", "#pragma omp end assumes");
4141 3 : vec_safe_truncate (scope_chain->omp_begin_assumes, 0);
4142 : }
4143 99885 : }
4144 :
4145 : /* Finish a template type parameter, specified as AGGR IDENTIFIER.
4146 : Returns the parameter. */
4147 :
4148 : tree
4149 166070756 : finish_template_type_parm (tree aggr, tree identifier)
4150 : {
4151 166070756 : if (aggr != class_type_node)
4152 : {
4153 0 : permerror (input_location, "template type parameters must use the keyword %<class%> or %<typename%>");
4154 0 : aggr = class_type_node;
4155 : }
4156 :
4157 166070756 : return build_tree_list (aggr, identifier);
4158 : }
4159 :
4160 : /* Finish a template template parameter, specified as AGGR IDENTIFIER.
4161 : Returns the parameter. */
4162 :
4163 : tree
4164 421974 : finish_template_template_parm (tree aggr, tree identifier)
4165 : {
4166 421974 : tree decl = build_decl (input_location,
4167 : TYPE_DECL, identifier, NULL_TREE);
4168 :
4169 421974 : tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
4170 421974 : DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
4171 421974 : DECL_TEMPLATE_RESULT (tmpl) = decl;
4172 421974 : DECL_ARTIFICIAL (decl) = 1;
4173 :
4174 : /* Associate the constraints with the underlying declaration,
4175 : not the template. */
4176 421974 : tree constr = current_template_constraints ();
4177 421974 : set_constraints (decl, constr);
4178 :
4179 421974 : end_template_decl ();
4180 :
4181 421974 : gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
4182 :
4183 421974 : check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl),
4184 : /*is_primary=*/true, /*is_partial=*/false,
4185 : /*is_friend=*/0);
4186 :
4187 421974 : return finish_template_type_parm (aggr, tmpl);
4188 : }
4189 :
4190 : /* ARGUMENT is the default-argument value for a template template
4191 : parameter. If ARGUMENT is invalid, issue error messages and return
4192 : the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */
4193 :
4194 : tree
4195 984 : check_template_template_default_arg (tree argument)
4196 : {
4197 984 : if (TREE_CODE (argument) != TEMPLATE_DECL
4198 : && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
4199 : && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
4200 : {
4201 : if (TREE_CODE (argument) == TYPE_DECL)
4202 : {
4203 18 : if (tree t = maybe_get_template_decl_from_type_decl (argument))
4204 18 : if (TREE_CODE (t) == TEMPLATE_DECL)
4205 : return t;
4206 15 : error ("invalid use of type %qT as a default value for a template "
4207 15 : "template-parameter", TREE_TYPE (argument));
4208 : }
4209 : else
4210 0 : error ("invalid default argument for a template template parameter");
4211 15 : return error_mark_node;
4212 : }
4213 :
4214 : return argument;
4215 : }
4216 :
4217 : /* Begin a class definition, as indicated by T. */
4218 :
4219 : tree
4220 31937878 : begin_class_definition (tree t)
4221 : {
4222 31937878 : if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t)))
4223 33 : return error_mark_node;
4224 :
4225 31937995 : if (processing_template_parmlist && !LAMBDA_TYPE_P (t))
4226 : {
4227 24 : error ("definition of %q#T inside template parameter list", t);
4228 24 : return error_mark_node;
4229 : }
4230 :
4231 : /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
4232 : are passed the same as decimal scalar types. */
4233 31937821 : if (TREE_CODE (t) == RECORD_TYPE
4234 31405120 : && !processing_template_decl)
4235 : {
4236 11263820 : tree ns = TYPE_CONTEXT (t);
4237 11263817 : if (ns && TREE_CODE (ns) == NAMESPACE_DECL
4238 9250228 : && DECL_CONTEXT (ns) == std_node
4239 2241065 : && DECL_NAME (ns)
4240 13504865 : && id_equal (DECL_NAME (ns), "decimal"))
4241 : {
4242 150 : const char *n = TYPE_NAME_STRING (t);
4243 150 : if ((strcmp (n, "decimal32") == 0)
4244 101 : || (strcmp (n, "decimal64") == 0)
4245 46 : || (strcmp (n, "decimal128") == 0))
4246 147 : TYPE_TRANSPARENT_AGGR (t) = 1;
4247 : }
4248 : }
4249 :
4250 : /* A non-implicit typename comes from code like:
4251 :
4252 : template <typename T> struct A {
4253 : template <typename U> struct A<T>::B ...
4254 :
4255 : This is erroneous. */
4256 20674001 : else if (TREE_CODE (t) == TYPENAME_TYPE)
4257 : {
4258 0 : error ("invalid definition of qualified type %qT", t);
4259 0 : t = error_mark_node;
4260 : }
4261 :
4262 31937821 : if (t == error_mark_node || ! MAYBE_CLASS_TYPE_P (t))
4263 : {
4264 0 : t = make_class_type (RECORD_TYPE);
4265 0 : pushtag (make_anon_name (), t);
4266 : }
4267 :
4268 31937821 : if (TYPE_BEING_DEFINED (t))
4269 : {
4270 0 : t = make_class_type (TREE_CODE (t));
4271 0 : pushtag (TYPE_IDENTIFIER (t), t);
4272 : }
4273 :
4274 31937821 : maybe_process_partial_specialization (t);
4275 31937821 : pushclass (t);
4276 31937821 : TYPE_BEING_DEFINED (t) = 1;
4277 31937821 : class_binding_level->defining_class_p = 1;
4278 :
4279 31937821 : if (flag_pack_struct)
4280 : {
4281 99 : tree v;
4282 99 : TYPE_PACKED (t) = 1;
4283 : /* Even though the type is being defined for the first time
4284 : here, there might have been a forward declaration, so there
4285 : might be cv-qualified variants of T. */
4286 99 : for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
4287 0 : TYPE_PACKED (v) = 1;
4288 : }
4289 : /* Reset the interface data, at the earliest possible
4290 : moment, as it might have been set via a class foo;
4291 : before. */
4292 66321723 : if (! TYPE_UNNAMED_P (t))
4293 : {
4294 31172154 : struct c_fileinfo *finfo = \
4295 31172154 : get_fileinfo (LOCATION_FILE (input_location));
4296 31172154 : CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
4297 31172154 : SET_CLASSTYPE_INTERFACE_UNKNOWN_X
4298 : (t, finfo->interface_unknown);
4299 : }
4300 31937821 : reset_specialization ();
4301 :
4302 : /* Make a declaration for this class in its own scope. */
4303 31937821 : build_self_reference ();
4304 :
4305 31937821 : return t;
4306 : }
4307 :
4308 : /* Finish the member declaration given by DECL. */
4309 :
4310 : void
4311 431159834 : finish_member_declaration (tree decl)
4312 : {
4313 431159834 : if (decl == error_mark_node || decl == NULL_TREE)
4314 : return;
4315 :
4316 431158785 : if (decl == void_type_node)
4317 : /* The COMPONENT was a friend, not a member, and so there's
4318 : nothing for us to do. */
4319 : return;
4320 :
4321 : /* We should see only one DECL at a time. */
4322 431158785 : gcc_assert (DECL_CHAIN (decl) == NULL_TREE);
4323 :
4324 : /* Don't add decls after definition. */
4325 431158806 : gcc_assert (TYPE_BEING_DEFINED (current_class_type)
4326 : /* We can add lambda types when late parsing default
4327 : arguments. */
4328 : || LAMBDA_TYPE_P (TREE_TYPE (decl)));
4329 :
4330 : /* Set up access control for DECL. */
4331 431158785 : TREE_PRIVATE (decl)
4332 431158785 : = (current_access_specifier == access_private_node);
4333 431158785 : TREE_PROTECTED (decl)
4334 431158785 : = (current_access_specifier == access_protected_node);
4335 431158785 : if (TREE_CODE (decl) == TEMPLATE_DECL)
4336 : {
4337 49321439 : TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
4338 49321439 : TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
4339 : }
4340 :
4341 : /* Mark the DECL as a member of the current class, unless it's
4342 : a member of an enumeration. */
4343 431158785 : if (TREE_CODE (decl) != CONST_DECL)
4344 428730423 : DECL_CONTEXT (decl) = current_class_type;
4345 :
4346 431158785 : if (TREE_TYPE (decl)
4347 427555204 : && ANON_AGGR_TYPE_P (TREE_TYPE (decl))
4348 431555727 : && TREE_CODE (decl) != TYPE_DECL)
4349 : {
4350 : /* Remember the single FIELD_DECL an anonymous aggregate type is used
4351 : for. */
4352 289063 : if (TREE_CODE (decl) == FIELD_DECL && DECL_NAME (decl) == NULL_TREE)
4353 : {
4354 289047 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
4355 289047 : gcc_assert (!ANON_AGGR_TYPE_FIELD (type));
4356 289047 : SET_ANON_AGGR_TYPE_FIELD (type, decl);
4357 : }
4358 : /* [class.union.anon]/1: Each object of such an unnamed type shall
4359 : be such an unnamed object. */
4360 16 : else if (ANON_UNION_TYPE_P (TREE_TYPE (decl)))
4361 : {
4362 10 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
4363 10 : auto_diagnostic_group d;
4364 10 : error_at (location_of (decl),
4365 : "declaration of member %qD with anonymous union type %qT",
4366 10 : decl, TREE_TYPE (decl));
4367 10 : inform (DECL_SOURCE_LOCATION (adecl),
4368 : "anonymous union declared here");
4369 10 : }
4370 : else
4371 : {
4372 6 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (TREE_TYPE (decl)));
4373 6 : auto_diagnostic_group d;
4374 6 : error_at (location_of (decl),
4375 : "declaration of member %qD with anonymous struct type %qT",
4376 6 : decl, TREE_TYPE (decl));
4377 6 : inform (DECL_SOURCE_LOCATION (adecl),
4378 : "anonymous struct declared here");
4379 6 : }
4380 : }
4381 430869722 : else if (TREE_TYPE (decl)
4382 427266141 : && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
4383 432477958 : && TREE_CODE (decl) != TYPE_DECL)
4384 : {
4385 1543179 : tree type = strip_array_types (TREE_TYPE (decl));
4386 1543179 : if (ANON_AGGR_TYPE_P (type))
4387 : {
4388 : /* [class.union.anon]/1: Each object of such an unnamed type shall
4389 : be such an unnamed object. */
4390 12 : tree adecl = TYPE_MAIN_DECL (TYPE_MAIN_VARIANT (type));
4391 12 : auto_diagnostic_group d;
4392 12 : if (ANON_UNION_TYPE_P (type))
4393 : {
4394 8 : error_at (location_of (decl),
4395 : "declaration of member %qD with array of anonymous "
4396 8 : "union type %qT", decl, TREE_TYPE (decl));
4397 8 : inform (DECL_SOURCE_LOCATION (adecl),
4398 : "anonymous union declared here");
4399 : }
4400 : else
4401 : {
4402 4 : error_at (location_of (decl),
4403 : "declaration of member %qD with array of anonymous "
4404 4 : "struct type %qT", decl, TREE_TYPE (decl));
4405 4 : inform (DECL_SOURCE_LOCATION (adecl),
4406 : "anonymous struct declared here");
4407 : }
4408 12 : }
4409 : }
4410 :
4411 431158785 : if (TREE_CODE (decl) == USING_DECL)
4412 : /* Avoid debug info for class-scope USING_DECLS for now, we'll
4413 : call cp_emit_debug_info_for_using later. */
4414 3510486 : DECL_IGNORED_P (decl) = 1;
4415 :
4416 : /* Check for bare parameter packs in the non-static data member
4417 : declaration. */
4418 431158785 : if (TREE_CODE (decl) == FIELD_DECL)
4419 : {
4420 31634078 : if (check_for_bare_parameter_packs (TREE_TYPE (decl)))
4421 9 : TREE_TYPE (decl) = error_mark_node;
4422 31634078 : if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl)))
4423 0 : DECL_ATTRIBUTES (decl) = NULL_TREE;
4424 : }
4425 :
4426 : /* [dcl.link]
4427 :
4428 : A C language linkage is ignored for the names of class members
4429 : and the member function type of class member functions. */
4430 431158785 : if (DECL_LANG_SPECIFIC (decl))
4431 393507550 : SET_DECL_LANGUAGE (decl, lang_cplusplus);
4432 :
4433 431158785 : bool add = false;
4434 :
4435 : /* Functions and non-functions are added differently. */
4436 431158785 : if (DECL_DECLARES_FUNCTION_P (decl))
4437 222653312 : add = add_method (current_class_type, decl, false);
4438 : /* Enter the DECL into the scope of the class, if the class
4439 : isn't a closure (whose fields are supposed to be unnamed). */
4440 208505473 : else if (CLASSTYPE_LAMBDA_EXPR (current_class_type)
4441 204571361 : || maybe_push_used_methods (decl)
4442 411140886 : || pushdecl_class_level (decl))
4443 : add = true;
4444 :
4445 222653312 : if (add)
4446 : {
4447 : /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
4448 : go at the beginning. The reason is that
4449 : legacy_nonfn_member_lookup searches the list in order, and we
4450 : want a field name to override a type name so that the "struct
4451 : stat hack" will work. In particular:
4452 :
4453 : struct S { enum E { }; static const int E = 5; int ary[S::E]; } s;
4454 :
4455 : is valid. */
4456 :
4457 431145395 : if (TREE_CODE (decl) == TYPE_DECL)
4458 147906943 : TYPE_FIELDS (current_class_type)
4459 295813886 : = chainon (TYPE_FIELDS (current_class_type), decl);
4460 : else
4461 : {
4462 283238452 : DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type);
4463 283238452 : TYPE_FIELDS (current_class_type) = decl;
4464 : }
4465 :
4466 431145395 : maybe_add_class_template_decl_list (current_class_type, decl,
4467 : /*friend_p=*/0);
4468 : }
4469 : }
4470 :
4471 : /* Finish processing a complete template declaration. The PARMS are
4472 : the template parameters. */
4473 :
4474 : void
4475 95257358 : finish_template_decl (tree parms)
4476 : {
4477 95257358 : if (parms)
4478 95257349 : end_template_decl ();
4479 : else
4480 9 : end_specialization ();
4481 95257358 : }
4482 :
4483 : // Returns the template type of the class scope being entered. If we're
4484 : // entering a constrained class scope. TYPE is the class template
4485 : // scope being entered and we may need to match the intended type with
4486 : // a constrained specialization. For example:
4487 : //
4488 : // template<Object T>
4489 : // struct S { void f(); }; #1
4490 : //
4491 : // template<Object T>
4492 : // void S<T>::f() { } #2
4493 : //
4494 : // We check, in #2, that S<T> refers precisely to the type declared by
4495 : // #1 (i.e., that the constraints match). Note that the following should
4496 : // be an error since there is no specialization of S<T> that is
4497 : // unconstrained, but this is not diagnosed here.
4498 : //
4499 : // template<typename T>
4500 : // void S<T>::f() { }
4501 : //
4502 : // We cannot diagnose this problem here since this function also matches
4503 : // qualified template names that are not part of a definition. For example:
4504 : //
4505 : // template<Integral T, Floating_point U>
4506 : // typename pair<T, U>::first_type void f(T, U);
4507 : //
4508 : // Here, it is unlikely that there is a partial specialization of
4509 : // pair constrained for Integral and Floating_point arguments.
4510 : //
4511 : // The general rule is: if a constrained specialization with matching
4512 : // constraints is found return that type. Also note that if TYPE is not a
4513 : // class-type (e.g. a typename type), then no fixup is needed.
4514 :
4515 : static tree
4516 18711225 : fixup_template_type (tree type)
4517 : {
4518 : // Find the template parameter list at the a depth appropriate to
4519 : // the scope we're trying to enter.
4520 18711225 : tree parms = current_template_parms;
4521 18711225 : int depth = template_class_depth (type);
4522 23066135 : for (int n = current_template_depth; n > depth && parms; --n)
4523 4354910 : parms = TREE_CHAIN (parms);
4524 18711225 : if (!parms)
4525 : return type;
4526 18711215 : tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms);
4527 18711215 : tree cur_constr = build_constraints (cur_reqs, NULL_TREE);
4528 :
4529 : // Search for a specialization whose type and constraints match.
4530 18711215 : tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
4531 18711215 : tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
4532 36180176 : while (specs)
4533 : {
4534 17917009 : tree spec_constr = get_constraints (TREE_VALUE (specs));
4535 :
4536 : // If the type and constraints match a specialization, then we
4537 : // are entering that type.
4538 17917009 : if (same_type_p (type, TREE_TYPE (specs))
4539 17917009 : && equivalent_constraints (cur_constr, spec_constr))
4540 448048 : return TREE_TYPE (specs);
4541 17468961 : specs = TREE_CHAIN (specs);
4542 : }
4543 :
4544 : // If no specialization matches, then must return the type
4545 : // previously found.
4546 : return type;
4547 : }
4548 :
4549 : /* Finish processing a template-id (which names a type) of the form
4550 : NAME < ARGS >. Return the TYPE_DECL for the type named by the
4551 : template-id. If ENTERING_SCOPE is nonzero we are about to enter
4552 : the scope of template-id indicated. */
4553 :
4554 : tree
4555 193039342 : finish_template_type (tree name, tree args, int entering_scope)
4556 : {
4557 193039342 : tree type;
4558 :
4559 193039342 : type = lookup_template_class (name, args,
4560 : NULL_TREE, NULL_TREE,
4561 : tf_warning_or_error | tf_user);
4562 193039339 : if (entering_scope)
4563 19769715 : type = adjust_type_for_entering_scope (type);
4564 :
4565 : /* If we might be entering the scope of a partial specialization,
4566 : find the one with the right constraints. */
4567 193039339 : if (flag_concepts
4568 190274912 : && entering_scope
4569 19395796 : && CLASS_TYPE_P (type)
4570 19223170 : && CLASSTYPE_TEMPLATE_INFO (type)
4571 19223161 : && dependent_type_p (type)
4572 211750564 : && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
4573 18711225 : type = fixup_template_type (type);
4574 :
4575 193039339 : if (type == error_mark_node)
4576 : return type;
4577 193037049 : else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
4578 151544282 : return TYPE_STUB_DECL (type);
4579 : else
4580 41492767 : return TYPE_NAME (type);
4581 : }
4582 :
4583 : /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER
4584 : and ANNOTATIONS.
4585 : Return a TREE_LIST containing the ACCESS_SPECIFIER (or if there are
4586 : ANNOTATIONS, TREE_LIST containing the ACCESS_SPECIFIER and ANNOTATIONS)
4587 : and the BASE_CLASS, or NULL_TREE if an error occurred. The
4588 : ACCESS_SPECIFIER is one of
4589 : access_{default,public,protected,private}_node. For a virtual base
4590 : we set TREE_TYPE. */
4591 :
4592 : tree
4593 11759348 : finish_base_specifier (tree base, tree access, bool virtual_p,
4594 : tree annotations)
4595 : {
4596 11759348 : tree result;
4597 :
4598 11759348 : if (base == error_mark_node)
4599 : {
4600 0 : error ("invalid base-class specification");
4601 0 : result = NULL_TREE;
4602 : }
4603 11759348 : else if (! MAYBE_CLASS_TYPE_P (base))
4604 : {
4605 3 : error ("%qT is not a class type", base);
4606 3 : result = NULL_TREE;
4607 : }
4608 : else
4609 : {
4610 11759345 : if (cp_type_quals (base) != 0)
4611 : {
4612 : /* DR 484: Can a base-specifier name a cv-qualified
4613 : class type? */
4614 12 : base = TYPE_MAIN_VARIANT (base);
4615 : }
4616 11759345 : if (annotations)
4617 18 : access = build_tree_list (access, nreverse (annotations));
4618 11759345 : result = build_tree_list (access, base);
4619 11759345 : if (virtual_p)
4620 26774 : TREE_TYPE (result) = integer_type_node;
4621 : }
4622 :
4623 11759348 : return result;
4624 : }
4625 :
4626 : /* If FNS is a member function, a set of member functions, or a
4627 : template-id referring to one or more member functions, return a
4628 : BASELINK for FNS, incorporating the current access context.
4629 : Otherwise, return FNS unchanged. If IGNORE_CURRENT_CLASS_P is
4630 : true, we do not consider the currently open derived class. */
4631 :
4632 : tree
4633 188793367 : baselink_for_fns (tree fns, bool ignore_current_class_p/*=false*/)
4634 : {
4635 188793367 : if (BASELINK_P (fns) || error_operand_p (fns))
4636 : return fns;
4637 :
4638 174564008 : tree scope = ovl_scope (fns);
4639 174564008 : if (!CLASS_TYPE_P (scope))
4640 : return fns;
4641 :
4642 9143520 : tree cl = (ignore_current_class_p
4643 9143520 : ? NULL_TREE
4644 9141780 : : currently_open_derived_class (scope));
4645 9141780 : if (!cl)
4646 : cl = scope;
4647 9143520 : tree access_path = TYPE_BINFO (cl);
4648 9143520 : tree conv_path = (cl == scope ? access_path
4649 731278 : : lookup_base (cl, scope, ba_any, NULL, tf_none));
4650 9143520 : return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE);
4651 : }
4652 :
4653 : /* Returns true iff we are currently parsing a lambda-declarator. */
4654 :
4655 : bool
4656 2031776725 : parsing_lambda_declarator ()
4657 : {
4658 2031776725 : cp_binding_level *b = current_binding_level;
4659 2033853086 : while (b->kind == sk_template_parms || b->kind == sk_function_parms)
4660 2076361 : b = b->level_chain;
4661 2031776725 : return b->kind == sk_lambda;
4662 : }
4663 :
4664 : /* Returns true iff DECL is a variable from a function outside
4665 : the current one. */
4666 :
4667 : static bool
4668 2713684991 : outer_var_p (tree decl)
4669 : {
4670 : /* These should have been stripped or otherwise handled by the caller. */
4671 2713684991 : gcc_checking_assert (!REFERENCE_REF_P (decl));
4672 :
4673 1782798486 : return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL)
4674 2492206175 : && DECL_FUNCTION_SCOPE_P (decl)
4675 : /* Don't get confused by temporaries. */
4676 2064554290 : && DECL_NAME (decl)
4677 4753793039 : && (DECL_CONTEXT (decl) != current_function_decl
4678 2029554064 : || parsing_nsdmi ()
4679 : /* Also consider captures as outer vars if we are in
4680 : decltype in a lambda declarator as in:
4681 : auto l = [j=0]() -> decltype((j)) { ... }
4682 : for the sake of finish_decltype_type.
4683 :
4684 : (Similar issue also affects non-lambdas, but vexing parse
4685 : makes it more difficult to handle than lambdas.) */
4686 2029552687 : || parsing_lambda_declarator ()));
4687 : }
4688 :
4689 : /* As above, but also checks that DECL is automatic. */
4690 :
4691 : bool
4692 2713684991 : outer_automatic_var_p (tree decl)
4693 : {
4694 2713684991 : return (outer_var_p (decl)
4695 2713684991 : && !TREE_STATIC (decl));
4696 : }
4697 :
4698 : /* Note whether capture proxy D is only used in a contract condition. */
4699 :
4700 : static void
4701 179642 : set_contract_capture_flag (tree d, bool val)
4702 : {
4703 179642 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (d));
4704 179642 : tree proxy = DECL_VALUE_EXPR (d);
4705 179642 : gcc_checking_assert (TREE_CODE (proxy) == COMPONENT_REF
4706 : && TREE_CODE (TREE_OPERAND (proxy, 1)) == FIELD_DECL);
4707 179642 : DECL_CONTRACT_CAPTURE_P (TREE_OPERAND (proxy, 1)) = val;
4708 179642 : }
4709 :
4710 : /* DECL satisfies outer_automatic_var_p. Possibly complain about it or
4711 : rewrite it for lambda capture.
4712 :
4713 : If ODR_USE is true, we're being called from mark_use, and we complain about
4714 : use of constant variables. If ODR_USE is false, we're being called for the
4715 : id-expression, and we do lambda capture. */
4716 :
4717 : tree
4718 5435871 : process_outer_var_ref (tree decl, tsubst_flags_t complain,
4719 : bool odr_use/*=false*/)
4720 : {
4721 5442324 : bool in_typeid_probe = false;
4722 5442324 : if (cp_unevaluated_operand)
4723 : {
4724 3218102 : tree type = TREE_TYPE (decl);
4725 3218102 : if (!dependent_type_p (type)
4726 3218102 : && variably_modified_type_p (type, NULL_TREE))
4727 : /* VLAs are used even in unevaluated context. */;
4728 3218096 : else if (cp_unevaluated_operand > cp_unevaluated_typeid_cutoff)
4729 : /* It's not a use (3.2) if we're in an unevaluated context. */
4730 : return decl;
4731 : else
4732 : /* Inside a typeid operand's own probe: capture is still
4733 : attempted below ([expr.prim.lambda.capture]/7), but a missing
4734 : capture-default must not be diagnosed yet - see below. */
4735 : in_typeid_probe = true;
4736 : }
4737 2224291 : if (decl == error_mark_node)
4738 : return decl;
4739 :
4740 2224285 : tree context = DECL_CONTEXT (decl);
4741 2224285 : tree containing_function = current_function_decl;
4742 2224285 : tree lambda_stack = NULL_TREE;
4743 2224285 : tree lambda_expr = NULL_TREE;
4744 2224285 : tree initializer = convert_from_reference (decl);
4745 2224285 : tree var = strip_normal_capture_proxy (decl);
4746 :
4747 : /* Mark it as used now even if the use is ill-formed. */
4748 2224285 : if (!mark_used (decl, complain))
4749 3 : return error_mark_node;
4750 :
4751 2224282 : if (parsing_nsdmi () || parsing_lambda_declarator ())
4752 : containing_function = NULL_TREE;
4753 :
4754 4447657 : if (containing_function && LAMBDA_FUNCTION_P (containing_function))
4755 : {
4756 : /* Check whether we've already built a proxy. */
4757 2223724 : tree d = retrieve_local_specialization (var);
4758 :
4759 2223724 : if (d && d != decl && is_capture_proxy (d))
4760 : {
4761 1141053 : if (flag_contracts && !processing_contract_condition)
4762 : /* We might have created a capture for a contract_assert ref. to
4763 : some var, if that is now captured 'normally' then this is OK.
4764 : Otherwise we leave the capture marked as incorrect. */
4765 179636 : set_contract_capture_flag (d, false);
4766 1141053 : if (DECL_CONTEXT (d) == containing_function)
4767 : /* We already have an inner proxy. */
4768 : return d;
4769 : else
4770 : /* We need to capture an outer proxy. */
4771 : return process_outer_var_ref (d, complain, odr_use);
4772 : }
4773 : }
4774 :
4775 : /* If we are in a lambda function, we can move out until we hit
4776 : 1. the context,
4777 : 2. a non-lambda function, or
4778 : 3. a non-default capturing lambda function. */
4779 2172678 : while (context != containing_function
4780 : /* containing_function can be null with invalid generic lambdas. */
4781 2172678 : && containing_function
4782 3263545 : && LAMBDA_FUNCTION_P (containing_function))
4783 : {
4784 1090867 : tree closure = DECL_CONTEXT (containing_function);
4785 1090867 : lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure);
4786 :
4787 1090867 : if (TYPE_CLASS_SCOPE_P (closure))
4788 : /* A lambda in an NSDMI (c++/64496). */
4789 : break;
4790 :
4791 1090864 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4792 : break;
4793 :
4794 1089449 : lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack);
4795 :
4796 1089449 : containing_function = decl_function_context (containing_function);
4797 : }
4798 :
4799 : /* In a lambda within a template, wait until instantiation time to implicitly
4800 : capture a parameter pack. We want to wait because we don't know if we're
4801 : capturing the whole pack or a single element, and it's OK to wait because
4802 : find_parameter_packs_r walks into the lambda body. */
4803 1083229 : if (context == containing_function
4804 1083229 : && DECL_PACK_P (decl))
4805 : return decl;
4806 :
4807 1038658 : if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl))
4808 : {
4809 6 : if (complain & tf_error)
4810 6 : error ("cannot capture member %qD of anonymous union", decl);
4811 6 : return error_mark_node;
4812 : }
4813 : /* Do lambda capture when processing the id-expression, not when
4814 : odr-using a variable, but uses in a contract must not cause a capture. */
4815 1038652 : if (!odr_use && context == containing_function)
4816 : {
4817 1036676 : decl = add_default_capture (lambda_stack,
4818 1036676 : /*id=*/DECL_NAME (decl), initializer);
4819 1036676 : if (flag_contracts && processing_contract_condition)
4820 6 : set_contract_capture_flag (decl, true);
4821 : }
4822 : /* Capture was attempted above; whether it's really needed depends on
4823 : an evaluated-ness we don't know yet. Defer instead of diagnosing:
4824 : a later, non-probe pass will complain if the operand turns out
4825 : evaluated, and there's nothing to complain about if it doesn't. */
4826 1976 : else if (in_typeid_probe)
4827 : return var;
4828 : /* Only an odr-use of an outer automatic variable causes an
4829 : error, and a constant variable can decay to a prvalue
4830 : constant without odr-use. So don't complain yet. */
4831 1967 : else if (!odr_use && decl_constant_var_p (var))
4832 : return var;
4833 : /* Don't complain when DECL is dependent, because it can turn out to
4834 : be constant (and therefore needing no capture) when instantiating. */
4835 438 : else if (VAR_P (var) && instantiation_dependent_expression_p (var))
4836 : return var;
4837 420 : else if (lambda_expr)
4838 : {
4839 60 : if (complain & tf_error)
4840 : {
4841 56 : auto_diagnostic_group d;
4842 56 : error ("%qD is not captured", decl);
4843 56 : tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr);
4844 56 : if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE)
4845 53 : inform (location_of (closure),
4846 : "the lambda has no capture-default");
4847 3 : else if (TYPE_CLASS_SCOPE_P (closure))
4848 3 : inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot "
4849 : "capture variables from the enclosing context",
4850 3 : TYPE_CONTEXT (closure));
4851 56 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4852 56 : }
4853 60 : return error_mark_node;
4854 : }
4855 360 : else if (processing_contract_condition && TREE_CODE (decl) == PARM_DECL)
4856 : /* Use of a parameter in a contract condition is fine. */
4857 : return decl;
4858 : else
4859 : {
4860 53 : if (complain & tf_error)
4861 : {
4862 39 : auto_diagnostic_group d;
4863 57 : error (VAR_P (decl)
4864 : ? G_("use of local variable with automatic storage from "
4865 : "containing function")
4866 : : G_("use of parameter from containing function"));
4867 39 : inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl);
4868 39 : }
4869 53 : return error_mark_node;
4870 : }
4871 : return decl;
4872 : }
4873 :
4874 : /* ID_EXPRESSION is a representation of parsed, but unprocessed,
4875 : id-expression. (See cp_parser_id_expression for details.) SCOPE,
4876 : if non-NULL, is the type or namespace used to explicitly qualify
4877 : ID_EXPRESSION. DECL is the entity to which that name has been
4878 : resolved.
4879 :
4880 : *CONSTANT_EXPRESSION_P is true if we are presently parsing a
4881 : constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
4882 : be set to true if this expression isn't permitted in a
4883 : constant-expression, but it is otherwise not set by this function.
4884 : *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
4885 : constant-expression, but a non-constant expression is also
4886 : permissible.
4887 :
4888 : DONE is true if this expression is a complete postfix-expression;
4889 : it is false if this expression is followed by '->', '[', '(', etc.
4890 : ADDRESS_P is true iff this expression is the operand of '&'.
4891 : TEMPLATE_P is true iff the qualified-id was of the form
4892 : "A::template B". TEMPLATE_ARG_P is true iff this qualified name
4893 : appears as a template argument.
4894 :
4895 : If an error occurs, and it is the kind of error that might cause
4896 : the parser to abort a tentative parse, *ERROR_MSG is filled in. It
4897 : is the caller's responsibility to issue the message. *ERROR_MSG
4898 : will be a string with static storage duration, so the caller need
4899 : not "free" it.
4900 :
4901 : Return an expression for the entity, after issuing appropriate
4902 : diagnostics. This function is also responsible for transforming a
4903 : reference to a non-static member into a COMPONENT_REF that makes
4904 : the use of "this" explicit.
4905 :
4906 : Upon return, *IDK will be filled in appropriately. */
4907 : static cp_expr
4908 806079961 : finish_id_expression_1 (tree id_expression,
4909 : tree decl,
4910 : tree scope,
4911 : cp_id_kind *idk,
4912 : bool integral_constant_expression_p,
4913 : bool allow_non_integral_constant_expression_p,
4914 : bool *non_integral_constant_expression_p,
4915 : bool template_p,
4916 : bool done,
4917 : bool address_p,
4918 : bool template_arg_p,
4919 : const char **error_msg,
4920 : location_t location)
4921 : {
4922 806079961 : decl = strip_using_decl (decl);
4923 :
4924 : /* Initialize the output parameters. */
4925 806079961 : *idk = CP_ID_KIND_NONE;
4926 806079961 : *error_msg = NULL;
4927 :
4928 806079961 : if (id_expression == error_mark_node)
4929 12 : return error_mark_node;
4930 : /* If we have a template-id, then no further lookup is
4931 : required. If the template-id was for a template-class, we
4932 : will sometimes have a TYPE_DECL at this point. */
4933 806079949 : else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
4934 749941503 : || TREE_CODE (decl) == TYPE_DECL)
4935 : ;
4936 : /* Look up the name. */
4937 : else
4938 : {
4939 749940580 : if (decl == error_mark_node)
4940 : {
4941 : /* Name lookup failed. */
4942 133224 : if (scope
4943 374 : && !dependent_namespace_p (scope)
4944 133598 : && (!TYPE_P (scope)
4945 119 : || (!dependentish_scope_p (scope)
4946 115 : && !(identifier_p (id_expression)
4947 100 : && IDENTIFIER_CONV_OP_P (id_expression)
4948 3 : && dependent_type_p (TREE_TYPE (id_expression))))))
4949 : {
4950 : /* If the qualifying type is non-dependent (and the name
4951 : does not name a conversion operator to a dependent
4952 : type), issue an error. */
4953 364 : qualified_name_lookup_error (scope, id_expression, decl, location);
4954 364 : return error_mark_node;
4955 : }
4956 132860 : else if (!scope)
4957 : {
4958 : /* It may be resolved via Koenig lookup. */
4959 132850 : *idk = CP_ID_KIND_UNQUALIFIED;
4960 132850 : return id_expression;
4961 : }
4962 : else
4963 : decl = id_expression;
4964 : }
4965 :
4966 : /* Remember that the name was used in the definition of
4967 : the current class so that we can check later to see if
4968 : the meaning would have been different after the class
4969 : was entirely defined. */
4970 749807356 : if (!scope && decl != error_mark_node && identifier_p (id_expression))
4971 670429048 : maybe_note_name_used_in_class (id_expression, decl);
4972 :
4973 : /* A use in unevaluated operand might not be instantiated appropriately
4974 : if tsubst_copy builds a dummy parm, or if we never instantiate a
4975 : generic lambda, so mark it now. */
4976 749807366 : if (processing_template_decl
4977 749807366 : && (cp_unevaluated_operand
4978 648825250 : || generic_lambda_fn_p (current_function_decl)))
4979 20961323 : mark_type_use (decl);
4980 :
4981 : /* Disallow uses of local variables from containing functions, except
4982 : within lambda-expressions. */
4983 749807366 : if (outer_automatic_var_p (decl))
4984 : {
4985 3880797 : decl = process_outer_var_ref (decl, tf_warning_or_error);
4986 3880797 : if (decl == error_mark_node)
4987 92 : return error_mark_node;
4988 : }
4989 :
4990 : /* Also disallow uses of function parameters outside the function
4991 : body, except inside an unevaluated context (i.e. decltype). */
4992 749807274 : if (TREE_CODE (decl) == PARM_DECL
4993 312552752 : && DECL_CONTEXT (decl) == NULL_TREE
4994 8468074 : && !CONSTRAINT_VAR_P (decl)
4995 4543289 : && !cp_unevaluated_operand
4996 595 : && !processing_contract_condition
4997 749807330 : && !processing_omp_trait_property_expr)
4998 : {
4999 38 : *error_msg = G_("use of parameter outside function body");
5000 38 : return error_mark_node;
5001 : }
5002 : }
5003 :
5004 : /* If we didn't find anything, or what we found was a type,
5005 : then this wasn't really an id-expression. */
5006 805946605 : if (TREE_CODE (decl) == TEMPLATE_DECL
5007 805946605 : && !DECL_FUNCTION_TEMPLATE_P (decl))
5008 : {
5009 51 : *error_msg = G_("missing template arguments");
5010 51 : return error_mark_node;
5011 : }
5012 805946554 : else if (TREE_CODE (decl) == TYPE_DECL
5013 805945631 : || TREE_CODE (decl) == NAMESPACE_DECL)
5014 : {
5015 938 : *error_msg = G_("expected primary-expression");
5016 938 : return error_mark_node;
5017 : }
5018 :
5019 : /* If the name resolved to a template parameter, there is no
5020 : need to look it up again later. */
5021 34450839 : if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
5022 820269484 : || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
5023 : {
5024 20126971 : tree r;
5025 :
5026 20126971 : *idk = CP_ID_KIND_NONE;
5027 20126971 : if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
5028 0 : decl = TEMPLATE_PARM_DECL (decl);
5029 20126971 : r = DECL_INITIAL (decl);
5030 20126971 : if (CLASS_TYPE_P (TREE_TYPE (r)) && !CP_TYPE_CONST_P (TREE_TYPE (r)))
5031 : {
5032 : /* If the entity is a template parameter object for a template
5033 : parameter of type T, the type of the expression is const T. */
5034 2969 : tree ctype = TREE_TYPE (r);
5035 2969 : ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype)
5036 : | TYPE_QUAL_CONST));
5037 2969 : r = build1 (VIEW_CONVERT_EXPR, ctype, r);
5038 : }
5039 20126971 : r = convert_from_reference (r);
5040 20126971 : if (integral_constant_expression_p
5041 3504926 : && !dependent_type_p (TREE_TYPE (decl))
5042 23125629 : && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r))))
5043 : {
5044 1023 : if (!allow_non_integral_constant_expression_p)
5045 6 : error ("template parameter %qD of type %qT is not allowed in "
5046 : "an integral constant expression because it is not of "
5047 6 : "integral or enumeration type", decl, TREE_TYPE (decl));
5048 1023 : *non_integral_constant_expression_p = true;
5049 : }
5050 :
5051 20126971 : if (flag_contracts && processing_contract_condition)
5052 27 : r = constify_contract_access (r);
5053 :
5054 20126971 : return r;
5055 : }
5056 785818645 : else if (TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE)
5057 : {
5058 9 : gcc_checking_assert (scope);
5059 9 : *idk = CP_ID_KIND_QUALIFIED;
5060 9 : cp_warn_deprecated_use_scopes (scope);
5061 9 : decl = finish_qualified_id_expr (scope, decl, done, address_p,
5062 : template_p, template_arg_p,
5063 : tf_warning_or_error);
5064 : }
5065 : else
5066 : {
5067 785818636 : if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
5068 56138446 : && variable_template_p (TREE_OPERAND (decl, 0))
5069 798527310 : && !concept_check_p (decl))
5070 : /* Try resolving this variable TEMPLATE_ID_EXPR (which is always
5071 : considered type-dependent) now, so that the dependence test that
5072 : follows gives us the right answer: if it represents a non-dependent
5073 : variable template-id then finish_template_variable will yield the
5074 : corresponding non-dependent VAR_DECL. */
5075 12708674 : decl = finish_template_variable (decl);
5076 :
5077 785818636 : bool dependent_p = type_dependent_expression_p (decl);
5078 :
5079 : /* If the declaration was explicitly qualified indicate
5080 : that. The semantics of `A::f(3)' are different than
5081 : `f(3)' if `f' is virtual. */
5082 1571637272 : *idk = (scope
5083 785818636 : ? CP_ID_KIND_QUALIFIED
5084 683559155 : : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
5085 683559155 : ? CP_ID_KIND_TEMPLATE_ID
5086 : : (dependent_p
5087 650596369 : ? CP_ID_KIND_UNQUALIFIED_DEPENDENT
5088 : : CP_ID_KIND_UNQUALIFIED)));
5089 :
5090 785818636 : if (dependent_p
5091 785818636 : && !scope
5092 450667693 : && DECL_P (decl)
5093 1204623861 : && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
5094 : /* Dependent type attributes on the decl mean that the TREE_TYPE is
5095 : wrong, so just return the identifier. */
5096 39 : return id_expression;
5097 :
5098 785818597 : if (DECL_CLASS_TEMPLATE_P (decl))
5099 : {
5100 0 : error ("use of class template %qT as expression", decl);
5101 0 : return error_mark_node;
5102 : }
5103 :
5104 785818597 : if (TREE_CODE (decl) == TREE_LIST)
5105 : {
5106 : /* Ambiguous reference to base members. */
5107 0 : auto_diagnostic_group d;
5108 0 : error ("request for member %qD is ambiguous in "
5109 : "multiple inheritance lattice", id_expression);
5110 0 : print_candidates (input_location, decl);
5111 0 : return error_mark_node;
5112 0 : }
5113 :
5114 : /* Mark variable-like entities as used. Functions are similarly
5115 : marked either below or after overload resolution. */
5116 785818597 : if ((VAR_P (decl)
5117 569658546 : || TREE_CODE (decl) == PARM_DECL
5118 257105838 : || TREE_CODE (decl) == CONST_DECL
5119 242781970 : || TREE_CODE (decl) == RESULT_DECL)
5120 1112695173 : && !mark_used (decl))
5121 12 : return error_mark_node;
5122 :
5123 : /* Only certain kinds of names are allowed in constant
5124 : expression. Template parameters have already
5125 : been handled above. */
5126 785818582 : if (! error_operand_p (decl)
5127 785818254 : && !dependent_p
5128 785818254 : && integral_constant_expression_p
5129 79195231 : && !decl_constant_var_p (decl)
5130 64410703 : && TREE_CODE (decl) != CONST_DECL
5131 55585324 : && !builtin_valid_in_constant_expr_p (decl)
5132 841353607 : && !concept_check_p (decl))
5133 : {
5134 54957273 : if (!allow_non_integral_constant_expression_p)
5135 : {
5136 30 : error ("%qD cannot appear in a constant-expression", decl);
5137 30 : return error_mark_node;
5138 : }
5139 54957243 : *non_integral_constant_expression_p = true;
5140 : }
5141 :
5142 785818552 : if (tree wrap = maybe_get_tls_wrapper_call (decl))
5143 : /* Replace an evaluated use of the thread_local variable with
5144 : a call to its wrapper. */
5145 : decl = wrap;
5146 785818040 : else if (concept_check_p (decl))
5147 : {
5148 : /* Nothing more to do. All of the analysis for concept checks
5149 : is done by build_conept_id, called from the parser. */
5150 : }
5151 768523195 : else if (scope)
5152 : {
5153 100270703 : if (TREE_CODE (decl) == SCOPE_REF)
5154 : {
5155 91442 : gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0)));
5156 91442 : decl = TREE_OPERAND (decl, 1);
5157 : }
5158 :
5159 100270703 : decl = (adjust_result_of_qualified_name_lookup
5160 100270703 : (decl, scope, current_nonlambda_class_type()));
5161 :
5162 100270703 : cp_warn_deprecated_use_scopes (scope);
5163 :
5164 100270703 : if (TYPE_P (scope))
5165 14338421 : decl = finish_qualified_id_expr (scope,
5166 : decl,
5167 : done,
5168 : address_p,
5169 : template_p,
5170 : template_arg_p,
5171 : tf_warning_or_error);
5172 : else
5173 85932282 : decl = convert_from_reference (decl);
5174 : }
5175 668252492 : else if (TREE_CODE (decl) == FIELD_DECL)
5176 : {
5177 69529301 : if (flag_contracts && processing_contract_condition
5178 37 : && contract_class_ptr == current_class_ptr)
5179 : {
5180 6 : error ("%qD 'this' required when accessing a member within a "
5181 : "constructor precondition or destructor postcondition "
5182 : "contract check", decl);
5183 6 : return error_mark_node;
5184 : }
5185 : /* Since SCOPE is NULL here, this is an unqualified name.
5186 : Access checking has been performed during name lookup
5187 : already. Turn off checking to avoid duplicate errors. */
5188 69529295 : push_deferring_access_checks (dk_no_check);
5189 69529295 : decl = finish_non_static_data_member (decl, NULL_TREE,
5190 : /*qualifying_scope=*/NULL_TREE);
5191 69529295 : pop_deferring_access_checks ();
5192 : }
5193 598723191 : else if (is_overloaded_fn (decl))
5194 : {
5195 : /* We only need to look at the first function,
5196 : because all the fns share the attribute we're
5197 : concerned with (all member fns or all non-members). */
5198 64266769 : tree first_fn = get_first_fn (decl);
5199 64266769 : first_fn = STRIP_TEMPLATE (first_fn);
5200 :
5201 64266769 : if (!template_arg_p
5202 64266769 : && (TREE_CODE (first_fn) == USING_DECL
5203 64264881 : || (TREE_CODE (first_fn) == FUNCTION_DECL
5204 64264881 : && DECL_FUNCTION_MEMBER_P (first_fn)
5205 39344022 : && !shared_member_p (decl))))
5206 : {
5207 : /* A set of member functions. */
5208 30325162 : if (flag_contracts && processing_contract_condition
5209 24 : && contract_class_ptr == current_class_ptr)
5210 : {
5211 3 : error ("%qD 'this' required when accessing a member within a "
5212 : "constructor precondition or destructor postcondition "
5213 : "contract check", decl);
5214 3 : return error_mark_node;
5215 : }
5216 30325159 : decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
5217 30325159 : return finish_class_member_access_expr (decl, id_expression,
5218 : /*template_p=*/false,
5219 30325159 : tf_warning_or_error);
5220 : }
5221 :
5222 33941607 : decl = baselink_for_fns (decl);
5223 : }
5224 : else
5225 : {
5226 522714069 : if (DECL_P (decl) && DECL_NONLOCAL (decl)
5227 535992145 : && DECL_CLASS_SCOPE_P (decl))
5228 : {
5229 1535723 : tree context = context_for_name_lookup (decl);
5230 1535723 : if (context != current_class_type)
5231 : {
5232 803337 : tree path = currently_open_derived_class (context);
5233 803337 : if (!path)
5234 : /* PATH can be null for using an enum of an unrelated
5235 : class; we checked its access in lookup_using_decl.
5236 :
5237 : ??? Should this case make a clone instead, like
5238 : handle_using_decl? */
5239 43 : gcc_assert (TREE_CODE (decl) == CONST_DECL
5240 : /* This is for:
5241 : constexpr auto r = ^^S::i;
5242 : auto a = [:r:]; */
5243 : || flag_reflection);
5244 : else
5245 803294 : perform_or_defer_access_check (TYPE_BINFO (path),
5246 : decl, decl,
5247 : tf_warning_or_error);
5248 : }
5249 : }
5250 :
5251 534456422 : decl = convert_from_reference (decl);
5252 : }
5253 : }
5254 :
5255 755493393 : check_param_in_postcondition (decl, location);
5256 755493393 : if (flag_contracts && processing_contract_condition)
5257 2184 : decl = constify_contract_access (decl);
5258 :
5259 755493393 : return cp_expr (decl, location);
5260 : }
5261 :
5262 : /* As per finish_id_expression_1, but adding a wrapper node
5263 : around the result if needed to express LOCATION. */
5264 :
5265 : cp_expr
5266 806079961 : finish_id_expression (tree id_expression,
5267 : tree decl,
5268 : tree scope,
5269 : cp_id_kind *idk,
5270 : bool integral_constant_expression_p,
5271 : bool allow_non_integral_constant_expression_p,
5272 : bool *non_integral_constant_expression_p,
5273 : bool template_p,
5274 : bool done,
5275 : bool address_p,
5276 : bool template_arg_p,
5277 : const char **error_msg,
5278 : location_t location)
5279 : {
5280 806079961 : cp_expr result
5281 806079961 : = finish_id_expression_1 (id_expression, decl, scope, idk,
5282 : integral_constant_expression_p,
5283 : allow_non_integral_constant_expression_p,
5284 : non_integral_constant_expression_p,
5285 : template_p, done, address_p, template_arg_p,
5286 : error_msg, location);
5287 806079958 : return result.maybe_add_location_wrapper ();
5288 : }
5289 :
5290 : /* Implement the __typeof keyword: Return the type of EXPR, suitable for
5291 : use as a type-specifier. */
5292 :
5293 : tree
5294 22396444 : finish_typeof (tree expr)
5295 : {
5296 22396444 : tree type;
5297 :
5298 22396444 : if (type_dependent_expression_p (expr))
5299 : {
5300 22303244 : type = cxx_make_type (TYPEOF_TYPE);
5301 22303244 : TYPEOF_TYPE_EXPR (type) = expr;
5302 22303244 : SET_TYPE_STRUCTURAL_EQUALITY (type);
5303 :
5304 22303244 : return type;
5305 : }
5306 :
5307 93200 : expr = mark_type_use (expr);
5308 :
5309 93200 : type = unlowered_expr_type (expr);
5310 :
5311 93200 : if (!type || type == unknown_type_node)
5312 : {
5313 3 : error ("type of %qE is unknown", expr);
5314 3 : return error_mark_node;
5315 : }
5316 :
5317 : return type;
5318 : }
5319 :
5320 : /* Implement the __underlying_type keyword: Return the underlying
5321 : type of TYPE, suitable for use as a type-specifier. */
5322 :
5323 : tree
5324 48989 : finish_underlying_type (tree type)
5325 : {
5326 48989 : if (!complete_type_or_else (type, NULL_TREE))
5327 3 : return error_mark_node;
5328 :
5329 48986 : if (TREE_CODE (type) != ENUMERAL_TYPE)
5330 : {
5331 24 : error ("%qT is not an enumeration type", type);
5332 24 : return error_mark_node;
5333 : }
5334 :
5335 48962 : tree underlying_type = ENUM_UNDERLYING_TYPE (type);
5336 :
5337 : /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
5338 : includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
5339 : See finish_enum_value_list for details. */
5340 48962 : if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
5341 56 : underlying_type
5342 56 : = c_common_type_for_mode (TYPE_MODE (underlying_type),
5343 56 : TYPE_UNSIGNED (underlying_type));
5344 :
5345 : return underlying_type;
5346 : }
5347 :
5348 : /* Implement the __type_pack_element keyword: Return the type
5349 : at index IDX within TYPES. */
5350 :
5351 : static tree
5352 135939 : finish_type_pack_element (tree idx, tree types, tsubst_flags_t complain)
5353 : {
5354 135939 : idx = maybe_constant_value (idx, NULL_TREE, mce_true);
5355 135939 : if (!INTEGRAL_TYPE_P (TREE_TYPE (idx)))
5356 : {
5357 6 : if (complain & tf_error)
5358 3 : error ("pack index has non-integral type %qT", TREE_TYPE (idx));
5359 6 : return error_mark_node;
5360 : }
5361 135933 : if (TREE_CODE (idx) != INTEGER_CST)
5362 : {
5363 2 : if (complain & tf_error)
5364 : {
5365 2 : error ("pack index is not an integral constant");
5366 2 : cxx_constant_value (idx);
5367 : }
5368 2 : return error_mark_node;
5369 : }
5370 135931 : if (tree_int_cst_sgn (idx) < 0)
5371 : {
5372 3 : if (complain & tf_error)
5373 3 : error ("pack index %qE is negative", idx);
5374 3 : return error_mark_node;
5375 : }
5376 135928 : if (wi::to_widest (idx) >= TREE_VEC_LENGTH (types))
5377 : {
5378 35 : if (complain & tf_error)
5379 29 : error ("pack index %qE is out of range for pack of length %qd",
5380 29 : idx, TREE_VEC_LENGTH (types));
5381 35 : return error_mark_node;
5382 : }
5383 135893 : return TREE_VEC_ELT (types, tree_to_shwi (idx));
5384 : }
5385 :
5386 : /* In a pack-index T...[N], return the element at index IDX within TYPES.
5387 : PARENTHESIZED_P is true iff the pack index was wrapped in (). */
5388 :
5389 : tree
5390 22552 : pack_index_element (tree idx, tree types, bool parenthesized_p,
5391 : tsubst_flags_t complain)
5392 : {
5393 22552 : tree r = finish_type_pack_element (idx, types, complain);
5394 22552 : if (parenthesized_p)
5395 : /* For the benefit of decltype(auto). */
5396 35 : r = force_paren_expr (r);
5397 22552 : return r;
5398 : }
5399 :
5400 : /* Implement the __direct_bases keyword: Return the direct base classes
5401 : of type. */
5402 :
5403 : tree
5404 15 : calculate_direct_bases (tree type, tsubst_flags_t complain)
5405 : {
5406 15 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5407 15 : || !NON_UNION_CLASS_TYPE_P (type))
5408 8 : return make_tree_vec (0);
5409 :
5410 7 : releasing_vec vector;
5411 7 : vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type));
5412 7 : tree binfo;
5413 7 : unsigned i;
5414 :
5415 : /* Virtual bases are initialized first */
5416 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5417 13 : if (BINFO_VIRTUAL_P (binfo))
5418 2 : vec_safe_push (vector, binfo);
5419 :
5420 : /* Now non-virtuals */
5421 20 : for (i = 0; base_binfos->iterate (i, &binfo); i++)
5422 13 : if (!BINFO_VIRTUAL_P (binfo))
5423 11 : vec_safe_push (vector, binfo);
5424 :
5425 7 : tree bases_vec = make_tree_vec (vector->length ());
5426 :
5427 27 : for (i = 0; i < vector->length (); ++i)
5428 13 : TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]);
5429 :
5430 7 : return bases_vec;
5431 7 : }
5432 :
5433 : /* Implement the __bases keyword: Return the base classes
5434 : of type */
5435 :
5436 : /* Find morally non-virtual base classes by walking binfo hierarchy */
5437 : /* Virtual base classes are handled separately in finish_bases */
5438 :
5439 : static tree
5440 73 : dfs_calculate_bases_pre (tree binfo, void * /*data_*/)
5441 : {
5442 : /* Don't walk bases of virtual bases */
5443 73 : return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE;
5444 : }
5445 :
5446 : static tree
5447 73 : dfs_calculate_bases_post (tree binfo, void *data_)
5448 : {
5449 73 : vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_);
5450 73 : if (!BINFO_VIRTUAL_P (binfo))
5451 48 : vec_safe_push (*data, BINFO_TYPE (binfo));
5452 73 : return NULL_TREE;
5453 : }
5454 :
5455 : /* Calculates the morally non-virtual base classes of a class */
5456 : static vec<tree, va_gc> *
5457 16 : calculate_bases_helper (tree type)
5458 : {
5459 16 : vec<tree, va_gc> *vector = make_tree_vector ();
5460 :
5461 : /* Now add non-virtual base classes in order of construction */
5462 16 : if (TYPE_BINFO (type))
5463 16 : dfs_walk_all (TYPE_BINFO (type),
5464 : dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector);
5465 16 : return vector;
5466 : }
5467 :
5468 : tree
5469 12 : calculate_bases (tree type, tsubst_flags_t complain)
5470 : {
5471 12 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)
5472 12 : || !NON_UNION_CLASS_TYPE_P (type))
5473 5 : return make_tree_vec (0);
5474 :
5475 7 : releasing_vec vector;
5476 7 : tree bases_vec = NULL_TREE;
5477 7 : unsigned i;
5478 7 : vec<tree, va_gc> *vbases;
5479 7 : tree binfo;
5480 :
5481 : /* First go through virtual base classes */
5482 7 : for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0;
5483 16 : vec_safe_iterate (vbases, i, &binfo); i++)
5484 : {
5485 9 : releasing_vec vbase_bases
5486 9 : = calculate_bases_helper (BINFO_TYPE (binfo));
5487 9 : vec_safe_splice (vector, vbase_bases);
5488 9 : }
5489 :
5490 : /* Now for the non-virtual bases */
5491 7 : releasing_vec nonvbases = calculate_bases_helper (type);
5492 7 : vec_safe_splice (vector, nonvbases);
5493 :
5494 : /* Note that during error recovery vector->length can even be zero. */
5495 7 : if (vector->length () > 1)
5496 : {
5497 : /* Last element is entire class, so don't copy */
5498 6 : bases_vec = make_tree_vec (vector->length () - 1);
5499 :
5500 53 : for (i = 0; i < vector->length () - 1; ++i)
5501 41 : TREE_VEC_ELT (bases_vec, i) = (*vector)[i];
5502 : }
5503 : else
5504 1 : bases_vec = make_tree_vec (0);
5505 :
5506 7 : return bases_vec;
5507 7 : }
5508 :
5509 : tree
5510 28 : finish_bases (tree type, bool direct)
5511 : {
5512 28 : tree bases = NULL_TREE;
5513 :
5514 28 : if (!processing_template_decl)
5515 : {
5516 : /* Parameter packs can only be used in templates */
5517 0 : error ("parameter pack %<__bases%> only valid in template declaration");
5518 0 : return error_mark_node;
5519 : }
5520 :
5521 28 : bases = cxx_make_type (BASES);
5522 28 : BASES_TYPE (bases) = type;
5523 28 : BASES_DIRECT (bases) = direct;
5524 28 : SET_TYPE_STRUCTURAL_EQUALITY (bases);
5525 :
5526 28 : return bases;
5527 : }
5528 :
5529 : /* Perform C++-specific checks for __builtin_offsetof before calling
5530 : fold_offsetof. */
5531 :
5532 : tree
5533 2497 : finish_offsetof (tree object_ptr, tree expr, location_t loc)
5534 : {
5535 : /* If we're processing a template, we can't finish the semantics yet.
5536 : Otherwise we can fold the entire expression now. */
5537 2497 : if (processing_template_decl)
5538 : {
5539 60 : expr = build2 (OFFSETOF_EXPR, size_type_node, expr, object_ptr);
5540 60 : SET_EXPR_LOCATION (expr, loc);
5541 60 : return expr;
5542 : }
5543 :
5544 2437 : if (expr == error_mark_node)
5545 : return error_mark_node;
5546 :
5547 2420 : if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
5548 : {
5549 6 : error ("cannot apply %<offsetof%> to destructor %<~%T%>",
5550 6 : TREE_OPERAND (expr, 2));
5551 6 : return error_mark_node;
5552 : }
5553 4813 : if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr))
5554 4813 : || TREE_TYPE (expr) == unknown_type_node)
5555 : {
5556 30 : while (TREE_CODE (expr) == COMPONENT_REF
5557 30 : || TREE_CODE (expr) == COMPOUND_EXPR)
5558 12 : expr = TREE_OPERAND (expr, 1);
5559 :
5560 18 : if (DECL_P (expr))
5561 : {
5562 0 : auto_diagnostic_group d;
5563 0 : error ("cannot apply %<offsetof%> to member function %qD", expr);
5564 0 : inform (DECL_SOURCE_LOCATION (expr), "declared here");
5565 0 : }
5566 : else
5567 18 : error ("cannot apply %<offsetof%> to member function");
5568 18 : return error_mark_node;
5569 : }
5570 2396 : if (TREE_CODE (expr) == CONST_DECL)
5571 : {
5572 3 : error ("cannot apply %<offsetof%> to an enumerator %qD", expr);
5573 3 : return error_mark_node;
5574 : }
5575 2393 : if (REFERENCE_REF_P (expr))
5576 9 : expr = TREE_OPERAND (expr, 0);
5577 2393 : if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr))
5578 3 : return error_mark_node;
5579 2390 : if (warn_invalid_offsetof
5580 2390 : && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr)))
5581 2390 : && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr)))
5582 2435 : && cp_unevaluated_operand == 0)
5583 45 : warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within "
5584 : "non-standard-layout type %qT is conditionally-supported",
5585 45 : TREE_TYPE (TREE_TYPE (object_ptr)));
5586 2390 : return fold_offsetof (expr);
5587 : }
5588 :
5589 : /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
5590 : function is broken out from the above for the benefit of the tree-ssa
5591 : project. */
5592 :
5593 : void
5594 376456 : simplify_aggr_init_expr (tree *tp)
5595 : {
5596 376456 : tree aggr_init_expr = *tp;
5597 :
5598 : /* Form an appropriate CALL_EXPR. */
5599 376456 : tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr);
5600 376456 : tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
5601 376456 : tree type = TREE_TYPE (slot);
5602 :
5603 376456 : tree call_expr;
5604 376456 : enum style_t { ctor, arg, pcc } style;
5605 :
5606 376456 : if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
5607 : style = ctor;
5608 : #ifdef PCC_STATIC_STRUCT_RETURN
5609 : else if (1)
5610 : style = pcc;
5611 : #endif
5612 : else
5613 : {
5614 101072 : gcc_assert (TREE_ADDRESSABLE (type));
5615 : style = arg;
5616 : }
5617 :
5618 376456 : call_expr = build_call_array_loc (input_location,
5619 376456 : TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
5620 : fn,
5621 376456 : aggr_init_expr_nargs (aggr_init_expr),
5622 376456 : AGGR_INIT_EXPR_ARGP (aggr_init_expr));
5623 376456 : TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr);
5624 376456 : CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr);
5625 376456 : CALL_EXPR_OPERATOR_SYNTAX (call_expr)
5626 376456 : = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr);
5627 376456 : CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr);
5628 376456 : CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr);
5629 376456 : CALL_EXPR_MUST_TAIL_CALL (call_expr) = AGGR_INIT_EXPR_MUST_TAIL (aggr_init_expr);
5630 :
5631 376456 : if (style == ctor)
5632 : {
5633 : /* Replace the first argument to the ctor with the address of the
5634 : slot. */
5635 275384 : cxx_mark_addressable (slot);
5636 275384 : CALL_EXPR_ARG (call_expr, 0) =
5637 275384 : build1 (ADDR_EXPR, build_pointer_type (type), slot);
5638 : }
5639 101072 : else if (style == arg)
5640 : {
5641 : /* Just mark it addressable here, and leave the rest to
5642 : expand_call{,_inline}. */
5643 101072 : cxx_mark_addressable (slot);
5644 101072 : CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
5645 101072 : call_expr = cp_build_init_expr (slot, call_expr);
5646 : }
5647 : else if (style == pcc)
5648 : {
5649 : /* If we're using the non-reentrant PCC calling convention, then we
5650 : need to copy the returned value out of the static buffer into the
5651 : SLOT. */
5652 : push_deferring_access_checks (dk_no_check);
5653 : call_expr = build_aggr_init (slot, call_expr,
5654 : DIRECT_BIND | LOOKUP_ONLYCONVERTING,
5655 : tf_warning_or_error);
5656 : pop_deferring_access_checks ();
5657 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
5658 : }
5659 :
5660 376456 : if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
5661 : {
5662 4194 : tree init = build_zero_init (type, NULL_TREE,
5663 : /*static_storage_p=*/false);
5664 4194 : init = cp_build_init_expr (slot, init);
5665 4194 : call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
5666 : init, call_expr);
5667 : }
5668 :
5669 376456 : *tp = call_expr;
5670 376456 : }
5671 :
5672 : /* Emit all thunks to FN that should be emitted when FN is emitted. */
5673 :
5674 : void
5675 61720438 : emit_associated_thunks (tree fn)
5676 : {
5677 : /* When we use vcall offsets, we emit thunks with the virtual
5678 : functions to which they thunk. The whole point of vcall offsets
5679 : is so that you can know statically the entire set of thunks that
5680 : will ever be needed for a given virtual function, thereby
5681 : enabling you to output all the thunks with the function itself. */
5682 61720438 : if (DECL_VIRTUAL_P (fn)
5683 : /* Do not emit thunks for extern template instantiations. */
5684 1174687 : && ! DECL_REALLY_EXTERN (fn)
5685 : /* Do not emit thunks for tentative decls, those will be processed
5686 : again at_eof if really needed. */
5687 62777670 : && (DECL_INTERFACE_KNOWN (fn) || !DECL_DEFER_OUTPUT (fn)))
5688 : {
5689 1056114 : tree thunk;
5690 :
5691 1060544 : for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk))
5692 : {
5693 4430 : if (!THUNK_ALIAS (thunk))
5694 : {
5695 4430 : use_thunk (thunk, /*emit_p=*/1);
5696 4430 : if (DECL_RESULT_THUNK_P (thunk))
5697 : {
5698 181 : tree probe;
5699 :
5700 181 : for (probe = DECL_THUNKS (thunk);
5701 333 : probe; probe = DECL_CHAIN (probe))
5702 152 : use_thunk (probe, /*emit_p=*/1);
5703 : }
5704 : }
5705 : else
5706 0 : gcc_assert (!DECL_THUNKS (thunk));
5707 : }
5708 : }
5709 61720438 : }
5710 :
5711 : /* Generate RTL for FN. */
5712 :
5713 : bool
5714 168077756 : expand_or_defer_fn_1 (tree fn)
5715 : {
5716 : /* When the parser calls us after finishing the body of a template
5717 : function, we don't really want to expand the body. */
5718 168077756 : if (processing_template_decl)
5719 : {
5720 : /* Normally, collection only occurs in rest_of_compilation. So,
5721 : if we don't collect here, we never collect junk generated
5722 : during the processing of templates until we hit a
5723 : non-template function. It's not safe to do this inside a
5724 : nested class, though, as the parser may have local state that
5725 : is not a GC root. */
5726 98098989 : if (!function_depth)
5727 97643479 : ggc_collect ();
5728 : return false;
5729 : }
5730 :
5731 69978767 : gcc_assert (DECL_SAVED_TREE (fn));
5732 :
5733 : /* We make a decision about linkage for these functions at the end
5734 : of the compilation. Until that point, we do not want the back
5735 : end to output them -- but we do want it to see the bodies of
5736 : these functions so that it can inline them as appropriate. */
5737 69978767 : if (DECL_DECLARED_INLINE_P (fn)
5738 1966365 : || DECL_IMPLICIT_INSTANTIATION (fn)
5739 70243216 : || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (fn))
5740 : {
5741 69714345 : if (DECL_INTERFACE_KNOWN (fn))
5742 : /* We've already made a decision as to how this function will
5743 : be handled. */;
5744 49301814 : else if (!at_eof
5745 17766743 : || DECL_IMMEDIATE_FUNCTION_P (fn)
5746 66631843 : || DECL_OMP_DECLARE_REDUCTION_P (fn))
5747 31971785 : tentative_decl_linkage (fn);
5748 : else
5749 17330029 : import_export_decl (fn);
5750 :
5751 : /* If the user wants us to keep all inline functions, then mark
5752 : this function as needed so that finish_file will make sure to
5753 : output it later. Similarly, all dllexport'd functions must
5754 : be emitted; there may be callers in other DLLs. */
5755 69714345 : if (DECL_DECLARED_INLINE_P (fn)
5756 68012402 : && !DECL_REALLY_EXTERN (fn)
5757 64252861 : && !DECL_IMMEDIATE_FUNCTION_P (fn)
5758 63200134 : && !DECL_OMP_DECLARE_REDUCTION_P (fn)
5759 132914479 : && (flag_keep_inline_functions
5760 63197341 : || (flag_keep_inline_dllexport
5761 63197341 : && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))))
5762 : {
5763 2793 : mark_needed (fn);
5764 2793 : DECL_EXTERNAL (fn) = 0;
5765 : }
5766 : }
5767 :
5768 : /* If this is a constructor or destructor body, we have to clone
5769 : it. */
5770 69978767 : if (maybe_clone_body (fn))
5771 : {
5772 : /* We don't want to process FN again, so pretend we've written
5773 : it out, even though we haven't. */
5774 8230129 : TREE_ASM_WRITTEN (fn) = 1;
5775 : /* If this is a constexpr function we still need the body to be
5776 : able to evaluate it. Similarly, with modules we only stream
5777 : the maybe-in-charge cdtor and regenerate the clones from it on
5778 : demand, so we also need to keep the body. Otherwise we don't
5779 : need it anymore. */
5780 8230129 : if (!maybe_constexpr_fn (fn)
5781 8230129 : && !(module_maybe_has_cmi_p () && vague_linkage_p (fn)))
5782 3845983 : DECL_SAVED_TREE (fn) = void_node;
5783 : return false;
5784 : }
5785 :
5786 : /* There's no reason to do any of the work here if we're only doing
5787 : semantic analysis; this code just generates RTL. */
5788 61748638 : if (flag_syntax_only)
5789 : {
5790 : /* Pretend that this function has been written out so that we don't try
5791 : to expand it again. */
5792 28184 : TREE_ASM_WRITTEN (fn) = 1;
5793 28184 : return false;
5794 : }
5795 :
5796 61720454 : if (DECL_OMP_DECLARE_REDUCTION_P (fn))
5797 16 : return false;
5798 :
5799 : return true;
5800 : }
5801 :
5802 : void
5803 159865876 : expand_or_defer_fn (tree fn)
5804 : {
5805 159865876 : if (expand_or_defer_fn_1 (fn))
5806 : {
5807 53511049 : function_depth++;
5808 :
5809 : /* Expand or defer, at the whim of the compilation unit manager. */
5810 53511049 : cgraph_node::finalize_function (fn, function_depth > 1);
5811 53511049 : emit_associated_thunks (fn);
5812 :
5813 53511049 : function_depth--;
5814 :
5815 107022098 : if (DECL_IMMEDIATE_FUNCTION_P (fn))
5816 : {
5817 1008271 : if (cgraph_node *node = cgraph_node::get (fn))
5818 : {
5819 1008271 : node->body_removed = true;
5820 1008271 : node->analyzed = false;
5821 1008271 : node->definition = false;
5822 1008271 : node->force_output = false;
5823 : }
5824 : }
5825 : }
5826 159865876 : }
5827 :
5828 468752 : class nrv_data
5829 : {
5830 : public:
5831 234376 : nrv_data () : visited (37) {}
5832 :
5833 : tree var;
5834 : tree result;
5835 : hash_set<tree> visited;
5836 : bool simple;
5837 : bool in_nrv_cleanup;
5838 : };
5839 :
5840 : /* Helper function for walk_tree, used by finalize_nrv below. */
5841 :
5842 : static tree
5843 21241121 : finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
5844 : {
5845 21241121 : class nrv_data *dp = (class nrv_data *)data;
5846 :
5847 : /* No need to walk into types. There wouldn't be any need to walk into
5848 : non-statements, except that we have to consider STMT_EXPRs. */
5849 21241121 : if (TYPE_P (*tp))
5850 193526 : *walk_subtrees = 0;
5851 :
5852 : /* Replace all uses of the NRV with the RESULT_DECL. */
5853 21047595 : else if (*tp == dp->var)
5854 509243 : *tp = dp->result;
5855 :
5856 : /* Avoid walking into the same tree more than once. Unfortunately, we
5857 : can't just use walk_tree_without duplicates because it would only call
5858 : us for the first occurrence of dp->var in the function body. */
5859 20538352 : else if (dp->visited.add (*tp))
5860 4492508 : *walk_subtrees = 0;
5861 :
5862 : /* If there's a label, we might need to destroy the NRV on goto (92407). */
5863 16045844 : else if (TREE_CODE (*tp) == LABEL_EXPR && !dp->in_nrv_cleanup)
5864 3 : dp->simple = false;
5865 : /* Change NRV returns to just refer to the RESULT_DECL; this is a nop,
5866 : but differs from using NULL_TREE in that it indicates that we care
5867 : about the value of the RESULT_DECL. But preserve anything appended
5868 : by check_return_expr. */
5869 16045841 : else if (TREE_CODE (*tp) == RETURN_EXPR)
5870 : {
5871 240586 : tree *p = &TREE_OPERAND (*tp, 0);
5872 616885 : while (TREE_CODE (*p) == COMPOUND_EXPR)
5873 135713 : p = &TREE_OPERAND (*p, 0);
5874 240586 : if (TREE_CODE (*p) == INIT_EXPR
5875 240586 : && INIT_EXPR_NRV_P (*p))
5876 240176 : *p = dp->result;
5877 : }
5878 : /* Change all cleanups for the NRV to only run when not returning. */
5879 15805255 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5880 15805255 : && CLEANUP_DECL (*tp) == dp->var)
5881 : {
5882 130567 : dp->in_nrv_cleanup = true;
5883 130567 : cp_walk_tree (&CLEANUP_BODY (*tp), finalize_nrv_r, data, 0);
5884 130567 : dp->in_nrv_cleanup = false;
5885 130567 : cp_walk_tree (&CLEANUP_EXPR (*tp), finalize_nrv_r, data, 0);
5886 130567 : *walk_subtrees = 0;
5887 :
5888 130567 : if (dp->simple)
5889 : /* For a simple NRV, just run it on the EH path. */
5890 129904 : CLEANUP_EH_ONLY (*tp) = true;
5891 : else
5892 : {
5893 : /* Not simple, we need to check current_retval_sentinel to decide
5894 : whether to run it. If it's set, we're returning normally and
5895 : don't want to destroy the NRV. If the sentinel is not set, we're
5896 : leaving scope some other way, either by flowing off the end of its
5897 : scope or throwing an exception. */
5898 1989 : tree cond = build3 (COND_EXPR, void_type_node,
5899 663 : current_retval_sentinel,
5900 663 : void_node, CLEANUP_EXPR (*tp));
5901 663 : CLEANUP_EXPR (*tp) = cond;
5902 : }
5903 :
5904 : /* If a cleanup might throw, we need to clear current_retval_sentinel on
5905 : the exception path, both so the check above succeeds and so an outer
5906 : cleanup added by maybe_splice_retval_cleanup doesn't run. */
5907 130567 : if (cp_function_chain->throwing_cleanup)
5908 : {
5909 220 : tree clear = build2 (MODIFY_EXPR, boolean_type_node,
5910 : current_retval_sentinel,
5911 : boolean_false_node);
5912 220 : if (dp->simple)
5913 : {
5914 : /* We're already only on the EH path, just prepend it. */
5915 210 : tree &exp = CLEANUP_EXPR (*tp);
5916 210 : exp = build2 (COMPOUND_EXPR, void_type_node, clear, exp);
5917 : }
5918 : else
5919 : {
5920 : /* The cleanup runs on both normal and EH paths, we need another
5921 : CLEANUP_STMT to clear the flag only on the EH path. */
5922 10 : tree &bod = CLEANUP_BODY (*tp);
5923 10 : bod = build_stmt (EXPR_LOCATION (*tp), CLEANUP_STMT,
5924 10 : bod, clear, current_retval_sentinel);
5925 10 : CLEANUP_EH_ONLY (bod) = true;
5926 : }
5927 : }
5928 : }
5929 : /* Disable maybe_splice_retval_cleanup within the NRV cleanup scope, we don't
5930 : want to destroy the retval before the variable goes out of scope. */
5931 15674688 : else if (TREE_CODE (*tp) == CLEANUP_STMT
5932 5184 : && dp->in_nrv_cleanup
5933 15678427 : && CLEANUP_DECL (*tp) == dp->result)
5934 6 : CLEANUP_EXPR (*tp) = void_node;
5935 : /* Replace the DECL_EXPR for the NRV with an initialization of the
5936 : RESULT_DECL, if needed. */
5937 15674682 : else if (TREE_CODE (*tp) == DECL_EXPR
5938 15674682 : && DECL_EXPR_DECL (*tp) == dp->var)
5939 : {
5940 234378 : tree init;
5941 234378 : if (DECL_INITIAL (dp->var)
5942 234378 : && DECL_INITIAL (dp->var) != error_mark_node)
5943 95973 : init = cp_build_init_expr (dp->result,
5944 95973 : DECL_INITIAL (dp->var));
5945 : else
5946 138405 : init = build_empty_stmt (EXPR_LOCATION (*tp));
5947 234378 : DECL_INITIAL (dp->var) = NULL_TREE;
5948 234378 : SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp));
5949 234378 : *tp = init;
5950 : }
5951 :
5952 : /* Keep iterating. */
5953 21241121 : return NULL_TREE;
5954 : }
5955 :
5956 : /* Called from finish_function to implement the named return value
5957 : optimization by overriding all the RETURN_EXPRs and pertinent
5958 : CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the
5959 : RESULT_DECL for the function. */
5960 :
5961 : void
5962 234376 : finalize_nrv (tree fndecl, tree var)
5963 : {
5964 234376 : class nrv_data data;
5965 234376 : tree result = DECL_RESULT (fndecl);
5966 :
5967 : /* Copy name from VAR to RESULT. */
5968 234376 : DECL_NAME (result) = DECL_NAME (var);
5969 : /* Don't forget that we take its address. */
5970 234376 : TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var);
5971 : /* Finally set DECL_VALUE_EXPR to avoid assigning
5972 : a stack slot at -O0 for the original var and debug info
5973 : uses RESULT location for VAR. */
5974 234376 : SET_DECL_VALUE_EXPR (var, result);
5975 234376 : DECL_HAS_VALUE_EXPR_P (var) = 1;
5976 :
5977 234376 : data.var = var;
5978 234376 : data.result = result;
5979 234376 : data.in_nrv_cleanup = false;
5980 :
5981 : /* This is simpler for variables declared in the outer scope of
5982 : the function so we know that their lifetime always ends with a
5983 : return; see g++.dg/opt/nrv6.C. */
5984 234376 : tree outer = outer_curly_brace_block (fndecl);
5985 234376 : data.simple = chain_member (var, BLOCK_VARS (outer));
5986 :
5987 234376 : cp_walk_tree (&DECL_SAVED_TREE (fndecl), finalize_nrv_r, &data, 0);
5988 234376 : }
5989 :
5990 : /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */
5991 :
5992 : bool
5993 2249 : cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor,
5994 : bool need_copy_ctor, bool need_copy_assignment,
5995 : bool need_dtor)
5996 : {
5997 2249 : int save_errorcount = errorcount;
5998 2249 : tree info, t;
5999 :
6000 : /* Always allocate 3 elements for simplicity. These are the
6001 : function decls for the ctor, dtor, and assignment op.
6002 : This layout is known to the three lang hooks,
6003 : cxx_omp_clause_default_init, cxx_omp_clause_copy_init,
6004 : and cxx_omp_clause_assign_op. */
6005 2249 : info = make_tree_vec (3);
6006 2249 : CP_OMP_CLAUSE_INFO (c) = info;
6007 :
6008 2249 : if (need_default_ctor || need_copy_ctor)
6009 : {
6010 1654 : if (need_default_ctor)
6011 1255 : t = get_default_ctor (type);
6012 : else
6013 399 : t = get_copy_ctor (type, tf_warning_or_error);
6014 :
6015 1654 : if (t && !trivial_fn_p (t))
6016 1400 : TREE_VEC_ELT (info, 0) = t;
6017 : }
6018 :
6019 2249 : if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
6020 1632 : TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error);
6021 :
6022 2249 : if (need_copy_assignment)
6023 : {
6024 397 : t = get_copy_assign (type);
6025 :
6026 397 : if (t && !trivial_fn_p (t))
6027 344 : TREE_VEC_ELT (info, 2) = t;
6028 : }
6029 :
6030 2249 : return errorcount != save_errorcount;
6031 : }
6032 :
6033 : /* If DECL is DECL_OMP_PRIVATIZED_MEMBER, return corresponding
6034 : FIELD_DECL, otherwise return DECL itself. */
6035 :
6036 : static tree
6037 26714 : omp_clause_decl_field (tree decl)
6038 : {
6039 26714 : if (VAR_P (decl)
6040 18651 : && DECL_HAS_VALUE_EXPR_P (decl)
6041 359 : && DECL_ARTIFICIAL (decl)
6042 359 : && DECL_LANG_SPECIFIC (decl)
6043 27049 : && DECL_OMP_PRIVATIZED_MEMBER (decl))
6044 : {
6045 328 : tree f = DECL_VALUE_EXPR (decl);
6046 328 : if (INDIRECT_REF_P (f))
6047 0 : f = TREE_OPERAND (f, 0);
6048 328 : if (TREE_CODE (f) == COMPONENT_REF)
6049 : {
6050 328 : f = TREE_OPERAND (f, 1);
6051 328 : gcc_assert (TREE_CODE (f) == FIELD_DECL);
6052 : return f;
6053 : }
6054 : }
6055 : return NULL_TREE;
6056 : }
6057 :
6058 : /* Adjust DECL if needed for printing using %qE. */
6059 :
6060 : static tree
6061 187 : omp_clause_printable_decl (tree decl)
6062 : {
6063 0 : tree t = omp_clause_decl_field (decl);
6064 187 : if (t)
6065 45 : return t;
6066 : return decl;
6067 : }
6068 :
6069 : /* For a FIELD_DECL F and corresponding DECL_OMP_PRIVATIZED_MEMBER
6070 : VAR_DECL T that doesn't need a DECL_EXPR added, record it for
6071 : privatization. */
6072 :
6073 : static void
6074 219 : omp_note_field_privatization (tree f, tree t)
6075 : {
6076 219 : if (!omp_private_member_map)
6077 71 : omp_private_member_map = new hash_map<tree, tree>;
6078 219 : tree &v = omp_private_member_map->get_or_insert (f);
6079 219 : if (v == NULL_TREE)
6080 : {
6081 146 : v = t;
6082 146 : omp_private_member_vec.safe_push (f);
6083 : /* Signal that we don't want to create DECL_EXPR for this dummy var. */
6084 146 : omp_private_member_vec.safe_push (integer_zero_node);
6085 : }
6086 219 : }
6087 :
6088 : /* Privatize FIELD_DECL T, return corresponding DECL_OMP_PRIVATIZED_MEMBER
6089 : dummy VAR_DECL. */
6090 :
6091 : tree
6092 861 : omp_privatize_field (tree t, bool shared)
6093 : {
6094 861 : tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6095 861 : if (m == error_mark_node)
6096 : return error_mark_node;
6097 861 : if (!omp_private_member_map && !shared)
6098 365 : omp_private_member_map = new hash_map<tree, tree>;
6099 861 : if (TYPE_REF_P (TREE_TYPE (t)))
6100 : {
6101 123 : gcc_assert (INDIRECT_REF_P (m));
6102 123 : m = TREE_OPERAND (m, 0);
6103 : }
6104 861 : tree vb = NULL_TREE;
6105 861 : tree &v = shared ? vb : omp_private_member_map->get_or_insert (t);
6106 861 : if (v == NULL_TREE)
6107 : {
6108 770 : v = create_temporary_var (TREE_TYPE (m));
6109 770 : retrofit_lang_decl (v);
6110 770 : DECL_OMP_PRIVATIZED_MEMBER (v) = 1;
6111 770 : SET_DECL_VALUE_EXPR (v, m);
6112 770 : DECL_HAS_VALUE_EXPR_P (v) = 1;
6113 770 : if (!shared)
6114 690 : omp_private_member_vec.safe_push (t);
6115 : }
6116 861 : return v;
6117 : }
6118 :
6119 : /* C++ specialisation of the c_omp_address_inspector class. */
6120 :
6121 : class cp_omp_address_inspector : public c_omp_address_inspector
6122 : {
6123 : public:
6124 31566 : cp_omp_address_inspector (location_t loc, tree t)
6125 31566 : : c_omp_address_inspector (loc, t)
6126 : {
6127 : }
6128 :
6129 31566 : ~cp_omp_address_inspector ()
6130 : {
6131 23121 : }
6132 :
6133 134796 : bool processing_template_decl_p ()
6134 : {
6135 134796 : return processing_template_decl;
6136 : }
6137 :
6138 0 : void emit_unmappable_type_notes (tree t)
6139 : {
6140 0 : if (TREE_TYPE (t) != error_mark_node
6141 0 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
6142 0 : cxx_incomplete_type_inform (TREE_TYPE (t));
6143 0 : }
6144 :
6145 1062 : tree convert_from_reference (tree x)
6146 : {
6147 1062 : return ::convert_from_reference (x);
6148 : }
6149 :
6150 147 : tree build_array_ref (location_t loc, tree arr, tree idx)
6151 : {
6152 147 : return ::build_array_ref (loc, arr, idx);
6153 : }
6154 :
6155 23063 : bool check_clause (tree clause)
6156 : {
6157 23063 : if (TREE_CODE (orig) == COMPONENT_REF
6158 23063 : && invalid_nonstatic_memfn_p (EXPR_LOCATION (orig), orig,
6159 : tf_warning_or_error))
6160 : return false;
6161 23060 : if (!c_omp_address_inspector::check_clause (clause))
6162 : return false;
6163 : return true;
6164 : }
6165 : };
6166 :
6167 : /* Helper function for handle_omp_array_sections. Called recursively
6168 : to handle multiple array-section-subscripts. C is the clause,
6169 : T current expression (initially OMP_CLAUSE_DECL), which is either
6170 : a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound
6171 : expression if specified, TREE_VALUE length expression if specified,
6172 : TREE_CHAIN is what it has been specified after, or some decl.
6173 : TYPES vector is populated with array section types, MAYBE_ZERO_LEN
6174 : set to true if any of the array-section-subscript could have length
6175 : of zero (explicit or implicit), FIRST_NON_ONE is the index of the
6176 : first array-section-subscript which is known not to have length
6177 : of one. Given say:
6178 : map(a[:b][2:1][:c][:2][:d][e:f][2:5])
6179 : FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c]
6180 : all are or may have length of 1, array-section-subscript [:2] is the
6181 : first one known not to have length 1. For array-section-subscript
6182 : <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't
6183 : 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we
6184 : can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above
6185 : case though, as some lengths could be zero. */
6186 :
6187 : static tree
6188 21512 : handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
6189 : bool &maybe_zero_len, unsigned int &first_non_one,
6190 : enum c_omp_region_type ort)
6191 : {
6192 21512 : tree ret, low_bound, length, type;
6193 21512 : bool openacc = (ort & C_ORT_ACC) != 0;
6194 21512 : if (TREE_CODE (t) != OMP_ARRAY_SECTION)
6195 : {
6196 9717 : if (error_operand_p (t))
6197 6 : return error_mark_node;
6198 :
6199 9711 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6200 9711 : tree t_refto = ai.maybe_unconvert_ref (t);
6201 :
6202 9711 : if (!ai.check_clause (c))
6203 0 : return error_mark_node;
6204 9711 : else if (ai.component_access_p ()
6205 11099 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6206 64 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO
6207 40 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM))
6208 1388 : t = ai.get_root_term (true);
6209 : else
6210 8323 : t = ai.unconverted_ref_origin ();
6211 9711 : if (t == error_mark_node)
6212 : return error_mark_node;
6213 9711 : ret = t_refto;
6214 9711 : if (TREE_CODE (t) == FIELD_DECL)
6215 33 : ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6216 9678 : else if (!VAR_P (t)
6217 2870 : && (openacc || !EXPR_P (t))
6218 2675 : && TREE_CODE (t) != PARM_DECL)
6219 : {
6220 51 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
6221 : return NULL_TREE;
6222 33 : if (DECL_P (t))
6223 33 : error_at (OMP_CLAUSE_LOCATION (c),
6224 : "%qD is not a variable in %qs clause", t,
6225 33 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6226 : else
6227 0 : error_at (OMP_CLAUSE_LOCATION (c),
6228 : "%qE is not a variable in %qs clause", t,
6229 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6230 33 : return error_mark_node;
6231 : }
6232 9627 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6233 9236 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6234 17934 : && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
6235 : {
6236 18 : error_at (OMP_CLAUSE_LOCATION (c),
6237 : "%qD is threadprivate variable in %qs clause", t,
6238 18 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6239 18 : return error_mark_node;
6240 : }
6241 9642 : if (type_dependent_expression_p (ret))
6242 : return NULL_TREE;
6243 8931 : ret = convert_from_reference (ret);
6244 8931 : return ret;
6245 9711 : }
6246 :
6247 11795 : if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
6248 7868 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6249 6566 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6250 5282 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6251 14509 : && TREE_CODE (TREE_OPERAND (t, 0)) == FIELD_DECL)
6252 43 : TREE_OPERAND (t, 0) = omp_privatize_field (TREE_OPERAND (t, 0), false);
6253 11795 : ret = handle_omp_array_sections_1 (c, TREE_OPERAND (t, 0), types,
6254 : maybe_zero_len, first_non_one, ort);
6255 11795 : if (ret == error_mark_node || ret == NULL_TREE)
6256 : return ret;
6257 :
6258 10725 : type = TREE_TYPE (ret);
6259 10725 : low_bound = TREE_OPERAND (t, 1);
6260 10725 : length = TREE_OPERAND (t, 2);
6261 8606 : if ((low_bound && type_dependent_expression_p (low_bound))
6262 19248 : || (length && type_dependent_expression_p (length)))
6263 : return NULL_TREE;
6264 :
6265 10637 : if (low_bound == error_mark_node || length == error_mark_node)
6266 : return error_mark_node;
6267 :
6268 10625 : if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound)))
6269 : {
6270 75 : error_at (OMP_CLAUSE_LOCATION (c),
6271 : "low bound %qE of array section does not have integral type",
6272 : low_bound);
6273 75 : return error_mark_node;
6274 : }
6275 10550 : if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length)))
6276 : {
6277 75 : error_at (OMP_CLAUSE_LOCATION (c),
6278 : "length %qE of array section does not have integral type",
6279 : length);
6280 75 : return error_mark_node;
6281 : }
6282 10475 : if (low_bound)
6283 8422 : low_bound = mark_rvalue_use (low_bound);
6284 10475 : if (length)
6285 9412 : length = mark_rvalue_use (length);
6286 : /* We need to reduce to real constant-values for checks below. */
6287 9412 : if (length)
6288 9412 : length = fold_simple (length);
6289 10475 : if (low_bound)
6290 8422 : low_bound = fold_simple (low_bound);
6291 8422 : if (low_bound
6292 8422 : && TREE_CODE (low_bound) == INTEGER_CST
6293 15907 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6294 7485 : > TYPE_PRECISION (sizetype))
6295 0 : low_bound = fold_convert (sizetype, low_bound);
6296 10475 : if (length
6297 9412 : && TREE_CODE (length) == INTEGER_CST
6298 17864 : && TYPE_PRECISION (TREE_TYPE (length))
6299 7389 : > TYPE_PRECISION (sizetype))
6300 0 : length = fold_convert (sizetype, length);
6301 10475 : if (low_bound == NULL_TREE)
6302 2053 : low_bound = integer_zero_node;
6303 :
6304 10475 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
6305 10475 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
6306 5167 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH))
6307 : {
6308 60 : if (length != integer_one_node)
6309 : {
6310 36 : error_at (OMP_CLAUSE_LOCATION (c),
6311 : "expected single pointer in %qs clause",
6312 : user_omp_clause_code_name (c, openacc));
6313 36 : return error_mark_node;
6314 : }
6315 : }
6316 10439 : if (length != NULL_TREE)
6317 : {
6318 9400 : if (!integer_nonzerop (length))
6319 : {
6320 2078 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6321 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6322 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6323 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6324 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6325 : {
6326 479 : if (integer_zerop (length))
6327 : {
6328 36 : error_at (OMP_CLAUSE_LOCATION (c),
6329 : "zero length array section in %qs clause",
6330 36 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6331 36 : return error_mark_node;
6332 : }
6333 : }
6334 : else
6335 1599 : maybe_zero_len = true;
6336 : }
6337 9364 : if (first_non_one == types.length ()
6338 9364 : && (TREE_CODE (length) != INTEGER_CST || integer_onep (length)))
6339 3998 : first_non_one++;
6340 : }
6341 10403 : if (TREE_CODE (type) == ARRAY_TYPE)
6342 : {
6343 5796 : if (length == NULL_TREE
6344 5796 : && (TYPE_DOMAIN (type) == NULL_TREE
6345 955 : || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE))
6346 : {
6347 33 : error_at (OMP_CLAUSE_LOCATION (c),
6348 : "for unknown bound array type length expression must "
6349 : "be specified");
6350 33 : return error_mark_node;
6351 : }
6352 5763 : if (TREE_CODE (low_bound) == INTEGER_CST
6353 5763 : && tree_int_cst_sgn (low_bound) == -1)
6354 : {
6355 177 : error_at (OMP_CLAUSE_LOCATION (c),
6356 : "negative low bound in array section in %qs clause",
6357 177 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6358 177 : return error_mark_node;
6359 : }
6360 5586 : if (length != NULL_TREE
6361 4688 : && TREE_CODE (length) == INTEGER_CST
6362 9348 : && tree_int_cst_sgn (length) == -1)
6363 : {
6364 177 : error_at (OMP_CLAUSE_LOCATION (c),
6365 : "negative length in array section in %qs clause",
6366 177 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6367 177 : return error_mark_node;
6368 : }
6369 5409 : if (TYPE_DOMAIN (type)
6370 5310 : && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
6371 10719 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
6372 : == INTEGER_CST)
6373 : {
6374 4914 : tree size
6375 4914 : = fold_convert (sizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
6376 4914 : size = size_binop (PLUS_EXPR, size, size_one_node);
6377 4914 : if (TREE_CODE (low_bound) == INTEGER_CST)
6378 : {
6379 4137 : if (tree_int_cst_lt (size, low_bound))
6380 : {
6381 63 : error_at (OMP_CLAUSE_LOCATION (c),
6382 : "low bound %qE above array section size "
6383 : "in %qs clause", low_bound,
6384 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6385 63 : return error_mark_node;
6386 : }
6387 4074 : if (tree_int_cst_equal (size, low_bound))
6388 : {
6389 21 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
6390 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6391 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6392 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6393 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6394 : {
6395 21 : error_at (OMP_CLAUSE_LOCATION (c),
6396 : "zero length array section in %qs clause",
6397 21 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6398 21 : return error_mark_node;
6399 : }
6400 0 : maybe_zero_len = true;
6401 : }
6402 4053 : else if (length == NULL_TREE
6403 1578 : && first_non_one == types.length ()
6404 4406 : && tree_int_cst_equal
6405 353 : (TYPE_MAX_VALUE (TYPE_DOMAIN (type)),
6406 : low_bound))
6407 207 : first_non_one++;
6408 : }
6409 777 : else if (length == NULL_TREE)
6410 : {
6411 24 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6412 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6413 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6414 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6415 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6416 13 : maybe_zero_len = true;
6417 48 : if (first_non_one == types.length ())
6418 21 : first_non_one++;
6419 : }
6420 4830 : if (length && TREE_CODE (length) == INTEGER_CST)
6421 : {
6422 3465 : if (tree_int_cst_lt (size, length))
6423 : {
6424 63 : error_at (OMP_CLAUSE_LOCATION (c),
6425 : "length %qE above array section size "
6426 : "in %qs clause", length,
6427 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6428 63 : return error_mark_node;
6429 : }
6430 3402 : if (TREE_CODE (low_bound) == INTEGER_CST)
6431 : {
6432 3064 : tree lbpluslen
6433 3064 : = size_binop (PLUS_EXPR,
6434 : fold_convert (sizetype, low_bound),
6435 : fold_convert (sizetype, length));
6436 3064 : if (TREE_CODE (lbpluslen) == INTEGER_CST
6437 3064 : && tree_int_cst_lt (size, lbpluslen))
6438 : {
6439 60 : error_at (OMP_CLAUSE_LOCATION (c),
6440 : "high bound %qE above array section size "
6441 : "in %qs clause", lbpluslen,
6442 60 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6443 60 : return error_mark_node;
6444 : }
6445 : }
6446 : }
6447 : }
6448 495 : else if (length == NULL_TREE)
6449 : {
6450 1 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6451 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6452 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION
6453 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION
6454 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION)
6455 0 : maybe_zero_len = true;
6456 2 : if (first_non_one == types.length ())
6457 1 : first_non_one++;
6458 : }
6459 :
6460 : /* For [lb:] we will need to evaluate lb more than once. */
6461 4157 : if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6462 : {
6463 733 : tree lb = cp_save_expr (low_bound);
6464 733 : if (lb != low_bound)
6465 : {
6466 13 : TREE_OPERAND (t, 1) = lb;
6467 13 : low_bound = lb;
6468 : }
6469 : }
6470 : }
6471 4607 : else if (TYPE_PTR_P (type))
6472 : {
6473 4547 : if (length == NULL_TREE)
6474 : {
6475 51 : if (TREE_CODE (ret) == PARM_DECL && DECL_ARRAY_PARAMETER_P (ret))
6476 45 : error_at (OMP_CLAUSE_LOCATION (c),
6477 : "for array function parameter length expression "
6478 : "must be specified");
6479 : else
6480 6 : error_at (OMP_CLAUSE_LOCATION (c),
6481 : "for pointer type length expression must be specified");
6482 51 : return error_mark_node;
6483 : }
6484 4496 : if (length != NULL_TREE
6485 4496 : && TREE_CODE (length) == INTEGER_CST
6486 3399 : && tree_int_cst_sgn (length) == -1)
6487 : {
6488 96 : error_at (OMP_CLAUSE_LOCATION (c),
6489 : "negative length in array section in %qs clause",
6490 96 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6491 96 : return error_mark_node;
6492 : }
6493 : /* If there is a pointer type anywhere but in the very first
6494 : array-section-subscript, the array section could be non-contiguous. */
6495 4400 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
6496 4298 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND
6497 8213 : && TREE_CODE (TREE_OPERAND (t, 0)) == OMP_ARRAY_SECTION)
6498 : {
6499 : /* If any prior dimension has a non-one length, then deem this
6500 : array section as non-contiguous. */
6501 159 : for (tree d = TREE_OPERAND (t, 0); TREE_CODE (d) == OMP_ARRAY_SECTION;
6502 69 : d = TREE_OPERAND (d, 0))
6503 : {
6504 90 : tree d_length = TREE_OPERAND (d, 2);
6505 90 : if (d_length == NULL_TREE || !integer_onep (d_length))
6506 : {
6507 21 : error_at (OMP_CLAUSE_LOCATION (c),
6508 : "array section is not contiguous in %qs clause",
6509 21 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6510 21 : return error_mark_node;
6511 : }
6512 : }
6513 : }
6514 : }
6515 : else
6516 : {
6517 60 : error_at (OMP_CLAUSE_LOCATION (c),
6518 : "%qE does not have pointer or array type", ret);
6519 60 : return error_mark_node;
6520 : }
6521 9581 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
6522 8676 : types.safe_push (TREE_TYPE (ret));
6523 : /* We will need to evaluate lb more than once. */
6524 9581 : tree lb = cp_save_expr (low_bound);
6525 9581 : if (lb != low_bound)
6526 : {
6527 722 : TREE_OPERAND (t, 1) = lb;
6528 722 : low_bound = lb;
6529 : }
6530 : /* Temporarily disable -fstrong-eval-order for array reductions.
6531 : The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects
6532 : is something the middle-end can't cope with and more importantly,
6533 : it needs to be the actual base variable that is privatized, not some
6534 : temporary assigned previous value of it. That, together with OpenMP
6535 : saying how many times the side-effects are evaluated is unspecified,
6536 : makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified. */
6537 9581 : warning_sentinel s (flag_strong_eval_order,
6538 9581 : OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6539 8484 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6540 16931 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION);
6541 9581 : ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, NULL,
6542 : tf_warning_or_error);
6543 9581 : return ret;
6544 9581 : }
6545 :
6546 : /* Handle array sections for clause C. */
6547 :
6548 : static bool
6549 9717 : handle_omp_array_sections (tree &c, enum c_omp_region_type ort)
6550 : {
6551 9717 : bool maybe_zero_len = false;
6552 9717 : unsigned int first_non_one = 0;
6553 9717 : auto_vec<tree, 10> types;
6554 9717 : tree *tp = &OMP_CLAUSE_DECL (c);
6555 9717 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6556 8758 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6557 10126 : && OMP_ITERATOR_DECL_P (*tp))
6558 258 : tp = &TREE_VALUE (*tp);
6559 9717 : tree first = handle_omp_array_sections_1 (c, *tp, types,
6560 : maybe_zero_len, first_non_one,
6561 : ort);
6562 9717 : if (first == error_mark_node)
6563 : return true;
6564 8604 : if (first == NULL_TREE)
6565 : return false;
6566 7787 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
6567 7787 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY)
6568 : {
6569 951 : tree t = *tp;
6570 951 : tree tem = NULL_TREE;
6571 951 : if (processing_template_decl)
6572 : return false;
6573 : /* Need to evaluate side effects in the length expressions
6574 : if any. */
6575 852 : while (TREE_CODE (t) == TREE_LIST)
6576 : {
6577 0 : if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t)))
6578 : {
6579 0 : if (tem == NULL_TREE)
6580 : tem = TREE_VALUE (t);
6581 : else
6582 0 : tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem),
6583 0 : TREE_VALUE (t), tem);
6584 : }
6585 0 : t = TREE_CHAIN (t);
6586 : }
6587 852 : if (tem)
6588 0 : first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first);
6589 852 : *tp = first;
6590 : }
6591 : else
6592 : {
6593 6836 : unsigned int num = types.length (), i;
6594 6836 : tree t, side_effects = NULL_TREE, size = NULL_TREE;
6595 6836 : tree condition = NULL_TREE;
6596 :
6597 6836 : if (int_size_in_bytes (TREE_TYPE (first)) <= 0)
6598 3 : maybe_zero_len = true;
6599 6836 : if (processing_template_decl && maybe_zero_len)
6600 : return false;
6601 :
6602 14380 : for (i = num, t = OMP_CLAUSE_DECL (c); i > 0;
6603 7622 : t = TREE_OPERAND (t, 0))
6604 : {
6605 7697 : gcc_assert (TREE_CODE (t) == OMP_ARRAY_SECTION);
6606 :
6607 7697 : tree low_bound = TREE_OPERAND (t, 1);
6608 7697 : tree length = TREE_OPERAND (t, 2);
6609 :
6610 7697 : i--;
6611 7697 : if (low_bound
6612 6251 : && TREE_CODE (low_bound) == INTEGER_CST
6613 13337 : && TYPE_PRECISION (TREE_TYPE (low_bound))
6614 5640 : > TYPE_PRECISION (sizetype))
6615 0 : low_bound = fold_convert (sizetype, low_bound);
6616 7697 : if (length
6617 7148 : && TREE_CODE (length) == INTEGER_CST
6618 12953 : && TYPE_PRECISION (TREE_TYPE (length))
6619 5256 : > TYPE_PRECISION (sizetype))
6620 0 : length = fold_convert (sizetype, length);
6621 7697 : if (low_bound == NULL_TREE)
6622 1446 : low_bound = integer_zero_node;
6623 7697 : if (!maybe_zero_len && i > first_non_one)
6624 : {
6625 646 : if (integer_nonzerop (low_bound))
6626 36 : goto do_warn_noncontiguous;
6627 610 : if (length != NULL_TREE
6628 282 : && TREE_CODE (length) == INTEGER_CST
6629 282 : && TYPE_DOMAIN (types[i])
6630 282 : && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))
6631 892 : && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])))
6632 : == INTEGER_CST)
6633 : {
6634 282 : tree size;
6635 282 : size = size_binop (PLUS_EXPR,
6636 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6637 : size_one_node);
6638 282 : if (!tree_int_cst_equal (length, size))
6639 : {
6640 39 : do_warn_noncontiguous:
6641 150 : error_at (OMP_CLAUSE_LOCATION (c),
6642 : "array section is not contiguous in %qs "
6643 : "clause",
6644 75 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
6645 75 : return true;
6646 : }
6647 : }
6648 571 : if (!processing_template_decl
6649 401 : && length != NULL_TREE
6650 742 : && TREE_SIDE_EFFECTS (length))
6651 : {
6652 0 : if (side_effects == NULL_TREE)
6653 : side_effects = length;
6654 : else
6655 0 : side_effects = build2 (COMPOUND_EXPR,
6656 0 : TREE_TYPE (side_effects),
6657 : length, side_effects);
6658 : }
6659 : }
6660 7051 : else if (processing_template_decl)
6661 726 : continue;
6662 : else
6663 : {
6664 6325 : tree l;
6665 :
6666 6325 : if (i > first_non_one
6667 6325 : && ((length && integer_nonzerop (length))
6668 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6669 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6670 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION))
6671 0 : continue;
6672 6325 : if (length)
6673 6186 : l = fold_convert (sizetype, length);
6674 : else
6675 : {
6676 139 : l = size_binop (PLUS_EXPR,
6677 : TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])),
6678 : size_one_node);
6679 139 : l = size_binop (MINUS_EXPR, l,
6680 : fold_convert (sizetype, low_bound));
6681 : }
6682 6325 : if (i > first_non_one)
6683 : {
6684 0 : l = fold_build2 (NE_EXPR, boolean_type_node, l,
6685 : size_zero_node);
6686 0 : if (condition == NULL_TREE)
6687 : condition = l;
6688 : else
6689 0 : condition = fold_build2 (BIT_AND_EXPR, boolean_type_node,
6690 : l, condition);
6691 : }
6692 6325 : else if (size == NULL_TREE)
6693 : {
6694 6038 : size = size_in_bytes (TREE_TYPE (types[i]));
6695 6038 : tree eltype = TREE_TYPE (types[num - 1]);
6696 6109 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6697 71 : eltype = TREE_TYPE (eltype);
6698 6038 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6699 5228 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6700 10513 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6701 1659 : size = size_binop (EXACT_DIV_EXPR, size,
6702 : size_in_bytes (eltype));
6703 6038 : size = size_binop (MULT_EXPR, size, l);
6704 6038 : if (condition)
6705 0 : size = fold_build3 (COND_EXPR, sizetype, condition,
6706 : size, size_zero_node);
6707 : }
6708 : else
6709 287 : size = size_binop (MULT_EXPR, size, l);
6710 : }
6711 : }
6712 6683 : if (!processing_template_decl)
6713 : {
6714 6038 : if (side_effects)
6715 0 : size = build2 (COMPOUND_EXPR, sizetype, side_effects, size);
6716 6038 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
6717 5228 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
6718 10513 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
6719 : {
6720 1659 : size = size_binop (MINUS_EXPR, size, size_one_node);
6721 1659 : size = save_expr (size);
6722 1659 : tree index_type = build_index_type (size);
6723 1659 : tree eltype = TREE_TYPE (first);
6724 1688 : while (TREE_CODE (eltype) == ARRAY_TYPE)
6725 29 : eltype = TREE_TYPE (eltype);
6726 1659 : tree type = build_array_type (eltype, index_type);
6727 1659 : tree ptype = build_pointer_type (eltype);
6728 1659 : if (TYPE_REF_P (TREE_TYPE (t))
6729 1659 : && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
6730 170 : t = convert_from_reference (t);
6731 1489 : else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
6732 641 : t = build_fold_addr_expr (t);
6733 1659 : tree t2 = build_fold_addr_expr (first);
6734 1659 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6735 : ptrdiff_type_node, t2);
6736 1659 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
6737 : ptrdiff_type_node, t2,
6738 1659 : fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6739 : ptrdiff_type_node, t));
6740 1659 : if (tree_fits_shwi_p (t2))
6741 1321 : t = build2 (MEM_REF, type, t,
6742 1321 : build_int_cst (ptype, tree_to_shwi (t2)));
6743 : else
6744 : {
6745 338 : t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c),
6746 : sizetype, t2);
6747 338 : t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR,
6748 338 : TREE_TYPE (t), t, t2);
6749 338 : t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0));
6750 : }
6751 1659 : OMP_CLAUSE_DECL (c) = t;
6752 6038 : return false;
6753 : }
6754 4379 : OMP_CLAUSE_DECL (c) = first;
6755 4379 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR)
6756 : return false;
6757 4353 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
6758 4353 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
6759 3787 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH
6760 3775 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FORCE_DETACH))
6761 4329 : OMP_CLAUSE_SIZE (c) = size;
6762 4353 : if (TREE_CODE (t) == FIELD_DECL)
6763 3 : t = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
6764 :
6765 4353 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
6766 : return false;
6767 :
6768 3799 : if (TREE_CODE (first) == INDIRECT_REF)
6769 : {
6770 : /* Detect and skip adding extra nodes for pointer-to-member
6771 : mappings. These are unsupported for now. */
6772 2413 : tree tmp = TREE_OPERAND (first, 0);
6773 :
6774 2413 : if (TREE_CODE (tmp) == NON_LVALUE_EXPR)
6775 1915 : tmp = TREE_OPERAND (tmp, 0);
6776 :
6777 2413 : if (TREE_CODE (tmp) == INDIRECT_REF)
6778 158 : tmp = TREE_OPERAND (tmp, 0);
6779 :
6780 2413 : if (TREE_CODE (tmp) == POINTER_PLUS_EXPR)
6781 : {
6782 468 : tree offset = TREE_OPERAND (tmp, 1);
6783 468 : STRIP_NOPS (offset);
6784 468 : if (TYPE_PTRMEM_P (TREE_TYPE (offset)))
6785 : {
6786 36 : sorry_at (OMP_CLAUSE_LOCATION (c),
6787 : "pointer-to-member mapping %qE not supported",
6788 18 : OMP_CLAUSE_DECL (c));
6789 18 : return true;
6790 : }
6791 : }
6792 : }
6793 :
6794 : /* FIRST represents the first item of data that we are mapping.
6795 : E.g. if we're mapping an array, FIRST might resemble
6796 : "foo.bar.myarray[0]". */
6797 :
6798 3781 : auto_vec<omp_addr_token *, 10> addr_tokens;
6799 :
6800 3781 : if (!omp_parse_expr (addr_tokens, first))
6801 : return true;
6802 :
6803 3781 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
6804 :
6805 3781 : tree nc = ai.expand_map_clause (c, first, addr_tokens, ort);
6806 3781 : if (nc != error_mark_node)
6807 : {
6808 3781 : using namespace omp_addr_tokenizer;
6809 :
6810 3781 : if (ai.maybe_zero_length_array_section (c))
6811 3757 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
6812 :
6813 : /* !!! If we're accessing a base decl via chained access
6814 : methods (e.g. multiple indirections), duplicate clause
6815 : detection won't work properly. Skip it in that case. */
6816 3781 : if ((addr_tokens[0]->type == STRUCTURE_BASE
6817 2764 : || addr_tokens[0]->type == ARRAY_BASE)
6818 3781 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
6819 3770 : && addr_tokens[1]->type == ACCESS_METHOD
6820 7551 : && omp_access_chain_p (addr_tokens, 1))
6821 218 : c = nc;
6822 :
6823 3781 : return false;
6824 : }
6825 7562 : }
6826 : }
6827 : return false;
6828 9717 : }
6829 :
6830 : /* Return identifier to look up for omp declare reduction. */
6831 :
6832 : tree
6833 7113 : omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type)
6834 : {
6835 7113 : const char *p = NULL;
6836 7113 : const char *m = NULL;
6837 7113 : switch (reduction_code)
6838 : {
6839 4200 : case PLUS_EXPR:
6840 4200 : case MULT_EXPR:
6841 4200 : case MINUS_EXPR:
6842 4200 : case BIT_AND_EXPR:
6843 4200 : case BIT_XOR_EXPR:
6844 4200 : case BIT_IOR_EXPR:
6845 4200 : case TRUTH_ANDIF_EXPR:
6846 4200 : case TRUTH_ORIF_EXPR:
6847 4200 : reduction_id = ovl_op_identifier (false, reduction_code);
6848 4200 : break;
6849 : case MIN_EXPR:
6850 : p = "min";
6851 : break;
6852 : case MAX_EXPR:
6853 : p = "max";
6854 : break;
6855 : default:
6856 : break;
6857 : }
6858 :
6859 4200 : if (p == NULL)
6860 : {
6861 6949 : if (TREE_CODE (reduction_id) != IDENTIFIER_NODE)
6862 0 : return error_mark_node;
6863 6949 : p = IDENTIFIER_POINTER (reduction_id);
6864 : }
6865 :
6866 7113 : if (type != NULL_TREE)
6867 2047 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
6868 :
6869 7113 : const char prefix[] = "omp declare reduction ";
6870 7113 : size_t lenp = sizeof (prefix);
6871 7113 : if (strncmp (p, prefix, lenp - 1) == 0)
6872 2047 : lenp = 1;
6873 7113 : size_t len = strlen (p);
6874 7113 : size_t lenm = m ? strlen (m) + 1 : 0;
6875 7113 : char *name = XALLOCAVEC (char, lenp + len + lenm);
6876 7113 : if (lenp > 1)
6877 5066 : memcpy (name, prefix, lenp - 1);
6878 7113 : memcpy (name + lenp - 1, p, len + 1);
6879 7113 : if (m)
6880 : {
6881 2047 : name[lenp + len - 1] = '~';
6882 2047 : memcpy (name + lenp + len, m, lenm);
6883 : }
6884 7113 : return get_identifier (name);
6885 : }
6886 :
6887 : /* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial
6888 : FUNCTION_DECL or NULL_TREE if not found. */
6889 :
6890 : static tree
6891 1298 : omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp,
6892 : vec<tree> *ambiguousp)
6893 : {
6894 1298 : tree orig_id = id;
6895 1298 : tree baselink = NULL_TREE;
6896 1298 : if (identifier_p (id))
6897 : {
6898 1270 : cp_id_kind idk;
6899 1270 : bool nonint_cst_expression_p;
6900 1270 : const char *error_msg;
6901 1270 : id = omp_reduction_id (ERROR_MARK, id, type);
6902 1270 : tree decl = lookup_name (id);
6903 1270 : if (decl == NULL_TREE)
6904 80 : decl = error_mark_node;
6905 1270 : id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true,
6906 : &nonint_cst_expression_p, false, true, false,
6907 : false, &error_msg, loc);
6908 1270 : if (idk == CP_ID_KIND_UNQUALIFIED
6909 1350 : && identifier_p (id))
6910 : {
6911 80 : vec<tree, va_gc> *args = NULL;
6912 80 : vec_safe_push (args, build_reference_type (type));
6913 80 : id = perform_koenig_lookup (id, args, tf_none);
6914 : }
6915 : }
6916 28 : else if (TREE_CODE (id) == SCOPE_REF)
6917 28 : id = lookup_qualified_name (TREE_OPERAND (id, 0),
6918 : omp_reduction_id (ERROR_MARK,
6919 28 : TREE_OPERAND (id, 1),
6920 : type),
6921 : LOOK_want::NORMAL, false);
6922 1298 : tree fns = id;
6923 1298 : id = NULL_TREE;
6924 1298 : if (fns && is_overloaded_fn (fns))
6925 : {
6926 1224 : for (lkp_iterator iter (get_fns (fns)); iter; ++iter)
6927 : {
6928 1224 : tree fndecl = *iter;
6929 1224 : if (TREE_CODE (fndecl) == FUNCTION_DECL)
6930 : {
6931 1224 : tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
6932 1224 : if (same_type_p (TREE_TYPE (argtype), type))
6933 : {
6934 1224 : id = fndecl;
6935 1224 : break;
6936 : }
6937 : }
6938 : }
6939 :
6940 1224 : if (id && BASELINK_P (fns))
6941 : {
6942 74 : if (baselinkp)
6943 0 : *baselinkp = fns;
6944 : else
6945 74 : baselink = fns;
6946 : }
6947 : }
6948 :
6949 1298 : if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type))
6950 : {
6951 35 : auto_vec<tree> ambiguous;
6952 35 : tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE;
6953 35 : unsigned int ix;
6954 35 : if (ambiguousp == NULL)
6955 19 : ambiguousp = &ambiguous;
6956 73 : for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
6957 : {
6958 62 : id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo),
6959 : baselinkp ? baselinkp : &baselink,
6960 : ambiguousp);
6961 38 : if (id == NULL_TREE)
6962 14 : continue;
6963 24 : if (!ambiguousp->is_empty ())
6964 3 : ambiguousp->safe_push (id);
6965 21 : else if (ret != NULL_TREE)
6966 : {
6967 6 : ambiguousp->safe_push (ret);
6968 6 : ambiguousp->safe_push (id);
6969 6 : ret = NULL_TREE;
6970 : }
6971 : else
6972 15 : ret = id;
6973 : }
6974 35 : if (ambiguousp != &ambiguous)
6975 16 : return ret;
6976 19 : if (!ambiguous.is_empty ())
6977 : {
6978 6 : auto_diagnostic_group d;
6979 6 : const char *str = _("candidates are:");
6980 6 : unsigned int idx;
6981 6 : tree udr;
6982 6 : error_at (loc, "user defined reduction lookup is ambiguous");
6983 27 : FOR_EACH_VEC_ELT (ambiguous, idx, udr)
6984 : {
6985 15 : inform (DECL_SOURCE_LOCATION (udr), "%s %#qD", str, udr);
6986 15 : if (idx == 0)
6987 6 : str = get_spaces (str);
6988 : }
6989 6 : ret = error_mark_node;
6990 6 : baselink = NULL_TREE;
6991 6 : }
6992 19 : id = ret;
6993 35 : }
6994 1282 : if (id && baselink)
6995 74 : perform_or_defer_access_check (BASELINK_BINFO (baselink),
6996 : id, id, tf_warning_or_error);
6997 : return id;
6998 : }
6999 :
7000 : /* Return identifier to look up for omp declare mapper. */
7001 :
7002 : tree
7003 4067 : omp_mapper_id (tree mapper_id, tree type)
7004 : {
7005 4067 : const char *p = NULL;
7006 4067 : const char *m = NULL;
7007 :
7008 4067 : if (mapper_id == NULL_TREE)
7009 : p = "";
7010 91 : else if (TREE_CODE (mapper_id) == IDENTIFIER_NODE)
7011 91 : p = IDENTIFIER_POINTER (mapper_id);
7012 : else
7013 0 : return error_mark_node;
7014 :
7015 4067 : if (type != NULL_TREE)
7016 4059 : m = mangle_type_string (TYPE_MAIN_VARIANT (type));
7017 :
7018 4067 : const char prefix[] = "omp declare mapper ";
7019 4067 : size_t lenp = sizeof (prefix);
7020 4067 : if (strncmp (p, prefix, lenp - 1) == 0)
7021 8 : lenp = 1;
7022 4067 : size_t len = strlen (p);
7023 4067 : size_t lenm = m ? strlen (m) + 1 : 0;
7024 4067 : char *name = XALLOCAVEC (char, lenp + len + lenm);
7025 4067 : memcpy (name, prefix, lenp - 1);
7026 4067 : memcpy (name + lenp - 1, p, len + 1);
7027 4067 : if (m)
7028 : {
7029 4059 : name[lenp + len - 1] = '~';
7030 4059 : memcpy (name + lenp + len, m, lenm);
7031 : }
7032 4067 : return get_identifier (name);
7033 : }
7034 :
7035 : tree
7036 12067 : cxx_omp_mapper_lookup (tree id, tree type)
7037 : {
7038 12067 : if (!RECORD_OR_UNION_TYPE_P (type))
7039 : return NULL_TREE;
7040 3826 : id = omp_mapper_id (id, type);
7041 3826 : return lookup_name (id);
7042 : }
7043 :
7044 : tree
7045 375 : cxx_omp_extract_mapper_directive (tree vardecl)
7046 : {
7047 375 : gcc_assert (TREE_CODE (vardecl) == VAR_DECL);
7048 :
7049 : /* Instantiate the decl if we haven't already. */
7050 375 : mark_used (vardecl);
7051 375 : tree body = DECL_INITIAL (vardecl);
7052 :
7053 375 : if (TREE_CODE (body) == STATEMENT_LIST)
7054 : {
7055 0 : tree_stmt_iterator tsi = tsi_start (body);
7056 0 : gcc_assert (TREE_CODE (tsi_stmt (tsi)) == DECL_EXPR);
7057 0 : tsi_next (&tsi);
7058 0 : body = tsi_stmt (tsi);
7059 : }
7060 :
7061 375 : gcc_assert (TREE_CODE (body) == OMP_DECLARE_MAPPER);
7062 :
7063 375 : return body;
7064 : }
7065 :
7066 : /* For now we can handle singleton OMP_ARRAY_SECTIONs with custom mappers, but
7067 : nothing more complicated. */
7068 :
7069 : tree
7070 1968 : cxx_omp_map_array_section (location_t loc, tree t)
7071 : {
7072 1968 : tree low = TREE_OPERAND (t, 1);
7073 1968 : tree len = TREE_OPERAND (t, 2);
7074 :
7075 1968 : if (len && integer_onep (len))
7076 : {
7077 326 : t = TREE_OPERAND (t, 0);
7078 :
7079 326 : if (!low)
7080 26 : low = integer_zero_node;
7081 :
7082 326 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
7083 6 : t = convert_from_reference (t);
7084 :
7085 326 : if (TYPE_PTR_P (TREE_TYPE (t))
7086 326 : || TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7087 326 : t = build_array_ref (loc, t, low);
7088 : else
7089 : /* handle_omp_array_sections_1 has already diagnosed the error. */
7090 0 : t = error_mark_node;
7091 : }
7092 :
7093 1968 : return t;
7094 : }
7095 :
7096 : /* Helper function for cp_parser_omp_declare_reduction_exprs
7097 : and tsubst_omp_udr.
7098 : Remove CLEANUP_STMT for data (omp_priv variable).
7099 : Also append INIT_EXPR for DECL_INITIAL of omp_priv after its
7100 : DECL_EXPR. */
7101 :
7102 : tree
7103 4449 : cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data)
7104 : {
7105 4449 : if (TYPE_P (*tp))
7106 230 : *walk_subtrees = 0;
7107 4219 : else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data)
7108 52 : *tp = CLEANUP_BODY (*tp);
7109 4167 : else if (TREE_CODE (*tp) == DECL_EXPR)
7110 : {
7111 310 : tree decl = DECL_EXPR_DECL (*tp);
7112 310 : if (!processing_template_decl
7113 261 : && decl == (tree) data
7114 261 : && DECL_INITIAL (decl)
7115 402 : && DECL_INITIAL (decl) != error_mark_node)
7116 : {
7117 92 : tree list = NULL_TREE;
7118 92 : append_to_statement_list_force (*tp, &list);
7119 92 : tree init_expr = build2 (INIT_EXPR, void_type_node,
7120 92 : decl, DECL_INITIAL (decl));
7121 92 : DECL_INITIAL (decl) = NULL_TREE;
7122 92 : append_to_statement_list_force (init_expr, &list);
7123 92 : *tp = list;
7124 : }
7125 : }
7126 4449 : return NULL_TREE;
7127 : }
7128 :
7129 : /* Data passed from cp_check_omp_declare_reduction to
7130 : cp_check_omp_declare_reduction_r. */
7131 :
7132 : struct cp_check_omp_declare_reduction_data
7133 : {
7134 : location_t loc;
7135 : tree stmts[7];
7136 : bool combiner_p;
7137 : };
7138 :
7139 : /* Helper function for cp_check_omp_declare_reduction, called via
7140 : cp_walk_tree. */
7141 :
7142 : static tree
7143 15042 : cp_check_omp_declare_reduction_r (tree *tp, int *, void *data)
7144 : {
7145 15042 : struct cp_check_omp_declare_reduction_data *udr_data
7146 : = (struct cp_check_omp_declare_reduction_data *) data;
7147 15042 : if (SSA_VAR_P (*tp)
7148 2702 : && !DECL_ARTIFICIAL (*tp)
7149 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3])
7150 225 : && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4]))
7151 : {
7152 135 : location_t loc = udr_data->loc;
7153 135 : if (udr_data->combiner_p)
7154 45 : error_at (loc, "%<#pragma omp declare reduction%> combiner refers to "
7155 : "variable %qD which is not %<omp_out%> nor %<omp_in%>",
7156 : *tp);
7157 : else
7158 90 : error_at (loc, "%<#pragma omp declare reduction%> initializer refers "
7159 : "to variable %qD which is not %<omp_priv%> nor "
7160 : "%<omp_orig%>",
7161 : *tp);
7162 135 : return *tp;
7163 : }
7164 : return NULL_TREE;
7165 : }
7166 :
7167 : /* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */
7168 :
7169 : bool
7170 1104 : cp_check_omp_declare_reduction (tree udr)
7171 : {
7172 1104 : tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr)));
7173 1104 : gcc_assert (TYPE_REF_P (type));
7174 1104 : type = TREE_TYPE (type);
7175 1104 : int i;
7176 1104 : location_t loc = DECL_SOURCE_LOCATION (udr);
7177 :
7178 1104 : if (type == error_mark_node)
7179 : return false;
7180 1104 : if (ARITHMETIC_TYPE_P (type))
7181 : {
7182 : static enum tree_code predef_codes[]
7183 : = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR,
7184 : BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR };
7185 3276 : for (i = 0; i < 8; i++)
7186 : {
7187 2918 : tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE);
7188 2918 : const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr));
7189 2918 : const char *n2 = IDENTIFIER_POINTER (id);
7190 2918 : if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0
7191 2918 : && (n1[IDENTIFIER_LENGTH (id)] == '~'
7192 0 : || n1[IDENTIFIER_LENGTH (id)] == '\0'))
7193 : break;
7194 : }
7195 :
7196 376 : if (i == 8
7197 358 : && TREE_CODE (type) != COMPLEX_EXPR)
7198 : {
7199 358 : const char prefix_minmax[] = "omp declare reduction m";
7200 358 : size_t prefix_size = sizeof (prefix_minmax) - 1;
7201 358 : const char *n = IDENTIFIER_POINTER (DECL_NAME (udr));
7202 358 : if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)),
7203 : prefix_minmax, prefix_size) == 0
7204 10 : && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n')
7205 4 : || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x'))
7206 368 : && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0'))
7207 6 : i = 0;
7208 : }
7209 376 : if (i < 8)
7210 : {
7211 24 : error_at (loc, "predeclared arithmetic type %qT in "
7212 : "%<#pragma omp declare reduction%>", type);
7213 24 : return false;
7214 : }
7215 : }
7216 : else if (FUNC_OR_METHOD_TYPE_P (type)
7217 : || TREE_CODE (type) == ARRAY_TYPE)
7218 : {
7219 24 : error_at (loc, "function or array type %qT in "
7220 : "%<#pragma omp declare reduction%>", type);
7221 24 : return false;
7222 : }
7223 : else if (TYPE_REF_P (type))
7224 : {
7225 0 : error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>",
7226 : type);
7227 0 : return false;
7228 : }
7229 704 : else if (TYPE_QUALS_NO_ADDR_SPACE (type))
7230 : {
7231 24 : error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
7232 : "type %qT in %<#pragma omp declare reduction%>", type);
7233 24 : return false;
7234 : }
7235 :
7236 1032 : tree body = DECL_SAVED_TREE (udr);
7237 1032 : if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST)
7238 : return true;
7239 :
7240 846 : tree_stmt_iterator tsi;
7241 846 : struct cp_check_omp_declare_reduction_data data;
7242 846 : memset (data.stmts, 0, sizeof data.stmts);
7243 846 : for (i = 0, tsi = tsi_start (body);
7244 4707 : i < 7 && !tsi_end_p (tsi);
7245 3861 : i++, tsi_next (&tsi))
7246 3861 : data.stmts[i] = tsi_stmt (tsi);
7247 846 : data.loc = loc;
7248 846 : gcc_assert (tsi_end_p (tsi));
7249 846 : if (i >= 3)
7250 : {
7251 846 : gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR
7252 : && TREE_CODE (data.stmts[1]) == DECL_EXPR);
7253 846 : if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */))
7254 : return true;
7255 801 : data.combiner_p = true;
7256 801 : if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r,
7257 : &data, NULL))
7258 45 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */);
7259 : }
7260 801 : if (i >= 6)
7261 : {
7262 339 : gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR
7263 : && TREE_CODE (data.stmts[4]) == DECL_EXPR);
7264 339 : data.combiner_p = false;
7265 339 : if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r,
7266 : &data, NULL)
7267 339 : || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])),
7268 : cp_check_omp_declare_reduction_r, &data, NULL))
7269 90 : suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */);
7270 339 : if (i == 7)
7271 201 : gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR);
7272 : }
7273 : return true;
7274 : }
7275 :
7276 : /* Helper function of finish_omp_clauses. Clone STMT as if we were making
7277 : an inline call. But, remap
7278 : the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER
7279 : and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */
7280 :
7281 : static tree
7282 2217 : clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
7283 : tree decl, tree placeholder)
7284 : {
7285 2217 : copy_body_data id;
7286 2217 : hash_map<tree, tree> decl_map;
7287 :
7288 2217 : decl_map.put (omp_decl1, placeholder);
7289 2217 : decl_map.put (omp_decl2, decl);
7290 2217 : memset (&id, 0, sizeof (id));
7291 2217 : id.src_fn = DECL_CONTEXT (omp_decl1);
7292 2217 : id.dst_fn = current_function_decl;
7293 2217 : id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
7294 2217 : id.decl_map = &decl_map;
7295 :
7296 2217 : id.copy_decl = copy_decl_no_change;
7297 2217 : id.transform_call_graph_edges = CB_CGE_DUPLICATE;
7298 2217 : id.transform_new_cfg = true;
7299 2217 : id.transform_return_to_modify = false;
7300 2217 : id.eh_lp_nr = 0;
7301 2217 : walk_tree (&stmt, copy_tree_body_r, &id, NULL);
7302 2217 : return stmt;
7303 2217 : }
7304 :
7305 : /* Helper function of finish_omp_clauses, called via cp_walk_tree.
7306 : Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */
7307 :
7308 : static tree
7309 15573 : find_omp_placeholder_r (tree *tp, int *, void *data)
7310 : {
7311 15573 : if (*tp == (tree) data)
7312 274 : return *tp;
7313 : return NULL_TREE;
7314 : }
7315 :
7316 : /* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C.
7317 : Return true if there is some error and the clause should be removed. */
7318 :
7319 : static bool
7320 9018 : finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor)
7321 : {
7322 9018 : tree t = OMP_CLAUSE_DECL (c);
7323 9018 : bool predefined = false;
7324 9018 : if (TREE_CODE (t) == TREE_LIST)
7325 : {
7326 0 : gcc_assert (processing_template_decl);
7327 : return false;
7328 : }
7329 9018 : tree type = TREE_TYPE (t);
7330 9018 : if (TREE_CODE (t) == MEM_REF)
7331 1656 : type = TREE_TYPE (type);
7332 9018 : if (TYPE_REF_P (type))
7333 557 : type = TREE_TYPE (type);
7334 9018 : if (TREE_CODE (type) == ARRAY_TYPE)
7335 : {
7336 377 : tree oatype = type;
7337 377 : gcc_assert (TREE_CODE (t) != MEM_REF);
7338 757 : while (TREE_CODE (type) == ARRAY_TYPE)
7339 380 : type = TREE_TYPE (type);
7340 377 : if (!processing_template_decl)
7341 : {
7342 270 : t = require_complete_type (t);
7343 270 : if (t == error_mark_node
7344 270 : || !complete_type_or_else (oatype, NULL_TREE))
7345 : return true;
7346 261 : tree size = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (oatype),
7347 : TYPE_SIZE_UNIT (type));
7348 261 : if (integer_zerop (size))
7349 : {
7350 6 : error_at (OMP_CLAUSE_LOCATION (c),
7351 : "%qE in %<reduction%> clause is a zero size array",
7352 : omp_clause_printable_decl (t));
7353 3 : return true;
7354 : }
7355 258 : size = size_binop (MINUS_EXPR, size, size_one_node);
7356 258 : size = save_expr (size);
7357 258 : tree index_type = build_index_type (size);
7358 258 : tree atype = build_array_type (type, index_type);
7359 258 : tree ptype = build_pointer_type (type);
7360 258 : if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
7361 152 : t = build_fold_addr_expr (t);
7362 258 : t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0));
7363 258 : OMP_CLAUSE_DECL (c) = t;
7364 : }
7365 : }
7366 9006 : if (type == error_mark_node)
7367 : return true;
7368 9003 : else if (ARITHMETIC_TYPE_P (type))
7369 7734 : switch (OMP_CLAUSE_REDUCTION_CODE (c))
7370 : {
7371 : case PLUS_EXPR:
7372 : case MULT_EXPR:
7373 : case MINUS_EXPR:
7374 : case TRUTH_ANDIF_EXPR:
7375 : case TRUTH_ORIF_EXPR:
7376 : predefined = true;
7377 : break;
7378 246 : case MIN_EXPR:
7379 246 : case MAX_EXPR:
7380 246 : if (TREE_CODE (type) == COMPLEX_TYPE)
7381 : break;
7382 : predefined = true;
7383 : break;
7384 111 : case BIT_AND_EXPR:
7385 111 : case BIT_IOR_EXPR:
7386 111 : case BIT_XOR_EXPR:
7387 111 : if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
7388 : break;
7389 : predefined = true;
7390 : break;
7391 : default:
7392 : break;
7393 : }
7394 1269 : else if (TYPE_READONLY (type))
7395 : {
7396 18 : error_at (OMP_CLAUSE_LOCATION (c),
7397 : "%qE has const type for %<reduction%>",
7398 : omp_clause_printable_decl (t));
7399 9 : return true;
7400 : }
7401 1260 : else if (!processing_template_decl)
7402 : {
7403 1047 : t = require_complete_type (t);
7404 1047 : if (t == error_mark_node)
7405 : return true;
7406 1047 : OMP_CLAUSE_DECL (c) = t;
7407 : }
7408 :
7409 1047 : if (predefined)
7410 : {
7411 7512 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7412 7512 : return false;
7413 : }
7414 1482 : else if (processing_template_decl)
7415 : {
7416 222 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node)
7417 : return true;
7418 219 : return false;
7419 : }
7420 :
7421 1260 : tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
7422 :
7423 1260 : type = TYPE_MAIN_VARIANT (type);
7424 1260 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE;
7425 1260 : if (id == NULL_TREE)
7426 933 : id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c),
7427 : NULL_TREE, NULL_TREE);
7428 1260 : id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL);
7429 1260 : if (id)
7430 : {
7431 1215 : if (id == error_mark_node)
7432 : return true;
7433 1209 : mark_used (id);
7434 1209 : tree body = DECL_SAVED_TREE (id);
7435 1209 : if (!body)
7436 : return true;
7437 1206 : if (TREE_CODE (body) == STATEMENT_LIST)
7438 : {
7439 1206 : tree_stmt_iterator tsi;
7440 1206 : tree placeholder = NULL_TREE, decl_placeholder = NULL_TREE;
7441 1206 : int i;
7442 1206 : tree stmts[7];
7443 1206 : tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id)));
7444 1206 : atype = TREE_TYPE (atype);
7445 1206 : bool need_static_cast = !same_type_p (type, atype);
7446 1206 : memset (stmts, 0, sizeof stmts);
7447 1206 : for (i = 0, tsi = tsi_start (body);
7448 8594 : i < 7 && !tsi_end_p (tsi);
7449 7388 : i++, tsi_next (&tsi))
7450 7388 : stmts[i] = tsi_stmt (tsi);
7451 1206 : gcc_assert (tsi_end_p (tsi));
7452 :
7453 1206 : if (i >= 3)
7454 : {
7455 1206 : gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR
7456 : && TREE_CODE (stmts[1]) == DECL_EXPR);
7457 1206 : placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type);
7458 1206 : DECL_ARTIFICIAL (placeholder) = 1;
7459 1206 : DECL_IGNORED_P (placeholder) = 1;
7460 1206 : OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder;
7461 1206 : if (TREE_CODE (t) == MEM_REF)
7462 : {
7463 600 : decl_placeholder = build_lang_decl (VAR_DECL, NULL_TREE,
7464 : type);
7465 600 : DECL_ARTIFICIAL (decl_placeholder) = 1;
7466 600 : DECL_IGNORED_P (decl_placeholder) = 1;
7467 600 : OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = decl_placeholder;
7468 : }
7469 1206 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0])))
7470 294 : cxx_mark_addressable (placeholder);
7471 1206 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1]))
7472 1206 : && (decl_placeholder
7473 158 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7474 390 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7475 127 : : OMP_CLAUSE_DECL (c));
7476 1206 : tree omp_out = placeholder;
7477 1206 : tree omp_in = decl_placeholder ? decl_placeholder
7478 606 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7479 1206 : if (need_static_cast)
7480 : {
7481 7 : tree rtype = build_reference_type (atype);
7482 7 : omp_out = build_static_cast (input_location,
7483 : rtype, omp_out,
7484 : tf_warning_or_error);
7485 7 : omp_in = build_static_cast (input_location,
7486 : rtype, omp_in,
7487 : tf_warning_or_error);
7488 7 : if (omp_out == error_mark_node || omp_in == error_mark_node)
7489 3 : return true;
7490 7 : omp_out = convert_from_reference (omp_out);
7491 7 : omp_in = convert_from_reference (omp_in);
7492 : }
7493 1206 : OMP_CLAUSE_REDUCTION_MERGE (c)
7494 1206 : = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]),
7495 1206 : DECL_EXPR_DECL (stmts[1]), omp_in, omp_out);
7496 : }
7497 1206 : if (i >= 6)
7498 : {
7499 1014 : gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR
7500 : && TREE_CODE (stmts[4]) == DECL_EXPR);
7501 1014 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3]))
7502 1014 : && (decl_placeholder
7503 232 : || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
7504 844 : cxx_mark_addressable (decl_placeholder ? decl_placeholder
7505 170 : : OMP_CLAUSE_DECL (c));
7506 1014 : if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4])))
7507 225 : cxx_mark_addressable (placeholder);
7508 1014 : tree omp_priv = decl_placeholder ? decl_placeholder
7509 438 : : convert_from_reference (OMP_CLAUSE_DECL (c));
7510 1014 : tree omp_orig = placeholder;
7511 1014 : if (need_static_cast)
7512 : {
7513 5 : if (i == 7)
7514 : {
7515 3 : error_at (OMP_CLAUSE_LOCATION (c),
7516 : "user defined reduction with constructor "
7517 : "initializer for base class %qT", atype);
7518 3 : return true;
7519 : }
7520 2 : tree rtype = build_reference_type (atype);
7521 2 : omp_priv = build_static_cast (input_location,
7522 : rtype, omp_priv,
7523 : tf_warning_or_error);
7524 2 : omp_orig = build_static_cast (input_location,
7525 : rtype, omp_orig,
7526 : tf_warning_or_error);
7527 2 : if (omp_priv == error_mark_node
7528 2 : || omp_orig == error_mark_node)
7529 : return true;
7530 2 : omp_priv = convert_from_reference (omp_priv);
7531 2 : omp_orig = convert_from_reference (omp_orig);
7532 : }
7533 1011 : if (i == 6)
7534 286 : *need_default_ctor = true;
7535 1011 : OMP_CLAUSE_REDUCTION_INIT (c)
7536 1011 : = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]),
7537 1011 : DECL_EXPR_DECL (stmts[3]),
7538 : omp_priv, omp_orig);
7539 1011 : if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c),
7540 : find_omp_placeholder_r, placeholder, NULL))
7541 247 : OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1;
7542 : }
7543 192 : else if (i >= 3)
7544 : {
7545 192 : if (CLASS_TYPE_P (type) && !pod_type_p (type))
7546 175 : *need_default_ctor = true;
7547 : else
7548 : {
7549 17 : tree init;
7550 17 : tree v = decl_placeholder ? decl_placeholder
7551 17 : : convert_from_reference (t);
7552 17 : if (AGGREGATE_TYPE_P (TREE_TYPE (v)))
7553 8 : init = build_constructor (TREE_TYPE (v), NULL);
7554 : else
7555 9 : init = fold_convert (TREE_TYPE (v), integer_zero_node);
7556 34 : OMP_CLAUSE_REDUCTION_INIT (c)
7557 34 : = cp_build_init_expr (v, init);
7558 : }
7559 : }
7560 : }
7561 : }
7562 1248 : if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
7563 1203 : *need_dtor = true;
7564 : else
7565 : {
7566 90 : error_at (OMP_CLAUSE_LOCATION (c),
7567 : "user defined reduction not found for %qE",
7568 : omp_clause_printable_decl (t));
7569 45 : return true;
7570 : }
7571 1203 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF)
7572 600 : gcc_assert (TYPE_SIZE_UNIT (type)
7573 : && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
7574 : return false;
7575 : }
7576 :
7577 : /* Check an instance of an "omp declare mapper" function. */
7578 :
7579 : bool
7580 208 : cp_check_omp_declare_mapper (tree udm)
7581 : {
7582 208 : tree var = OMP_DECLARE_MAPPER_DECL (udm);
7583 208 : tree type = TREE_TYPE (var);
7584 208 : location_t loc = DECL_SOURCE_LOCATION (var);
7585 :
7586 208 : if (type == error_mark_node)
7587 : return false;
7588 :
7589 208 : if (processing_template_decl)
7590 : return true;
7591 :
7592 197 : if (!RECORD_OR_UNION_TYPE_P (type))
7593 : {
7594 17 : error_at (loc, "%qT is not a struct, union or class type in "
7595 : "%<#pragma omp declare mapper%>", type);
7596 17 : return false;
7597 : }
7598 180 : if (CLASSTYPE_VBASECLASSES (type))
7599 : {
7600 3 : error_at (loc, "%qT must not be a virtual base class in "
7601 : "%<#pragma omp declare mapper%>", type);
7602 3 : return false;
7603 : }
7604 :
7605 177 : tree c = OMP_DECLARE_MAPPER_CLAUSES (udm);
7606 215 : for ( ; c; c = OMP_CLAUSE_CHAIN (c))
7607 : {
7608 187 : tree dvar = OMP_CLAUSE_DECL (c);
7609 400 : while (!DECL_P (dvar) && TREE_OPERAND_LENGTH (dvar))
7610 213 : dvar = TREE_OPERAND (dvar, 0);
7611 187 : if (dvar == var)
7612 : break;
7613 : }
7614 177 : if (!c)
7615 : {
7616 : // After template handling, the var is mangled, demangle it
7617 28 : const char *name = IDENTIFIER_POINTER (DECL_NAME (var));
7618 28 : char *n = NULL;
7619 28 : if (startswith (name, "omp declare mapper "))
7620 : {
7621 3 : name += strlen ("omp declare mapper ");
7622 3 : n = xstrdup (name);
7623 3 : n[strchr (n, '~')-n] = '\0';
7624 3 : name = n;
7625 : }
7626 28 : error_at (loc, "at least one %<map%> clause must map %qs or an "
7627 : "element of it", name);
7628 28 : if (n)
7629 3 : free (n);
7630 : return false;
7631 : }
7632 :
7633 : /* FIXME: The vardecl created for the mapper_id uses DECL_DECLARED_CONSTEXPR_P
7634 : = 1, which is set to false in finalize_literal_type_property for C++ < 11,
7635 : leading to an error in ensure_literal_type_for_constexpr_object.
7636 : Examples (compile with -std=c++98): gcc.dg/gomp/declare-mapper-13.c and
7637 : libgomp.c++/declare-mapper-{5,6,8}.C. */
7638 149 : if (cxx_dialect < cxx11)
7639 : {
7640 0 : sorry_at (loc, "%<#pragma omp declare mapper%> with %<-std=%> set to "
7641 : "before C++11");
7642 0 : return false;
7643 : }
7644 :
7645 : return true;
7646 : }
7647 :
7648 : /* Called from finish_struct_1. linear(this) or linear(this:step)
7649 : clauses might not be finalized yet because the class has been incomplete
7650 : when parsing #pragma omp declare simd methods. Fix those up now. */
7651 :
7652 : void
7653 118636 : finish_omp_declare_simd_methods (tree t)
7654 : {
7655 118636 : if (processing_template_decl)
7656 : return;
7657 :
7658 809799 : for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))
7659 : {
7660 1144035 : if (TREE_CODE (x) == USING_DECL
7661 691163 : || !DECL_IOBJ_MEMBER_FUNCTION_P (x))
7662 452872 : continue;
7663 238291 : tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x));
7664 238399 : if (!ods || !TREE_VALUE (ods))
7665 238183 : continue;
7666 366 : for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c))
7667 258 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
7668 66 : && integer_zerop (OMP_CLAUSE_DECL (c))
7669 18 : && OMP_CLAUSE_LINEAR_STEP (c)
7670 276 : && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c))))
7671 : {
7672 18 : tree s = OMP_CLAUSE_LINEAR_STEP (c);
7673 18 : s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s);
7674 18 : s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR,
7675 18 : sizetype, s, TYPE_SIZE_UNIT (t));
7676 18 : OMP_CLAUSE_LINEAR_STEP (c) = s;
7677 : }
7678 : }
7679 : }
7680 :
7681 : /* Adjust sink depend/doacross clause to take into account pointer offsets.
7682 :
7683 : Return TRUE if there was a problem processing the offset, and the
7684 : whole clause should be removed. */
7685 :
7686 : static bool
7687 298 : cp_finish_omp_clause_doacross_sink (tree sink_clause)
7688 : {
7689 298 : tree t = OMP_CLAUSE_DECL (sink_clause);
7690 298 : gcc_assert (TREE_CODE (t) == TREE_LIST);
7691 :
7692 : /* Make sure we don't adjust things twice for templates. */
7693 298 : if (processing_template_decl)
7694 : return false;
7695 :
7696 671 : for (; t; t = TREE_CHAIN (t))
7697 : {
7698 391 : tree decl = TREE_VALUE (t);
7699 391 : if (TYPE_PTR_P (TREE_TYPE (decl)))
7700 : {
7701 6 : tree offset = TREE_PURPOSE (t);
7702 6 : bool neg = wi::neg_p (wi::to_wide (offset));
7703 6 : offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset);
7704 6 : decl = mark_rvalue_use (decl);
7705 6 : decl = convert_from_reference (decl);
7706 12 : tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause),
7707 : neg ? MINUS_EXPR : PLUS_EXPR,
7708 : decl, offset);
7709 6 : t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
7710 : MINUS_EXPR, sizetype,
7711 : fold_convert (sizetype, t2),
7712 : fold_convert (sizetype, decl));
7713 6 : if (t2 == error_mark_node)
7714 : return true;
7715 6 : TREE_PURPOSE (t) = t2;
7716 : }
7717 : }
7718 : return false;
7719 : }
7720 :
7721 : /* Finish OpenMP iterators ITER. Return true if they are erroneous
7722 : and clauses containing them should be removed. */
7723 :
7724 : static bool
7725 624 : cp_omp_finish_iterators (tree iter)
7726 : {
7727 624 : bool ret = false;
7728 1413 : for (tree it = iter; it; it = TREE_CHAIN (it))
7729 : {
7730 789 : tree var = OMP_ITERATOR_VAR (it);
7731 789 : tree begin = OMP_ITERATOR_BEGIN (it);
7732 789 : tree end = OMP_ITERATOR_END (it);
7733 789 : tree step = OMP_ITERATOR_STEP (it);
7734 789 : tree orig_step;
7735 789 : tree type = TREE_TYPE (var);
7736 789 : location_t loc = DECL_SOURCE_LOCATION (var);
7737 789 : if (type == error_mark_node)
7738 : {
7739 0 : ret = true;
7740 218 : continue;
7741 : }
7742 789 : if (type_dependent_expression_p (var))
7743 59 : continue;
7744 730 : if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
7745 : {
7746 27 : error_at (loc, "iterator %qD has neither integral nor pointer type",
7747 : var);
7748 27 : ret = true;
7749 27 : continue;
7750 : }
7751 703 : else if (TYPE_READONLY (type))
7752 : {
7753 24 : error_at (loc, "iterator %qD has const qualified type", var);
7754 24 : ret = true;
7755 24 : continue;
7756 : }
7757 679 : if (type_dependent_expression_p (begin)
7758 670 : || type_dependent_expression_p (end)
7759 1349 : || type_dependent_expression_p (step))
7760 15 : continue;
7761 664 : else if (error_operand_p (step))
7762 : {
7763 0 : ret = true;
7764 0 : continue;
7765 : }
7766 664 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
7767 : {
7768 21 : error_at (EXPR_LOC_OR_LOC (step, loc),
7769 : "iterator step with non-integral type");
7770 21 : ret = true;
7771 21 : continue;
7772 : }
7773 :
7774 643 : begin = mark_rvalue_use (begin);
7775 643 : end = mark_rvalue_use (end);
7776 643 : step = mark_rvalue_use (step);
7777 643 : begin = cp_build_c_cast (input_location, type, begin,
7778 : tf_warning_or_error);
7779 643 : end = cp_build_c_cast (input_location, type, end,
7780 : tf_warning_or_error);
7781 643 : orig_step = step;
7782 643 : if (!processing_template_decl)
7783 566 : step = orig_step = save_expr (step);
7784 643 : tree stype = POINTER_TYPE_P (type) ? sizetype : type;
7785 643 : step = cp_build_c_cast (input_location, stype, step,
7786 : tf_warning_or_error);
7787 643 : if (POINTER_TYPE_P (type) && !processing_template_decl)
7788 : {
7789 66 : begin = save_expr (begin);
7790 66 : step = pointer_int_sum (loc, PLUS_EXPR, begin, step);
7791 66 : step = fold_build2_loc (loc, MINUS_EXPR, sizetype,
7792 : fold_convert (sizetype, step),
7793 : fold_convert (sizetype, begin));
7794 66 : step = fold_convert (ssizetype, step);
7795 : }
7796 643 : if (!processing_template_decl)
7797 : {
7798 566 : begin = maybe_constant_value (begin);
7799 566 : end = maybe_constant_value (end);
7800 566 : step = maybe_constant_value (step);
7801 566 : orig_step = maybe_constant_value (orig_step);
7802 : }
7803 643 : if (integer_zerop (step))
7804 : {
7805 27 : error_at (loc, "iterator %qD has zero step", var);
7806 27 : ret = true;
7807 27 : continue;
7808 : }
7809 :
7810 616 : if (begin == error_mark_node
7811 607 : || end == error_mark_node
7812 598 : || step == error_mark_node
7813 598 : || orig_step == error_mark_node)
7814 : {
7815 18 : ret = true;
7816 18 : continue;
7817 : }
7818 :
7819 598 : if (!processing_template_decl)
7820 : {
7821 521 : begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin);
7822 521 : end = fold_build_cleanup_point_expr (TREE_TYPE (end), end);
7823 521 : step = fold_build_cleanup_point_expr (TREE_TYPE (step), step);
7824 521 : orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step),
7825 : orig_step);
7826 : }
7827 598 : hash_set<tree> pset;
7828 598 : tree it2;
7829 754 : for (it2 = TREE_CHAIN (it); it2; it2 = TREE_CHAIN (it2))
7830 : {
7831 183 : tree var2 = OMP_ITERATOR_VAR (it2);
7832 183 : tree begin2 = OMP_ITERATOR_BEGIN (it2);
7833 183 : tree end2 = OMP_ITERATOR_END (it2);
7834 183 : tree step2 = OMP_ITERATOR_STEP (it2);
7835 183 : location_t loc2 = DECL_SOURCE_LOCATION (var2);
7836 183 : if (cp_walk_tree (&begin2, find_omp_placeholder_r, var, &pset))
7837 : {
7838 9 : error_at (EXPR_LOC_OR_LOC (begin2, loc2),
7839 : "begin expression refers to outer iterator %qD", var);
7840 36 : break;
7841 : }
7842 174 : else if (cp_walk_tree (&end2, find_omp_placeholder_r, var, &pset))
7843 : {
7844 9 : error_at (EXPR_LOC_OR_LOC (end2, loc2),
7845 : "end expression refers to outer iterator %qD", var);
7846 9 : break;
7847 : }
7848 165 : else if (cp_walk_tree (&step2, find_omp_placeholder_r, var, &pset))
7849 : {
7850 9 : error_at (EXPR_LOC_OR_LOC (step2, loc2),
7851 : "step expression refers to outer iterator %qD", var);
7852 9 : break;
7853 : }
7854 : }
7855 598 : if (it2)
7856 : {
7857 27 : ret = true;
7858 27 : continue;
7859 : }
7860 571 : OMP_ITERATOR_BEGIN (it) = begin;
7861 571 : OMP_ITERATOR_END (it) = end;
7862 571 : if (processing_template_decl)
7863 71 : OMP_ITERATOR_STEP (it) = orig_step;
7864 : else
7865 : {
7866 500 : OMP_ITERATOR_STEP (it) = step;
7867 500 : OMP_ITERATOR_ORIG_STEP (it) = orig_step;
7868 : }
7869 598 : }
7870 624 : return ret;
7871 : }
7872 :
7873 : /* Ensure that pointers are used in OpenACC attach and detach clauses.
7874 : Return true if an error has been detected. */
7875 :
7876 : static bool
7877 18850 : cp_oacc_check_attachments (tree c)
7878 : {
7879 18850 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
7880 : return false;
7881 :
7882 : /* OpenACC attach / detach clauses must be pointers. */
7883 14815 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
7884 14815 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
7885 : {
7886 196 : tree t = OMP_CLAUSE_DECL (c);
7887 196 : tree type;
7888 :
7889 232 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
7890 36 : t = TREE_OPERAND (t, 0);
7891 :
7892 196 : type = TREE_TYPE (t);
7893 :
7894 196 : if (TREE_CODE (type) == REFERENCE_TYPE)
7895 36 : type = TREE_TYPE (type);
7896 :
7897 196 : if (TREE_CODE (type) != POINTER_TYPE)
7898 : {
7899 36 : error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause",
7900 : user_omp_clause_code_name (c, true));
7901 36 : return true;
7902 : }
7903 : }
7904 :
7905 : return false;
7906 : }
7907 :
7908 : /* Update OMP_CLAUSE_INIT_PREFER_TYPE in case template substitution
7909 : happened. */
7910 :
7911 : tree
7912 813 : cp_finish_omp_init_prefer_type (tree pref_type)
7913 : {
7914 813 : if (processing_template_decl
7915 741 : || pref_type == NULL_TREE
7916 356 : || TREE_CODE (pref_type) != TREE_LIST)
7917 : return pref_type;
7918 :
7919 81 : tree t = TREE_PURPOSE (pref_type);
7920 81 : char *str = const_cast<char *> (TREE_STRING_POINTER (t));
7921 81 : tree fr_list = TREE_VALUE (pref_type);
7922 81 : int len = TREE_VEC_LENGTH (fr_list);
7923 81 : int cnt = 0;
7924 :
7925 270 : while (str[0] == (char) GOMP_INTEROP_IFR_SEPARATOR)
7926 : {
7927 270 : str++;
7928 270 : if (str[0] == (char) GOMP_INTEROP_IFR_UNKNOWN)
7929 : {
7930 : /* Assume a no or a single 'fr'. */
7931 150 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7932 150 : location_t loc = UNKNOWN_LOCATION;
7933 150 : tree value = TREE_VEC_ELT (fr_list, cnt);
7934 150 : if (value != NULL_TREE && value != error_mark_node)
7935 : {
7936 126 : loc = EXPR_LOCATION (value);
7937 126 : if (value && TREE_CODE (value) == NOP_EXPR)
7938 39 : value = TREE_OPERAND (value, 0);
7939 126 : value = cp_fully_fold (value);
7940 : }
7941 126 : if (value != NULL_TREE && value != error_mark_node)
7942 : {
7943 126 : if (TREE_CODE (value) != INTEGER_CST
7944 126 : || !tree_fits_shwi_p (value))
7945 0 : error_at (loc,
7946 : "expected string literal or "
7947 : "constant integer expression instead of %qE", value);
7948 : else
7949 : {
7950 126 : HOST_WIDE_INT n = tree_to_shwi (value);
7951 126 : if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
7952 : {
7953 48 : warning_at (loc, OPT_Wopenmp,
7954 : "unknown foreign runtime identifier %qwd", n);
7955 48 : n = GOMP_INTEROP_IFR_UNKNOWN;
7956 : }
7957 126 : str[0] = (char) n;
7958 : }
7959 : }
7960 150 : str++;
7961 : }
7962 120 : else if (str[0] != (char) GOMP_INTEROP_IFR_SEPARATOR)
7963 : {
7964 : /* Assume a no or a single 'fr'. */
7965 120 : gcc_checking_assert (str[1] == (char) GOMP_INTEROP_IFR_SEPARATOR);
7966 120 : str++;
7967 : }
7968 270 : str++;
7969 294 : while (str[0] != '\0')
7970 24 : str += strlen (str) + 1;
7971 270 : str++;
7972 270 : cnt++;
7973 270 : if (cnt >= len)
7974 : break;
7975 : }
7976 : return t;
7977 : }
7978 :
7979 : /* For all elements of CLAUSES, validate them vs OpenMP constraints.
7980 : Remove any elements from the list that are invalid. */
7981 :
7982 : tree
7983 63524 : finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
7984 : {
7985 63524 : bitmap_head generic_head, firstprivate_head, lastprivate_head;
7986 63524 : bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head;
7987 63524 : bitmap_head oacc_reduction_head, is_on_device_head;
7988 63524 : tree c, t, *pc;
7989 63524 : tree safelen = NULL_TREE;
7990 63524 : bool openacc = (ort & C_ORT_ACC) != 0;
7991 63524 : bool branch_seen = false;
7992 63524 : bool copyprivate_seen = false;
7993 63524 : bool ordered_seen = false;
7994 63524 : bool order_seen = false;
7995 63524 : bool schedule_seen = false;
7996 63524 : bool oacc_async = false;
7997 63524 : bool indir_component_ref_p = false;
7998 63524 : tree last_iterators = NULL_TREE;
7999 63524 : bool last_iterators_remove = false;
8000 : /* 1 if normal/task reduction has been seen, -1 if inscan reduction
8001 : has been seen, -2 if mixed inscan/normal reduction diagnosed. */
8002 63524 : int reduction_seen = 0;
8003 63524 : bool allocate_seen = false;
8004 63524 : tree detach_seen = NULL_TREE;
8005 63524 : bool mergeable_seen = false;
8006 63524 : bool implicit_moved = false;
8007 63524 : bool target_in_reduction_seen = false;
8008 63524 : bool num_tasks_seen = false;
8009 63524 : bool partial_seen = false;
8010 63524 : bool init_seen = false;
8011 63524 : bool init_use_destroy_seen = false;
8012 63524 : tree init_no_targetsync_clause = NULL_TREE;
8013 63524 : tree depend_clause = NULL_TREE;
8014 :
8015 63524 : if (!openacc)
8016 50703 : clauses = omp_remove_duplicate_maps (clauses, true);
8017 :
8018 63524 : bitmap_obstack_initialize (NULL);
8019 63524 : bitmap_initialize (&generic_head, &bitmap_default_obstack);
8020 63524 : bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
8021 63524 : bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
8022 63524 : bitmap_initialize (&aligned_head, &bitmap_default_obstack);
8023 : /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
8024 63524 : bitmap_initialize (&map_head, &bitmap_default_obstack);
8025 63524 : bitmap_initialize (&map_field_head, &bitmap_default_obstack);
8026 63524 : bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack);
8027 : /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
8028 : instead and for ort == C_ORT_OMP_TARGET used as in_reduction_head. */
8029 63524 : bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
8030 63524 : bitmap_initialize (&is_on_device_head, &bitmap_default_obstack);
8031 :
8032 63524 : if (openacc)
8033 28440 : for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
8034 16007 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC)
8035 : {
8036 : oacc_async = true;
8037 : break;
8038 : }
8039 :
8040 63524 : tree *grp_start_p = NULL, grp_sentinel = NULL_TREE;
8041 :
8042 162517 : for (pc = &clauses, c = clauses; c ; c = *pc)
8043 : {
8044 98993 : bool remove = false;
8045 98993 : bool field_ok = false;
8046 :
8047 : /* We've reached the end of a list of expanded nodes. Reset the group
8048 : start pointer. */
8049 98993 : if (c == grp_sentinel)
8050 : {
8051 5713 : if (grp_start_p
8052 5713 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
8053 96 : for (tree gc = *grp_start_p; gc != grp_sentinel;
8054 66 : gc = OMP_CLAUSE_CHAIN (gc))
8055 66 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
8056 : grp_start_p = NULL;
8057 : }
8058 :
8059 98993 : switch (OMP_CLAUSE_CODE (c))
8060 : {
8061 2100 : case OMP_CLAUSE_SHARED:
8062 2100 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8063 2100 : goto check_dup_generic;
8064 2584 : case OMP_CLAUSE_PRIVATE:
8065 2584 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8066 2584 : goto check_dup_generic;
8067 7548 : case OMP_CLAUSE_REDUCTION:
8068 7548 : if (reduction_seen == 0)
8069 6429 : reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1;
8070 1119 : else if (reduction_seen != -2
8071 2238 : && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c)
8072 1119 : ? -1 : 1))
8073 : {
8074 6 : error_at (OMP_CLAUSE_LOCATION (c),
8075 : "%<inscan%> and non-%<inscan%> %<reduction%> clauses "
8076 : "on the same construct");
8077 6 : reduction_seen = -2;
8078 : }
8079 : /* FALLTHRU */
8080 9693 : case OMP_CLAUSE_IN_REDUCTION:
8081 9693 : case OMP_CLAUSE_TASK_REDUCTION:
8082 9693 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8083 9693 : t = OMP_CLAUSE_DECL (c);
8084 9693 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
8085 : {
8086 2315 : if (handle_omp_array_sections (c, ort))
8087 : {
8088 : remove = true;
8089 : break;
8090 : }
8091 2273 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
8092 2273 : && OMP_CLAUSE_REDUCTION_INSCAN (c))
8093 : {
8094 3 : error_at (OMP_CLAUSE_LOCATION (c),
8095 : "%<inscan%> %<reduction%> clause with array "
8096 : "section");
8097 3 : remove = true;
8098 3 : break;
8099 : }
8100 2270 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
8101 : {
8102 4888 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
8103 2618 : t = TREE_OPERAND (t, 0);
8104 : }
8105 : else
8106 : {
8107 0 : gcc_assert (TREE_CODE (t) == MEM_REF);
8108 0 : t = TREE_OPERAND (t, 0);
8109 0 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
8110 0 : t = TREE_OPERAND (t, 0);
8111 0 : if (TREE_CODE (t) == ADDR_EXPR
8112 0 : || INDIRECT_REF_P (t))
8113 0 : t = TREE_OPERAND (t, 0);
8114 : }
8115 2270 : tree n = omp_clause_decl_field (t);
8116 2270 : if (n)
8117 59 : t = n;
8118 2270 : goto check_dup_generic_t;
8119 : }
8120 7378 : if (oacc_async)
8121 7 : cxx_mark_addressable (t);
8122 7378 : goto check_dup_generic;
8123 98 : case OMP_CLAUSE_COPYPRIVATE:
8124 98 : copyprivate_seen = true;
8125 98 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8126 98 : goto check_dup_generic;
8127 280 : case OMP_CLAUSE_COPYIN:
8128 280 : goto check_dup_generic;
8129 1631 : case OMP_CLAUSE_LINEAR:
8130 1631 : field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
8131 1631 : t = OMP_CLAUSE_DECL (c);
8132 1631 : if (ort != C_ORT_OMP_DECLARE_SIMD
8133 1631 : && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
8134 : {
8135 84 : if (OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c))
8136 : {
8137 42 : error_at (OMP_CLAUSE_LOCATION (c),
8138 : "modifier should not be specified in %<linear%> "
8139 : "clause on %<simd%> or %<for%> constructs when "
8140 : "not using OpenMP 5.2 modifiers");
8141 42 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
8142 : }
8143 42 : else if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_VAL)
8144 : {
8145 18 : error_at (OMP_CLAUSE_LOCATION (c),
8146 : "modifier other than %<val%> specified in "
8147 : "%<linear%> clause on %<simd%> or %<for%> "
8148 : "constructs when using OpenMP 5.2 modifiers");
8149 18 : OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
8150 : }
8151 : }
8152 1011 : if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL)
8153 2571 : && !type_dependent_expression_p (t))
8154 : {
8155 1529 : tree type = TREE_TYPE (t);
8156 1529 : if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
8157 1448 : || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL)
8158 1598 : && !TYPE_REF_P (type))
8159 : {
8160 12 : error_at (OMP_CLAUSE_LOCATION (c),
8161 : "linear clause with %qs modifier applied to "
8162 : "non-reference variable with %qT type",
8163 12 : OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF
8164 12 : ? "ref" : "uval", TREE_TYPE (t));
8165 12 : remove = true;
8166 12 : break;
8167 : }
8168 1517 : if (TYPE_REF_P (type))
8169 281 : type = TREE_TYPE (type);
8170 1517 : if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF)
8171 : {
8172 1442 : if (!INTEGRAL_TYPE_P (type)
8173 85 : && !TYPE_PTR_P (type))
8174 : {
8175 18 : error_at (OMP_CLAUSE_LOCATION (c),
8176 : "linear clause applied to non-integral "
8177 : "non-pointer variable with %qT type",
8178 18 : TREE_TYPE (t));
8179 18 : remove = true;
8180 18 : break;
8181 : }
8182 : }
8183 : }
8184 1601 : t = OMP_CLAUSE_LINEAR_STEP (c);
8185 1601 : if (t == NULL_TREE)
8186 6 : t = integer_one_node;
8187 1601 : if (t == error_mark_node)
8188 : {
8189 : remove = true;
8190 : break;
8191 : }
8192 1601 : else if (!type_dependent_expression_p (t)
8193 1599 : && !INTEGRAL_TYPE_P (TREE_TYPE (t))
8194 1613 : && (ort != C_ORT_OMP_DECLARE_SIMD
8195 9 : || TREE_CODE (t) != PARM_DECL
8196 6 : || !TYPE_REF_P (TREE_TYPE (t))
8197 6 : || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
8198 : {
8199 6 : error_at (OMP_CLAUSE_LOCATION (c),
8200 : "linear step expression must be integral");
8201 6 : remove = true;
8202 6 : break;
8203 : }
8204 : else
8205 : {
8206 1595 : t = mark_rvalue_use (t);
8207 1595 : if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL)
8208 : {
8209 42 : OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
8210 42 : goto check_dup_generic;
8211 : }
8212 1553 : if (!processing_template_decl
8213 1553 : && (VAR_P (OMP_CLAUSE_DECL (c))
8214 835 : || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
8215 : {
8216 1372 : if (ort == C_ORT_OMP_DECLARE_SIMD)
8217 : {
8218 589 : t = maybe_constant_value (t);
8219 589 : if (TREE_CODE (t) != INTEGER_CST)
8220 : {
8221 6 : error_at (OMP_CLAUSE_LOCATION (c),
8222 : "%<linear%> clause step %qE is neither "
8223 : "constant nor a parameter", t);
8224 6 : remove = true;
8225 6 : break;
8226 : }
8227 : }
8228 1366 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8229 1366 : tree type = TREE_TYPE (OMP_CLAUSE_DECL (c));
8230 1366 : if (TYPE_REF_P (type))
8231 257 : type = TREE_TYPE (type);
8232 1366 : if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF)
8233 : {
8234 66 : type = build_pointer_type (type);
8235 66 : tree d = fold_convert (type, OMP_CLAUSE_DECL (c));
8236 66 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8237 : d, t);
8238 66 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8239 : MINUS_EXPR, sizetype,
8240 : fold_convert (sizetype, t),
8241 : fold_convert (sizetype, d));
8242 66 : if (t == error_mark_node)
8243 : {
8244 : remove = true;
8245 : break;
8246 : }
8247 : }
8248 1300 : else if (TYPE_PTR_P (type)
8249 : /* Can't multiply the step yet if *this
8250 : is still incomplete type. */
8251 1300 : && (ort != C_ORT_OMP_DECLARE_SIMD
8252 45 : || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
8253 45 : || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
8254 30 : || DECL_NAME (OMP_CLAUSE_DECL (c))
8255 30 : != this_identifier
8256 30 : || !TYPE_BEING_DEFINED (TREE_TYPE (type))))
8257 : {
8258 37 : tree d = convert_from_reference (OMP_CLAUSE_DECL (c));
8259 37 : t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
8260 : d, t);
8261 37 : t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
8262 : MINUS_EXPR, sizetype,
8263 : fold_convert (sizetype, t),
8264 : fold_convert (sizetype, d));
8265 37 : if (t == error_mark_node)
8266 : {
8267 : remove = true;
8268 : break;
8269 : }
8270 : }
8271 : else
8272 1263 : t = fold_convert (type, t);
8273 : }
8274 1547 : OMP_CLAUSE_LINEAR_STEP (c) = t;
8275 : }
8276 1547 : goto check_dup_generic;
8277 14995 : check_dup_generic:
8278 14995 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8279 14995 : if (t)
8280 : {
8281 101 : if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED)
8282 101 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8283 : }
8284 : else
8285 14894 : t = OMP_CLAUSE_DECL (c);
8286 17532 : check_dup_generic_t:
8287 17532 : if (t == current_class_ptr
8288 17532 : && ((ort != C_ORT_OMP_DECLARE_SIMD && !openacc)
8289 102 : || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
8290 72 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
8291 : {
8292 24 : error_at (OMP_CLAUSE_LOCATION (c),
8293 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8294 : " clauses");
8295 24 : remove = true;
8296 24 : break;
8297 : }
8298 17508 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8299 586 : && (!field_ok || TREE_CODE (t) != FIELD_DECL))
8300 : {
8301 59 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8302 : break;
8303 39 : if (DECL_P (t))
8304 30 : error_at (OMP_CLAUSE_LOCATION (c),
8305 : "%qD is not a variable in clause %qs", t,
8306 15 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8307 : else
8308 48 : error_at (OMP_CLAUSE_LOCATION (c),
8309 : "%qE is not a variable in clause %qs", t,
8310 24 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8311 : remove = true;
8312 : }
8313 17449 : else if ((openacc
8314 2707 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
8315 14980 : || (ort == C_ORT_OMP
8316 12647 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
8317 12616 : || (OMP_CLAUSE_CODE (c)
8318 : == OMP_CLAUSE_USE_DEVICE_ADDR)))
8319 32322 : || (ort == C_ORT_OMP_TARGET
8320 938 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION))
8321 : {
8322 2854 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
8323 2854 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
8324 275 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))))
8325 : {
8326 6 : error_at (OMP_CLAUSE_LOCATION (c),
8327 : "%qD appears more than once in data-sharing "
8328 : "clauses", t);
8329 6 : remove = true;
8330 6 : break;
8331 : }
8332 2848 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
8333 272 : target_in_reduction_seen = true;
8334 2848 : if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
8335 : {
8336 12 : error_at (OMP_CLAUSE_LOCATION (c),
8337 : openacc
8338 : ? "%qD appears more than once in reduction clauses"
8339 : : "%qD appears more than once in data clauses",
8340 : t);
8341 6 : remove = true;
8342 : }
8343 : else
8344 2842 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
8345 : }
8346 14595 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8347 14522 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8348 14519 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t))
8349 29114 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8350 : {
8351 76 : error_at (OMP_CLAUSE_LOCATION (c),
8352 : "%qD appears more than once in data clauses", t);
8353 76 : remove = true;
8354 : }
8355 14519 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
8356 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_HAS_DEVICE_ADDR
8357 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
8358 3125 : && bitmap_bit_p (&map_head, DECL_UID (t)))
8359 : {
8360 9 : if (openacc)
8361 0 : error_at (OMP_CLAUSE_LOCATION (c),
8362 : "%qD appears more than once in data clauses", t);
8363 : else
8364 9 : error_at (OMP_CLAUSE_LOCATION (c),
8365 : "%qD appears both in data and map clauses", t);
8366 : remove = true;
8367 : }
8368 : else
8369 14510 : bitmap_set_bit (&generic_head, DECL_UID (t));
8370 17482 : if (!field_ok)
8371 : break;
8372 13071 : handle_field_decl:
8373 21825 : if (!remove
8374 21630 : && TREE_CODE (t) == FIELD_DECL
8375 16940 : && t == OMP_CLAUSE_DECL (c))
8376 : {
8377 795 : OMP_CLAUSE_DECL (c)
8378 795 : = omp_privatize_field (t, (OMP_CLAUSE_CODE (c)
8379 : == OMP_CLAUSE_SHARED));
8380 795 : if (OMP_CLAUSE_DECL (c) == error_mark_node)
8381 98524 : remove = true;
8382 : }
8383 : break;
8384 :
8385 3486 : case OMP_CLAUSE_FIRSTPRIVATE:
8386 3486 : if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved)
8387 : {
8388 414 : move_implicit:
8389 414 : implicit_moved = true;
8390 : /* Move firstprivate and map clauses with
8391 : OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of
8392 : clauses chain. */
8393 414 : tree cl1 = NULL_TREE, cl2 = NULL_TREE;
8394 414 : tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2;
8395 2704 : while (*pc1)
8396 2290 : if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE
8397 2290 : && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1))
8398 : {
8399 275 : *pc3 = *pc1;
8400 275 : pc3 = &OMP_CLAUSE_CHAIN (*pc3);
8401 275 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8402 : }
8403 2015 : else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP
8404 2015 : && OMP_CLAUSE_MAP_IMPLICIT (*pc1))
8405 : {
8406 370 : *pc2 = *pc1;
8407 370 : pc2 = &OMP_CLAUSE_CHAIN (*pc2);
8408 370 : *pc1 = OMP_CLAUSE_CHAIN (*pc1);
8409 : }
8410 : else
8411 1645 : pc1 = &OMP_CLAUSE_CHAIN (*pc1);
8412 414 : *pc3 = NULL;
8413 414 : *pc2 = cl2;
8414 414 : *pc1 = cl1;
8415 414 : continue;
8416 414 : }
8417 3229 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8418 3229 : if (t)
8419 69 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8420 : else
8421 3160 : t = OMP_CLAUSE_DECL (c);
8422 3229 : if (!openacc && t == current_class_ptr)
8423 : {
8424 6 : error_at (OMP_CLAUSE_LOCATION (c),
8425 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8426 : " clauses");
8427 6 : remove = true;
8428 6 : break;
8429 : }
8430 3223 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8431 333 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8432 333 : || TREE_CODE (t) != FIELD_DECL))
8433 : {
8434 41 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8435 : break;
8436 18 : if (DECL_P (t))
8437 12 : error_at (OMP_CLAUSE_LOCATION (c),
8438 : "%qD is not a variable in clause %<firstprivate%>",
8439 : t);
8440 : else
8441 6 : error_at (OMP_CLAUSE_LOCATION (c),
8442 : "%qE is not a variable in clause %<firstprivate%>",
8443 : t);
8444 : remove = true;
8445 : }
8446 3182 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8447 275 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c)
8448 3436 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8449 : remove = true;
8450 3182 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8451 3173 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
8452 6352 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t)))
8453 : {
8454 15 : error_at (OMP_CLAUSE_LOCATION (c),
8455 : "%qD appears more than once in data clauses", t);
8456 15 : remove = true;
8457 : }
8458 3167 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
8459 3167 : || bitmap_bit_p (&map_field_head, DECL_UID (t)))
8460 : {
8461 21 : if (openacc)
8462 0 : error_at (OMP_CLAUSE_LOCATION (c),
8463 : "%qD appears more than once in data clauses", t);
8464 21 : else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c)
8465 21 : && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c))
8466 : /* Silently drop the clause. */;
8467 : else
8468 18 : error_at (OMP_CLAUSE_LOCATION (c),
8469 : "%qD appears both in data and map clauses", t);
8470 : remove = true;
8471 : }
8472 : else
8473 3146 : bitmap_set_bit (&firstprivate_head, DECL_UID (t));
8474 3200 : goto handle_field_decl;
8475 :
8476 2793 : case OMP_CLAUSE_LASTPRIVATE:
8477 2793 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
8478 2793 : if (t)
8479 35 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
8480 : else
8481 2758 : t = OMP_CLAUSE_DECL (c);
8482 2793 : if (!openacc && t == current_class_ptr)
8483 : {
8484 6 : error_at (OMP_CLAUSE_LOCATION (c),
8485 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8486 : " clauses");
8487 6 : remove = true;
8488 6 : break;
8489 : }
8490 2787 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
8491 259 : && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
8492 259 : || TREE_CODE (t) != FIELD_DECL))
8493 : {
8494 35 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8495 : break;
8496 9 : if (DECL_P (t))
8497 3 : error_at (OMP_CLAUSE_LOCATION (c),
8498 : "%qD is not a variable in clause %<lastprivate%>",
8499 : t);
8500 : else
8501 6 : error_at (OMP_CLAUSE_LOCATION (c),
8502 : "%qE is not a variable in clause %<lastprivate%>",
8503 : t);
8504 : remove = true;
8505 : }
8506 2752 : else if (bitmap_bit_p (&generic_head, DECL_UID (t))
8507 2752 : || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
8508 : {
8509 12 : error_at (OMP_CLAUSE_LOCATION (c),
8510 : "%qD appears more than once in data clauses", t);
8511 12 : remove = true;
8512 : }
8513 : else
8514 2740 : bitmap_set_bit (&lastprivate_head, DECL_UID (t));
8515 2761 : goto handle_field_decl;
8516 :
8517 2221 : case OMP_CLAUSE_IF:
8518 2221 : case OMP_CLAUSE_SELF:
8519 2221 : t = OMP_CLAUSE_OPERAND (c, 0);
8520 2221 : t = maybe_convert_cond (t);
8521 2221 : if (t == error_mark_node)
8522 : remove = true;
8523 2203 : else if (!processing_template_decl)
8524 2142 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8525 2221 : OMP_CLAUSE_OPERAND (c, 0) = t;
8526 2221 : break;
8527 :
8528 289 : case OMP_CLAUSE_FINAL:
8529 289 : t = OMP_CLAUSE_FINAL_EXPR (c);
8530 289 : t = maybe_convert_cond (t);
8531 289 : if (t == error_mark_node)
8532 : remove = true;
8533 289 : else if (!processing_template_decl)
8534 283 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8535 289 : OMP_CLAUSE_FINAL_EXPR (c) = t;
8536 289 : break;
8537 :
8538 92 : case OMP_CLAUSE_NOCONTEXT:
8539 92 : t = OMP_CLAUSE_NOCONTEXT_EXPR (c);
8540 92 : t = maybe_convert_cond (t);
8541 92 : if (t == error_mark_node)
8542 : remove = true;
8543 89 : else if (!processing_template_decl)
8544 83 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8545 92 : OMP_CLAUSE_NOCONTEXT_EXPR (c) = t;
8546 92 : break;
8547 :
8548 80 : case OMP_CLAUSE_NOVARIANTS:
8549 80 : t = OMP_CLAUSE_NOVARIANTS_EXPR (c);
8550 80 : t = maybe_convert_cond (t);
8551 80 : if (t == error_mark_node)
8552 : remove = true;
8553 77 : else if (!processing_template_decl)
8554 71 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8555 80 : OMP_CLAUSE_NOVARIANTS_EXPR (c) = t;
8556 80 : break;
8557 :
8558 1249 : case OMP_CLAUSE_GANG:
8559 : /* Operand 1 is the gang static: argument. */
8560 1249 : t = OMP_CLAUSE_OPERAND (c, 1);
8561 1249 : if (t != NULL_TREE)
8562 : {
8563 129 : if (t == error_mark_node)
8564 : remove = true;
8565 129 : else if (!type_dependent_expression_p (t)
8566 129 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8567 : {
8568 6 : error_at (OMP_CLAUSE_LOCATION (c),
8569 : "%<gang%> static expression must be integral");
8570 6 : remove = true;
8571 : }
8572 : else
8573 : {
8574 123 : t = mark_rvalue_use (t);
8575 123 : if (!processing_template_decl)
8576 : {
8577 123 : t = maybe_constant_value (t);
8578 123 : if (TREE_CODE (t) == INTEGER_CST
8579 109 : && tree_int_cst_sgn (t) != 1
8580 176 : && t != integer_minus_one_node)
8581 : {
8582 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8583 : "%<gang%> static value must be "
8584 : "positive");
8585 0 : t = integer_one_node;
8586 : }
8587 123 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8588 : }
8589 : }
8590 129 : OMP_CLAUSE_OPERAND (c, 1) = t;
8591 : }
8592 : /* Check operand 0, the num argument. */
8593 : /* FALLTHRU */
8594 :
8595 3480 : case OMP_CLAUSE_WORKER:
8596 3480 : case OMP_CLAUSE_VECTOR:
8597 3480 : if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE)
8598 : break;
8599 : /* FALLTHRU */
8600 :
8601 484 : case OMP_CLAUSE_NUM_TASKS:
8602 484 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TASKS)
8603 136 : num_tasks_seen = true;
8604 : /* FALLTHRU */
8605 :
8606 3034 : case OMP_CLAUSE_NUM_TEAMS:
8607 3034 : case OMP_CLAUSE_NUM_THREADS:
8608 3034 : case OMP_CLAUSE_NUM_GANGS:
8609 3034 : case OMP_CLAUSE_NUM_WORKERS:
8610 3034 : case OMP_CLAUSE_DYN_GROUPPRIVATE:
8611 3034 : case OMP_CLAUSE_VECTOR_LENGTH:
8612 3034 : t = OMP_CLAUSE_OPERAND (c, 0);
8613 3034 : if (t == error_mark_node)
8614 : remove = true;
8615 3034 : else if (!type_dependent_expression_p (t)
8616 3034 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8617 : {
8618 99 : switch (OMP_CLAUSE_CODE (c))
8619 : {
8620 12 : case OMP_CLAUSE_GANG:
8621 12 : error_at (OMP_CLAUSE_LOCATION (c),
8622 12 : "%<gang%> num expression must be integral"); break;
8623 12 : case OMP_CLAUSE_VECTOR:
8624 12 : error_at (OMP_CLAUSE_LOCATION (c),
8625 : "%<vector%> length expression must be integral");
8626 12 : break;
8627 12 : case OMP_CLAUSE_WORKER:
8628 12 : error_at (OMP_CLAUSE_LOCATION (c),
8629 : "%<worker%> num expression must be integral");
8630 12 : break;
8631 63 : default:
8632 63 : error_at (OMP_CLAUSE_LOCATION (c),
8633 : "%qs expression must be integral",
8634 63 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8635 : }
8636 : remove = true;
8637 : }
8638 : else
8639 : {
8640 2935 : t = mark_rvalue_use (t);
8641 2935 : if (!processing_template_decl)
8642 : {
8643 2687 : t = maybe_constant_value (t);
8644 2687 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DYN_GROUPPRIVATE
8645 2652 : && TREE_CODE (t) == INTEGER_CST
8646 4142 : && tree_int_cst_sgn (t) != 1)
8647 : {
8648 85 : switch (OMP_CLAUSE_CODE (c))
8649 : {
8650 3 : case OMP_CLAUSE_GANG:
8651 3 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8652 : "%<gang%> num value must be positive");
8653 3 : break;
8654 0 : case OMP_CLAUSE_VECTOR:
8655 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8656 : "%<vector%> length value must be "
8657 : "positive");
8658 0 : break;
8659 0 : case OMP_CLAUSE_WORKER:
8660 0 : warning_at (OMP_CLAUSE_LOCATION (c), 0,
8661 : "%<worker%> num value must be "
8662 : "positive");
8663 0 : break;
8664 82 : default:
8665 82 : warning_at (OMP_CLAUSE_LOCATION (c),
8666 46 : (flag_openmp || flag_openmp_simd)
8667 82 : ? OPT_Wopenmp : 0,
8668 : "%qs value must be positive",
8669 : omp_clause_code_name
8670 82 : [OMP_CLAUSE_CODE (c)]);
8671 : }
8672 85 : t = integer_one_node;
8673 : }
8674 2602 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DYN_GROUPPRIVATE
8675 35 : && TREE_CODE (t) == INTEGER_CST
8676 2625 : && tree_int_cst_sgn (t) < 0)
8677 : {
8678 8 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8679 : "%<dyn_groupprivate%> value must be "
8680 : "non-negative");
8681 8 : t = integer_zero_node;
8682 : }
8683 2687 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8684 : }
8685 2935 : OMP_CLAUSE_OPERAND (c, 0) = t;
8686 : }
8687 3034 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
8688 752 : && OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c)
8689 3313 : && !remove)
8690 : {
8691 279 : t = OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c);
8692 279 : if (t == error_mark_node)
8693 : remove = true;
8694 279 : else if (!type_dependent_expression_p (t)
8695 279 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8696 : {
8697 0 : error_at (OMP_CLAUSE_LOCATION (c),
8698 : "%qs expression must be integral",
8699 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8700 0 : remove = true;
8701 : }
8702 : else
8703 : {
8704 279 : t = mark_rvalue_use (t);
8705 279 : if (!processing_template_decl)
8706 : {
8707 213 : t = maybe_constant_value (t);
8708 213 : if (TREE_CODE (t) == INTEGER_CST
8709 213 : && tree_int_cst_sgn (t) != 1)
8710 : {
8711 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8712 : "%qs value must be positive",
8713 : omp_clause_code_name
8714 18 : [OMP_CLAUSE_CODE (c)]);
8715 18 : t = NULL_TREE;
8716 : }
8717 : else
8718 195 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8719 213 : tree upper = OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c);
8720 213 : if (t
8721 195 : && TREE_CODE (t) == INTEGER_CST
8722 43 : && TREE_CODE (upper) == INTEGER_CST
8723 250 : && tree_int_cst_lt (upper, t))
8724 : {
8725 18 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8726 : "%<num_teams%> lower bound %qE bigger "
8727 : "than upper bound %qE", t, upper);
8728 18 : t = NULL_TREE;
8729 : }
8730 : }
8731 279 : OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = t;
8732 : }
8733 : }
8734 : break;
8735 :
8736 3892 : case OMP_CLAUSE_SCHEDULE:
8737 3892 : t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c);
8738 3892 : if (t == NULL)
8739 : ;
8740 2093 : else if (t == error_mark_node)
8741 : remove = true;
8742 2093 : else if (!type_dependent_expression_p (t)
8743 2093 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8744 : {
8745 9 : error_at (OMP_CLAUSE_LOCATION (c),
8746 : "schedule chunk size expression must be integral");
8747 9 : remove = true;
8748 : }
8749 : else
8750 : {
8751 2084 : t = mark_rvalue_use (t);
8752 2084 : if (!processing_template_decl)
8753 : {
8754 2044 : t = maybe_constant_value (t);
8755 2044 : if (TREE_CODE (t) == INTEGER_CST
8756 2044 : && tree_int_cst_sgn (t) != 1)
8757 : {
8758 6 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8759 : "chunk size value must be positive");
8760 6 : t = integer_one_node;
8761 : }
8762 2044 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8763 : }
8764 2084 : OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
8765 : }
8766 2093 : if (!remove)
8767 : schedule_seen = true;
8768 : break;
8769 :
8770 1268 : case OMP_CLAUSE_SIMDLEN:
8771 1268 : case OMP_CLAUSE_SAFELEN:
8772 1268 : t = OMP_CLAUSE_OPERAND (c, 0);
8773 1268 : if (t == error_mark_node)
8774 : remove = true;
8775 1268 : else if (!type_dependent_expression_p (t)
8776 1268 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8777 : {
8778 0 : error_at (OMP_CLAUSE_LOCATION (c),
8779 : "%qs length expression must be integral",
8780 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8781 0 : remove = true;
8782 : }
8783 : else
8784 : {
8785 1268 : t = mark_rvalue_use (t);
8786 1268 : if (!processing_template_decl)
8787 : {
8788 1219 : t = maybe_constant_value (t);
8789 1219 : if (TREE_CODE (t) != INTEGER_CST
8790 1219 : || tree_int_cst_sgn (t) != 1)
8791 : {
8792 0 : error_at (OMP_CLAUSE_LOCATION (c),
8793 : "%qs length expression must be positive "
8794 : "constant integer expression",
8795 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
8796 0 : remove = true;
8797 : }
8798 : }
8799 1268 : OMP_CLAUSE_OPERAND (c, 0) = t;
8800 1268 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN)
8801 470 : safelen = c;
8802 : }
8803 : break;
8804 :
8805 388 : case OMP_CLAUSE_ASYNC:
8806 388 : t = OMP_CLAUSE_ASYNC_EXPR (c);
8807 388 : if (t == error_mark_node)
8808 : remove = true;
8809 373 : else if (!type_dependent_expression_p (t)
8810 373 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8811 : {
8812 12 : error_at (OMP_CLAUSE_LOCATION (c),
8813 : "%<async%> expression must be integral");
8814 12 : remove = true;
8815 : }
8816 : else
8817 : {
8818 361 : t = mark_rvalue_use (t);
8819 361 : if (!processing_template_decl)
8820 352 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8821 361 : OMP_CLAUSE_ASYNC_EXPR (c) = t;
8822 : }
8823 : break;
8824 :
8825 204 : case OMP_CLAUSE_WAIT:
8826 204 : t = OMP_CLAUSE_WAIT_EXPR (c);
8827 204 : if (t == error_mark_node)
8828 : remove = true;
8829 204 : else if (!processing_template_decl)
8830 196 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8831 204 : OMP_CLAUSE_WAIT_EXPR (c) = t;
8832 204 : break;
8833 :
8834 637 : case OMP_CLAUSE_THREAD_LIMIT:
8835 637 : t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c);
8836 637 : if (t == error_mark_node)
8837 : remove = true;
8838 637 : else if (!type_dependent_expression_p (t)
8839 637 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8840 : {
8841 0 : error_at (OMP_CLAUSE_LOCATION (c),
8842 : "%<thread_limit%> expression must be integral");
8843 0 : remove = true;
8844 : }
8845 : else
8846 : {
8847 637 : t = mark_rvalue_use (t);
8848 637 : if (!processing_template_decl)
8849 : {
8850 583 : t = maybe_constant_value (t);
8851 583 : if (TREE_CODE (t) == INTEGER_CST
8852 583 : && tree_int_cst_sgn (t) != 1)
8853 : {
8854 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
8855 : "%<thread_limit%> value must be positive");
8856 0 : t = integer_one_node;
8857 : }
8858 583 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8859 : }
8860 637 : OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
8861 : }
8862 : break;
8863 :
8864 771 : case OMP_CLAUSE_DEVICE:
8865 771 : t = OMP_CLAUSE_DEVICE_ID (c);
8866 771 : if (t == error_mark_node)
8867 : remove = true;
8868 771 : else if (!type_dependent_expression_p (t)
8869 771 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8870 : {
8871 6 : error_at (OMP_CLAUSE_LOCATION (c),
8872 : "%<device%> id must be integral");
8873 6 : remove = true;
8874 : }
8875 765 : else if (OMP_CLAUSE_DEVICE_ANCESTOR (c)
8876 66 : && TREE_CODE (t) == INTEGER_CST
8877 825 : && !integer_onep (t))
8878 : {
8879 3 : error_at (OMP_CLAUSE_LOCATION (c),
8880 : "the %<device%> clause expression must evaluate to "
8881 : "%<1%>");
8882 3 : remove = true;
8883 : }
8884 : else
8885 : {
8886 762 : t = mark_rvalue_use (t);
8887 762 : if (!processing_template_decl)
8888 751 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8889 762 : OMP_CLAUSE_DEVICE_ID (c) = t;
8890 : }
8891 : break;
8892 :
8893 1848 : case OMP_CLAUSE_DIST_SCHEDULE:
8894 1848 : t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c);
8895 1848 : if (t == NULL)
8896 : ;
8897 1827 : else if (t == error_mark_node)
8898 : remove = true;
8899 1827 : else if (!type_dependent_expression_p (t)
8900 1827 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8901 : {
8902 0 : error_at (OMP_CLAUSE_LOCATION (c),
8903 : "%<dist_schedule%> chunk size expression must be "
8904 : "integral");
8905 0 : remove = true;
8906 : }
8907 : else
8908 : {
8909 1827 : t = mark_rvalue_use (t);
8910 1827 : if (!processing_template_decl)
8911 1827 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
8912 1827 : OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
8913 : }
8914 : break;
8915 :
8916 807 : case OMP_CLAUSE_ALIGNED:
8917 807 : t = OMP_CLAUSE_DECL (c);
8918 807 : if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD)
8919 : {
8920 0 : error_at (OMP_CLAUSE_LOCATION (c),
8921 : "%<this%> allowed in OpenMP only in %<declare simd%>"
8922 : " clauses");
8923 0 : remove = true;
8924 0 : break;
8925 : }
8926 807 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8927 : {
8928 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8929 : break;
8930 0 : if (DECL_P (t))
8931 0 : error_at (OMP_CLAUSE_LOCATION (c),
8932 : "%qD is not a variable in %<aligned%> clause", t);
8933 : else
8934 0 : error_at (OMP_CLAUSE_LOCATION (c),
8935 : "%qE is not a variable in %<aligned%> clause", t);
8936 : remove = true;
8937 : }
8938 807 : else if (!type_dependent_expression_p (t)
8939 789 : && !TYPE_PTR_P (TREE_TYPE (t))
8940 111 : && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
8941 864 : && (!TYPE_REF_P (TREE_TYPE (t))
8942 39 : || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))
8943 30 : && (TREE_CODE (TREE_TYPE (TREE_TYPE (t)))
8944 : != ARRAY_TYPE))))
8945 : {
8946 33 : error_at (OMP_CLAUSE_LOCATION (c),
8947 : "%qE in %<aligned%> clause is neither a pointer nor "
8948 : "an array nor a reference to pointer or array", t);
8949 33 : remove = true;
8950 : }
8951 774 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
8952 : {
8953 0 : error_at (OMP_CLAUSE_LOCATION (c),
8954 : "%qD appears more than once in %<aligned%> clauses",
8955 : t);
8956 0 : remove = true;
8957 : }
8958 : else
8959 774 : bitmap_set_bit (&aligned_head, DECL_UID (t));
8960 807 : t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c);
8961 807 : if (t == error_mark_node)
8962 : remove = true;
8963 807 : else if (t == NULL_TREE)
8964 : break;
8965 744 : else if (!type_dependent_expression_p (t)
8966 744 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
8967 : {
8968 0 : error_at (OMP_CLAUSE_LOCATION (c),
8969 : "%<aligned%> clause alignment expression must "
8970 : "be integral");
8971 0 : remove = true;
8972 : }
8973 : else
8974 : {
8975 744 : t = mark_rvalue_use (t);
8976 744 : if (!processing_template_decl)
8977 : {
8978 690 : t = maybe_constant_value (t);
8979 690 : if (TREE_CODE (t) != INTEGER_CST
8980 690 : || tree_int_cst_sgn (t) != 1)
8981 : {
8982 0 : error_at (OMP_CLAUSE_LOCATION (c),
8983 : "%<aligned%> clause alignment expression must "
8984 : "be positive constant integer expression");
8985 0 : remove = true;
8986 : }
8987 : }
8988 744 : OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t;
8989 : }
8990 : break;
8991 :
8992 369 : case OMP_CLAUSE_NONTEMPORAL:
8993 369 : t = OMP_CLAUSE_DECL (c);
8994 369 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
8995 : {
8996 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
8997 : break;
8998 0 : if (DECL_P (t))
8999 0 : error_at (OMP_CLAUSE_LOCATION (c),
9000 : "%qD is not a variable in %<nontemporal%> clause",
9001 : t);
9002 : else
9003 0 : error_at (OMP_CLAUSE_LOCATION (c),
9004 : "%qE is not a variable in %<nontemporal%> clause",
9005 : t);
9006 : remove = true;
9007 : }
9008 369 : else if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
9009 : {
9010 6 : error_at (OMP_CLAUSE_LOCATION (c),
9011 : "%qD appears more than once in %<nontemporal%> "
9012 : "clauses", t);
9013 6 : remove = true;
9014 : }
9015 : else
9016 363 : bitmap_set_bit (&oacc_reduction_head, DECL_UID (t));
9017 : break;
9018 :
9019 2809 : case OMP_CLAUSE_ALLOCATE:
9020 2809 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
9021 2809 : if (t)
9022 14 : omp_note_field_privatization (t, OMP_CLAUSE_DECL (c));
9023 : else
9024 2795 : t = OMP_CLAUSE_DECL (c);
9025 2809 : if (t == current_class_ptr)
9026 : {
9027 0 : error_at (OMP_CLAUSE_LOCATION (c),
9028 : "%<this%> not allowed in %<allocate%> clause");
9029 0 : remove = true;
9030 0 : break;
9031 : }
9032 2809 : if (!VAR_P (t)
9033 678 : && TREE_CODE (t) != PARM_DECL
9034 45 : && TREE_CODE (t) != FIELD_DECL)
9035 : {
9036 3 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9037 : break;
9038 3 : if (DECL_P (t))
9039 3 : error_at (OMP_CLAUSE_LOCATION (c),
9040 : "%qD is not a variable in %<allocate%> clause", t);
9041 : else
9042 0 : error_at (OMP_CLAUSE_LOCATION (c),
9043 : "%qE is not a variable in %<allocate%> clause", t);
9044 : remove = true;
9045 : }
9046 2806 : else if (bitmap_bit_p (&aligned_head, DECL_UID (t)))
9047 : {
9048 12 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9049 : "%qD appears more than once in %<allocate%> clauses",
9050 : t);
9051 12 : remove = true;
9052 : }
9053 : else
9054 : {
9055 2794 : bitmap_set_bit (&aligned_head, DECL_UID (t));
9056 2794 : allocate_seen = true;
9057 : }
9058 2809 : tree allocator, align;
9059 2809 : align = OMP_CLAUSE_ALLOCATE_ALIGN (c);
9060 2809 : if (error_operand_p (align))
9061 : {
9062 : remove = true;
9063 : break;
9064 : }
9065 2809 : if (align)
9066 : {
9067 211 : if (!type_dependent_expression_p (align)
9068 211 : && !INTEGRAL_TYPE_P (TREE_TYPE (align)))
9069 : {
9070 4 : error_at (OMP_CLAUSE_LOCATION (c),
9071 : "%<allocate%> clause %<align%> modifier "
9072 : "argument needs to be positive constant "
9073 : "power of two integer expression");
9074 4 : remove = true;
9075 : }
9076 : else
9077 : {
9078 207 : align = mark_rvalue_use (align);
9079 207 : if (!processing_template_decl)
9080 : {
9081 192 : align = maybe_constant_value (align);
9082 192 : if (TREE_CODE (align) != INTEGER_CST
9083 189 : || !tree_fits_uhwi_p (align)
9084 381 : || !integer_pow2p (align))
9085 : {
9086 10 : error_at (OMP_CLAUSE_LOCATION (c),
9087 : "%<allocate%> clause %<align%> modifier "
9088 : "argument needs to be positive constant "
9089 : "power of two integer expression");
9090 10 : remove = true;
9091 : }
9092 : }
9093 : }
9094 211 : OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
9095 : }
9096 2809 : allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c);
9097 2809 : if (error_operand_p (allocator))
9098 : {
9099 : remove = true;
9100 : break;
9101 : }
9102 2809 : if (allocator == NULL_TREE)
9103 1751 : goto handle_field_decl;
9104 1058 : tree allocatort;
9105 1058 : allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator));
9106 1058 : if (!type_dependent_expression_p (allocator)
9107 1058 : && (TREE_CODE (allocatort) != ENUMERAL_TYPE
9108 1039 : || TYPE_NAME (allocatort) == NULL_TREE
9109 1039 : || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL
9110 2078 : || (DECL_NAME (TYPE_NAME (allocatort))
9111 1039 : != get_identifier ("omp_allocator_handle_t"))
9112 1039 : || (TYPE_CONTEXT (allocatort)
9113 1039 : != DECL_CONTEXT (global_namespace))))
9114 : {
9115 16 : error_at (OMP_CLAUSE_LOCATION (c),
9116 : "%<allocate%> clause allocator expression has "
9117 : "type %qT rather than %<omp_allocator_handle_t%>",
9118 16 : TREE_TYPE (allocator));
9119 16 : remove = true;
9120 16 : break;
9121 : }
9122 : else
9123 : {
9124 1042 : allocator = mark_rvalue_use (allocator);
9125 1042 : if (!processing_template_decl)
9126 1023 : allocator = maybe_constant_value (allocator);
9127 1042 : OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
9128 : }
9129 1042 : goto handle_field_decl;
9130 :
9131 654 : case OMP_CLAUSE_DOACROSS:
9132 654 : t = OMP_CLAUSE_DECL (c);
9133 654 : if (t == NULL_TREE)
9134 : break;
9135 298 : if (OMP_CLAUSE_DOACROSS_KIND (c) == OMP_CLAUSE_DOACROSS_SINK)
9136 : {
9137 298 : if (cp_finish_omp_clause_doacross_sink (c))
9138 98524 : remove = true;
9139 : break;
9140 : }
9141 0 : gcc_unreachable ();
9142 89 : case OMP_CLAUSE_USES_ALLOCATORS:
9143 89 : t = OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c);
9144 89 : t = convert_from_reference (t);
9145 89 : if (t == error_mark_node)
9146 : {
9147 : remove = true;
9148 : break;
9149 : }
9150 82 : if (DECL_P (t)
9151 82 : && (bitmap_bit_p (&generic_head, DECL_UID (t))
9152 79 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9153 78 : || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
9154 : {
9155 1 : error_at (OMP_CLAUSE_LOCATION (c),
9156 : "%qE appears more than once in data clauses", t);
9157 1 : remove = true;
9158 : }
9159 81 : else if (DECL_P (t))
9160 78 : bitmap_set_bit (&generic_head, DECL_UID (t));
9161 82 : if (type_dependent_expression_p (t))
9162 : break;
9163 77 : if (TREE_CODE (t) == FIELD_DECL)
9164 : {
9165 0 : sorry_at (OMP_CLAUSE_LOCATION (c), "class member %qE not yet "
9166 : "supported in %<uses_allocators%> clause", t);
9167 0 : remove = true;
9168 0 : break;
9169 : }
9170 77 : if (TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9171 151 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9172 : "omp_allocator_handle_t") != 0)
9173 : {
9174 3 : error_at (OMP_CLAUSE_LOCATION (c),
9175 : "allocator %qE must be of %<omp_allocator_handle_t%> "
9176 : "type", t);
9177 3 : remove = true;
9178 3 : break;
9179 : }
9180 74 : tree init;
9181 74 : if (TREE_CODE (t) == CONST_DECL)
9182 7 : init = DECL_INITIAL(t);
9183 : else
9184 : init = t;
9185 74 : if (!DECL_P (t)
9186 74 : && (init == NULL_TREE
9187 3 : || TREE_CODE (init) != INTEGER_CST
9188 3 : || ((wi::to_widest (init) < 0
9189 3 : || wi::to_widest (init) > GOMP_OMP_PREDEF_ALLOC_MAX)
9190 1 : && (wi::to_widest (init) < GOMP_OMPX_PREDEF_ALLOC_MIN
9191 1 : || (wi::to_widest (init)
9192 2 : > GOMP_OMPX_PREDEF_ALLOC_MAX)))))
9193 : {
9194 1 : remove = true;
9195 1 : error_at (OMP_CLAUSE_LOCATION (c),
9196 : "allocator %qE must be either a variable or a "
9197 : "predefined allocator", t);
9198 1 : break;
9199 : }
9200 73 : else if (TREE_CODE (t) == CONST_DECL)
9201 : {
9202 : /* omp_null_allocator is ignored and for predefined allocators,
9203 : not special handling is required; thus, remove them removed. */
9204 7 : remove = true;
9205 :
9206 7 : if (OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c)
9207 7 : || OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c))
9208 : {
9209 0 : error_at (OMP_CLAUSE_LOCATION (c),
9210 : "modifiers cannot be used with predefined "
9211 : "allocators");
9212 0 : break;
9213 : }
9214 : }
9215 73 : t = OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c);
9216 73 : if (t == error_mark_node)
9217 : {
9218 : remove = true;
9219 : break;
9220 : }
9221 72 : if (t != NULL_TREE
9222 16 : && !type_dependent_expression_p (t)
9223 88 : && ((TREE_CODE (t) != CONST_DECL && TREE_CODE (t) != INTEGER_CST)
9224 15 : || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE
9225 28 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (TREE_TYPE (t))),
9226 : "omp_memspace_handle_t") != 0))
9227 : {
9228 2 : error_at (OMP_CLAUSE_LOCATION (c), "memspace modifier %qE must be"
9229 : " constant enum of %<omp_memspace_handle_t%> type", t);
9230 2 : remove = true;
9231 2 : break;
9232 : }
9233 70 : t = OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c);
9234 70 : if (t == error_mark_node)
9235 : {
9236 : remove = true;
9237 : break;
9238 : }
9239 69 : if (type_dependent_expression_p (t))
9240 : break;
9241 69 : if (t != NULL_TREE
9242 41 : && t != error_mark_node
9243 41 : && !type_dependent_expression_p (t)
9244 110 : && (!DECL_P (t)
9245 41 : || DECL_EXTERNAL (t)
9246 39 : || TREE_CODE (t) == PARM_DECL))
9247 : {
9248 4 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must be "
9249 : "defined in same scope as the construct on which the "
9250 : "clause appears", t);
9251 4 : remove = true;
9252 : }
9253 69 : if (t != NULL_TREE)
9254 : {
9255 41 : bool type_err = false;
9256 :
9257 41 : if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
9258 39 : || DECL_SIZE (t) == NULL_TREE
9259 79 : || !COMPLETE_TYPE_P (TREE_TYPE (t)))
9260 : type_err = true;
9261 : else
9262 : {
9263 38 : tree elem_t = TREE_TYPE (TREE_TYPE (t));
9264 38 : if (TREE_CODE (elem_t) != RECORD_TYPE
9265 76 : || strcmp (IDENTIFIER_POINTER (TYPE_IDENTIFIER (elem_t)),
9266 : "omp_alloctrait_t") != 0
9267 76 : || !TYPE_READONLY (elem_t))
9268 : type_err = true;
9269 : }
9270 37 : if (type_err)
9271 : {
9272 4 : error_at (OMP_CLAUSE_LOCATION (c), "traits array %qE must "
9273 : "be of %<const omp_alloctrait_t []%> type", t);
9274 4 : remove = true;
9275 : }
9276 37 : else if (TREE_CODE (array_type_nelts_top (TREE_TYPE (t)))
9277 : != INTEGER_CST)
9278 : {
9279 1 : error_at (OMP_CLAUSE_LOCATION (c), "variable length traits "
9280 : "arrays are not supported");
9281 1 : remove = true;
9282 : }
9283 : else
9284 : {
9285 36 : tree cst_val = decl_constant_value (t);
9286 36 : if (cst_val == t)
9287 : {
9288 1 : error_at (OMP_CLAUSE_LOCATION (c), "traits array must be "
9289 : "initialized with constants");
9290 1 : remove = true;
9291 : }
9292 : }
9293 : }
9294 69 : if (remove)
9295 : break;
9296 55 : pc = &OMP_CLAUSE_CHAIN (c);
9297 55 : continue;
9298 1807 : case OMP_CLAUSE_DEPEND:
9299 1807 : depend_clause = c;
9300 : /* FALLTHRU */
9301 2416 : case OMP_CLAUSE_AFFINITY:
9302 2416 : t = OMP_CLAUSE_DECL (c);
9303 2416 : if (OMP_ITERATOR_DECL_P (t))
9304 : {
9305 623 : if (TREE_PURPOSE (t) != last_iterators)
9306 525 : last_iterators_remove
9307 525 : = cp_omp_finish_iterators (TREE_PURPOSE (t));
9308 623 : last_iterators = TREE_PURPOSE (t);
9309 623 : t = TREE_VALUE (t);
9310 623 : if (last_iterators_remove)
9311 144 : t = error_mark_node;
9312 : }
9313 : else
9314 : last_iterators = NULL_TREE;
9315 :
9316 2416 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9317 : {
9318 1368 : if (handle_omp_array_sections (c, ort))
9319 : remove = true;
9320 1014 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9321 1014 : && (OMP_CLAUSE_DEPEND_KIND (c)
9322 : == OMP_CLAUSE_DEPEND_DEPOBJ))
9323 : {
9324 6 : error_at (OMP_CLAUSE_LOCATION (c),
9325 : "%<depend%> clause with %<depobj%> dependence "
9326 : "type on array section");
9327 6 : remove = true;
9328 : }
9329 : break;
9330 : }
9331 1048 : if (t == error_mark_node)
9332 : remove = true;
9333 886 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9334 886 : && t == ridpointers[RID_OMP_ALL_MEMORY])
9335 : {
9336 33 : if (OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_OUT
9337 33 : && OMP_CLAUSE_DEPEND_KIND (c) != OMP_CLAUSE_DEPEND_INOUT)
9338 : {
9339 9 : error_at (OMP_CLAUSE_LOCATION (c),
9340 : "%<omp_all_memory%> used with %<depend%> kind "
9341 : "other than %<out%> or %<inout%>");
9342 9 : remove = true;
9343 : }
9344 33 : if (processing_template_decl)
9345 : break;
9346 : }
9347 853 : else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9348 : break;
9349 661 : else if (!lvalue_p (t))
9350 : {
9351 21 : if (DECL_P (t))
9352 24 : error_at (OMP_CLAUSE_LOCATION (c),
9353 : "%qD is not lvalue expression nor array section "
9354 : "in %qs clause", t,
9355 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9356 : else
9357 18 : error_at (OMP_CLAUSE_LOCATION (c),
9358 : "%qE is not lvalue expression nor array section "
9359 : "in %qs clause", t,
9360 9 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9361 : remove = true;
9362 : }
9363 640 : else if (TREE_CODE (t) == COMPONENT_REF
9364 36 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
9365 676 : && DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
9366 : {
9367 12 : error_at (OMP_CLAUSE_LOCATION (c),
9368 : "bit-field %qE in %qs clause", t,
9369 6 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9370 6 : remove = true;
9371 : }
9372 634 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9373 634 : && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ)
9374 : {
9375 130 : if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9376 8 : ? TREE_TYPE (TREE_TYPE (t))
9377 57 : : TREE_TYPE (t)))
9378 : {
9379 12 : error_at (OMP_CLAUSE_LOCATION (c),
9380 : "%qE does not have %<omp_depend_t%> type in "
9381 : "%<depend%> clause with %<depobj%> dependence "
9382 : "type", t);
9383 12 : remove = true;
9384 : }
9385 : }
9386 569 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
9387 1010 : && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t))
9388 4 : ? TREE_TYPE (TREE_TYPE (t))
9389 437 : : TREE_TYPE (t)))
9390 : {
9391 15 : error_at (OMP_CLAUSE_LOCATION (c),
9392 : "%qE should not have %<omp_depend_t%> type in "
9393 : "%<depend%> clause with dependence type other than "
9394 : "%<depobj%>", t);
9395 15 : remove = true;
9396 : }
9397 87 : if (!remove)
9398 : {
9399 631 : if (t == ridpointers[RID_OMP_ALL_MEMORY])
9400 24 : t = null_pointer_node;
9401 : else
9402 : {
9403 607 : tree addr = cp_build_addr_expr (t, tf_warning_or_error);
9404 607 : if (addr == error_mark_node)
9405 : {
9406 : remove = true;
9407 : break;
9408 : }
9409 607 : t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c),
9410 : addr, RO_UNARY_STAR,
9411 : tf_warning_or_error);
9412 607 : if (t == error_mark_node)
9413 : {
9414 : remove = true;
9415 : break;
9416 : }
9417 : }
9418 631 : if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST
9419 137 : && TREE_PURPOSE (OMP_CLAUSE_DECL (c))
9420 768 : && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c)))
9421 : == TREE_VEC))
9422 137 : TREE_VALUE (OMP_CLAUSE_DECL (c)) = t;
9423 : else
9424 494 : OMP_CLAUSE_DECL (c) = t;
9425 : }
9426 : break;
9427 69 : case OMP_CLAUSE_DETACH:
9428 69 : t = OMP_CLAUSE_DECL (c);
9429 69 : if (detach_seen)
9430 : {
9431 3 : error_at (OMP_CLAUSE_LOCATION (c),
9432 : "too many %qs clauses on a task construct",
9433 : "detach");
9434 3 : remove = true;
9435 3 : break;
9436 : }
9437 66 : else if (error_operand_p (t))
9438 : {
9439 : remove = true;
9440 : break;
9441 : }
9442 : else
9443 : {
9444 63 : tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
9445 63 : if (!type_dependent_expression_p (t)
9446 63 : && (!INTEGRAL_TYPE_P (type)
9447 : || TREE_CODE (type) != ENUMERAL_TYPE
9448 51 : || TYPE_NAME (type) == NULL_TREE
9449 102 : || (DECL_NAME (TYPE_NAME (type))
9450 51 : != get_identifier ("omp_event_handle_t"))))
9451 : {
9452 6 : error_at (OMP_CLAUSE_LOCATION (c),
9453 : "%<detach%> clause event handle "
9454 : "has type %qT rather than "
9455 : "%<omp_event_handle_t%>",
9456 : type);
9457 6 : remove = true;
9458 : }
9459 63 : detach_seen = c;
9460 63 : cxx_mark_addressable (t);
9461 : }
9462 63 : break;
9463 :
9464 16361 : case OMP_CLAUSE_MAP:
9465 16361 : if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved)
9466 157 : goto move_implicit;
9467 16204 : if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_PUSH_MAPPER_NAME
9468 16204 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POP_MAPPER_NAME)
9469 : {
9470 : remove = true;
9471 : break;
9472 : }
9473 : /* FALLTHRU */
9474 19391 : case OMP_CLAUSE_TO:
9475 19391 : case OMP_CLAUSE_FROM:
9476 19391 : if (OMP_CLAUSE_ITERATORS (c)
9477 19391 : && cp_omp_finish_iterators (OMP_CLAUSE_ITERATORS (c)))
9478 : {
9479 98524 : t = error_mark_node;
9480 : break;
9481 : }
9482 : /* FALLTHRU */
9483 20279 : case OMP_CLAUSE__CACHE_:
9484 20279 : {
9485 20279 : using namespace omp_addr_tokenizer;
9486 20279 : auto_vec<omp_addr_token *, 10> addr_tokens;
9487 :
9488 20279 : t = OMP_CLAUSE_DECL (c);
9489 20279 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
9490 : {
9491 6006 : grp_start_p = pc;
9492 6006 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9493 :
9494 6006 : if (handle_omp_array_sections (c, ort))
9495 : remove = true;
9496 : else
9497 : {
9498 5196 : t = OMP_CLAUSE_DECL (c);
9499 5196 : if (TREE_CODE (t) != OMP_ARRAY_SECTION
9500 4335 : && !type_dependent_expression_p (t)
9501 9531 : && !omp_mappable_type (TREE_TYPE (t)))
9502 : {
9503 3 : auto_diagnostic_group d;
9504 6 : error_at (OMP_CLAUSE_LOCATION (c),
9505 : "array section does not have mappable type "
9506 : "in %qs clause",
9507 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9508 3 : if (TREE_TYPE (t) != error_mark_node
9509 3 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9510 3 : cxx_incomplete_type_inform (TREE_TYPE (t));
9511 3 : remove = true;
9512 3 : }
9513 7121 : while (TREE_CODE (t) == ARRAY_REF)
9514 1925 : t = TREE_OPERAND (t, 0);
9515 :
9516 5196 : if (type_dependent_expression_p (t))
9517 : break;
9518 :
9519 4722 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9520 :
9521 4722 : if (!ai.map_supported_p ()
9522 4722 : || !omp_parse_expr (addr_tokens, t))
9523 : {
9524 18 : sorry_at (OMP_CLAUSE_LOCATION (c),
9525 : "unsupported map expression %qE",
9526 9 : OMP_CLAUSE_DECL (c));
9527 9 : remove = true;
9528 9 : break;
9529 : }
9530 :
9531 : /* This check is to determine if this will be the only map
9532 : node created for this clause. Otherwise, we'll check
9533 : the following FIRSTPRIVATE_POINTER,
9534 : FIRSTPRIVATE_REFERENCE or ATTACH_DETACH node on the next
9535 : iteration(s) of the loop. */
9536 9377 : if (addr_tokens.length () >= 4
9537 1063 : && addr_tokens[0]->type == STRUCTURE_BASE
9538 1057 : && addr_tokens[0]->u.structure_base_kind == BASE_DECL
9539 1057 : && addr_tokens[1]->type == ACCESS_METHOD
9540 1057 : && addr_tokens[2]->type == COMPONENT_SELECTOR
9541 977 : && addr_tokens[3]->type == ACCESS_METHOD
9542 5427 : && (addr_tokens[3]->u.access_kind == ACCESS_DIRECT
9543 551 : || (addr_tokens[3]->u.access_kind
9544 : == ACCESS_INDEXED_ARRAY)))
9545 : {
9546 165 : tree rt = addr_tokens[1]->expr;
9547 :
9548 165 : gcc_assert (DECL_P (rt));
9549 :
9550 165 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9551 154 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9552 165 : && (bitmap_bit_p (&map_head, DECL_UID (rt))
9553 0 : || bitmap_bit_p (&map_field_head, DECL_UID (rt))
9554 0 : || bitmap_bit_p (&map_firstprivate_head,
9555 0 : DECL_UID (rt))))
9556 : {
9557 : remove = true;
9558 : break;
9559 : }
9560 165 : if (bitmap_bit_p (&map_field_head, DECL_UID (rt)))
9561 : break;
9562 116 : if (bitmap_bit_p (&map_head, DECL_UID (rt)))
9563 : {
9564 0 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9565 0 : error_at (OMP_CLAUSE_LOCATION (c),
9566 : "%qD appears more than once in motion"
9567 : " clauses", rt);
9568 0 : else if (openacc)
9569 0 : error_at (OMP_CLAUSE_LOCATION (c),
9570 : "%qD appears more than once in data"
9571 : " clauses", rt);
9572 : else
9573 0 : error_at (OMP_CLAUSE_LOCATION (c),
9574 : "%qD appears more than once in map"
9575 : " clauses", rt);
9576 : remove = true;
9577 : }
9578 : else
9579 : {
9580 116 : bitmap_set_bit (&map_head, DECL_UID (rt));
9581 116 : bitmap_set_bit (&map_field_head, DECL_UID (rt));
9582 : }
9583 : }
9584 4722 : }
9585 5474 : if (cp_oacc_check_attachments (c))
9586 12 : remove = true;
9587 5474 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9588 4484 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9589 4420 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9590 5572 : && !OMP_CLAUSE_SIZE (c))
9591 : /* In this case, we have a single array element which is a
9592 : pointer, and we already set OMP_CLAUSE_SIZE in
9593 : handle_omp_array_sections above. For attach/detach
9594 : clauses, reset the OMP_CLAUSE_SIZE (representing a bias)
9595 : to zero here. */
9596 60 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9597 : break;
9598 : }
9599 14273 : else if (type_dependent_expression_p (t))
9600 : break;
9601 13490 : else if (!omp_parse_expr (addr_tokens, t))
9602 : {
9603 0 : sorry_at (OMP_CLAUSE_LOCATION (c),
9604 : "unsupported map expression %qE",
9605 0 : OMP_CLAUSE_DECL (c));
9606 0 : remove = true;
9607 0 : break;
9608 : }
9609 13490 : if (t == error_mark_node)
9610 : {
9611 : remove = true;
9612 : break;
9613 : }
9614 :
9615 13376 : tree attr;
9616 13376 : if (DECL_P (t)
9617 10690 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9618 7767 : && (attr = lookup_attribute ("omp declare target",
9619 7767 : DECL_ATTRIBUTES (t)))
9620 13908 : && value_member (get_identifier ("local"),
9621 532 : TREE_VALUE (attr)))
9622 : {
9623 0 : error_at (OMP_CLAUSE_LOCATION (c),
9624 : "device-local variable %qD cannot appear "
9625 : "in map clause", t);
9626 0 : remove = true;
9627 0 : break;
9628 : }
9629 :
9630 : /* OpenACC attach / detach clauses must be pointers. */
9631 13376 : if (cp_oacc_check_attachments (c))
9632 : {
9633 : remove = true;
9634 : break;
9635 : }
9636 13352 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9637 10307 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH
9638 10258 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)
9639 13426 : && !OMP_CLAUSE_SIZE (c))
9640 : /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a
9641 : bias) to zero here, so it is not set erroneously to the
9642 : pointer size later on in gimplify.cc. */
9643 66 : OMP_CLAUSE_SIZE (c) = size_zero_node;
9644 :
9645 13352 : cp_omp_address_inspector ai (OMP_CLAUSE_LOCATION (c), t);
9646 :
9647 13352 : if (!ai.check_clause (c))
9648 : {
9649 : remove = true;
9650 : break;
9651 : }
9652 :
9653 13331 : if (!ai.map_supported_p ())
9654 : {
9655 88 : sorry_at (OMP_CLAUSE_LOCATION (c),
9656 : "unsupported map expression %qE",
9657 44 : OMP_CLAUSE_DECL (c));
9658 44 : remove = true;
9659 44 : break;
9660 : }
9661 :
9662 26574 : gcc_assert ((addr_tokens[0]->type == ARRAY_BASE
9663 : || addr_tokens[0]->type == STRUCTURE_BASE)
9664 : && addr_tokens[1]->type == ACCESS_METHOD);
9665 :
9666 13287 : t = addr_tokens[1]->expr;
9667 :
9668 : /* This is used to prevent cxx_mark_addressable from being called
9669 : on 'this' for expressions like 'this->a', i.e. typical member
9670 : accesses. */
9671 13287 : indir_component_ref_p
9672 26574 : = (addr_tokens[0]->type == STRUCTURE_BASE
9673 13287 : && addr_tokens[1]->u.access_kind != ACCESS_DIRECT);
9674 :
9675 13287 : if (addr_tokens[0]->u.structure_base_kind != BASE_DECL)
9676 1 : goto skip_decl_checks;
9677 :
9678 : /* For OpenMP, we can access a struct "t" and "t.d" on the same
9679 : mapping. OpenACC allows multiple fields of the same structure
9680 : to be written. */
9681 13286 : if (addr_tokens[0]->type == STRUCTURE_BASE
9682 13286 : && (bitmap_bit_p (&map_field_head, DECL_UID (t))
9683 1263 : || (!openacc && bitmap_bit_p (&map_head, DECL_UID (t)))))
9684 1351 : goto skip_decl_checks;
9685 :
9686 11935 : if (!processing_template_decl && TREE_CODE (t) == FIELD_DECL)
9687 : {
9688 0 : OMP_CLAUSE_DECL (c)
9689 0 : = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
9690 0 : break;
9691 : }
9692 11935 : if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
9693 : {
9694 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
9695 : break;
9696 0 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9697 0 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9698 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER
9699 0 : || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH
9700 0 : || (!openacc && EXPR_P (t))))
9701 : break;
9702 0 : if (DECL_P (t))
9703 0 : error_at (OMP_CLAUSE_LOCATION (c),
9704 : "%qD is not a variable in %qs clause", t,
9705 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9706 : else
9707 0 : error_at (OMP_CLAUSE_LOCATION (c),
9708 : "%qE is not a variable in %qs clause", t,
9709 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9710 : remove = true;
9711 : }
9712 11935 : else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
9713 : {
9714 0 : error_at (OMP_CLAUSE_LOCATION (c),
9715 : "%qD is threadprivate variable in %qs clause", t,
9716 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9717 0 : remove = true;
9718 : }
9719 11935 : else if (!processing_template_decl
9720 11756 : && !TYPE_REF_P (TREE_TYPE (t))
9721 11079 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9722 8144 : || (OMP_CLAUSE_MAP_KIND (c)
9723 : != GOMP_MAP_FIRSTPRIVATE_POINTER))
9724 9096 : && !indir_component_ref_p
9725 8732 : && (t != current_class_ptr
9726 18 : || OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9727 6 : || OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH)
9728 20667 : && !cxx_mark_addressable (t))
9729 : remove = true;
9730 11935 : else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9731 8982 : && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
9732 8982 : || (OMP_CLAUSE_MAP_KIND (c)
9733 : == GOMP_MAP_FIRSTPRIVATE_POINTER)
9734 6999 : || (OMP_CLAUSE_MAP_KIND (c)
9735 : == GOMP_MAP_ATTACH_DETACH)))
9736 9292 : && t == OMP_CLAUSE_DECL (c)
9737 8594 : && !type_dependent_expression_p (t)
9738 29123 : && !omp_mappable_type (TYPE_REF_P (TREE_TYPE (t))
9739 278 : ? TREE_TYPE (TREE_TYPE (t))
9740 8316 : : TREE_TYPE (t)))
9741 : {
9742 42 : auto_diagnostic_group d;
9743 84 : error_at (OMP_CLAUSE_LOCATION (c),
9744 : "%qD does not have a mappable type in %qs clause", t,
9745 42 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
9746 42 : if (TREE_TYPE (t) != error_mark_node
9747 42 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9748 39 : cxx_incomplete_type_inform (TREE_TYPE (t));
9749 42 : remove = true;
9750 42 : }
9751 11893 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9752 8946 : && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR
9753 93 : && !type_dependent_expression_p (t)
9754 11986 : && !INDIRECT_TYPE_P (TREE_TYPE (t)))
9755 : {
9756 6 : error_at (OMP_CLAUSE_LOCATION (c),
9757 : "%qD is not a pointer variable", t);
9758 6 : remove = true;
9759 : }
9760 11887 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9761 8940 : && OMP_CLAUSE_MAP_IMPLICIT (c)
9762 12257 : && (bitmap_bit_p (&map_head, DECL_UID (t))
9763 367 : || bitmap_bit_p (&map_field_head, DECL_UID (t))
9764 367 : || bitmap_bit_p (&map_firstprivate_head,
9765 367 : DECL_UID (t))))
9766 : remove = true;
9767 11881 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9768 11881 : && (OMP_CLAUSE_MAP_KIND (c)
9769 : == GOMP_MAP_FIRSTPRIVATE_POINTER))
9770 : {
9771 1977 : if (bitmap_bit_p (&generic_head, DECL_UID (t))
9772 1977 : || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9773 3951 : || (openacc
9774 1364 : && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))))
9775 : {
9776 12 : error_at (OMP_CLAUSE_LOCATION (c),
9777 : "%qD appears more than once in data clauses", t);
9778 12 : remove = true;
9779 : }
9780 1965 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9781 12 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9782 1973 : && openacc)
9783 : {
9784 3 : error_at (OMP_CLAUSE_LOCATION (c),
9785 : "%qD appears more than once in data clauses", t);
9786 3 : remove = true;
9787 : }
9788 : else
9789 1962 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9790 : }
9791 9904 : else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
9792 9904 : && (OMP_CLAUSE_MAP_KIND (c)
9793 : == GOMP_MAP_FIRSTPRIVATE_REFERENCE))
9794 115 : bitmap_set_bit (&map_firstprivate_head, DECL_UID (t));
9795 9789 : else if (bitmap_bit_p (&map_head, DECL_UID (t))
9796 181 : && !bitmap_bit_p (&map_field_head, DECL_UID (t))
9797 38 : && ort != C_ORT_OMP
9798 38 : && ort != C_ORT_OMP_TARGET
9799 9805 : && ort != C_ORT_OMP_EXIT_DATA)
9800 : {
9801 9 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
9802 0 : error_at (OMP_CLAUSE_LOCATION (c),
9803 : "%qD appears more than once in motion clauses", t);
9804 9 : else if (openacc)
9805 9 : error_at (OMP_CLAUSE_LOCATION (c),
9806 : "%qD appears more than once in data clauses", t);
9807 : else
9808 0 : error_at (OMP_CLAUSE_LOCATION (c),
9809 : "%qD appears more than once in map clauses", t);
9810 : remove = true;
9811 : }
9812 9780 : else if (openacc && bitmap_bit_p (&generic_head, DECL_UID (t)))
9813 : {
9814 0 : error_at (OMP_CLAUSE_LOCATION (c),
9815 : "%qD appears more than once in data clauses", t);
9816 0 : remove = true;
9817 : }
9818 9780 : else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))
9819 9780 : || bitmap_bit_p (&is_on_device_head, DECL_UID (t)))
9820 : {
9821 27 : if (openacc)
9822 0 : error_at (OMP_CLAUSE_LOCATION (c),
9823 : "%qD appears more than once in data clauses", t);
9824 : else
9825 27 : error_at (OMP_CLAUSE_LOCATION (c),
9826 : "%qD appears both in data and map clauses", t);
9827 : remove = true;
9828 : }
9829 9753 : else if (!omp_access_chain_p (addr_tokens, 1))
9830 : {
9831 9673 : bitmap_set_bit (&map_head, DECL_UID (t));
9832 :
9833 9673 : tree decl = OMP_CLAUSE_DECL (c);
9834 9673 : if (t != decl
9835 9673 : && (TREE_CODE (decl) == COMPONENT_REF
9836 162 : || (INDIRECT_REF_P (decl)
9837 162 : && (TREE_CODE (TREE_OPERAND (decl, 0))
9838 : == COMPONENT_REF)
9839 150 : && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (decl,
9840 : 0))))))
9841 1165 : bitmap_set_bit (&map_field_head, DECL_UID (t));
9842 : }
9843 :
9844 4693 : skip_decl_checks:
9845 : /* If we call ai.expand_map_clause in handle_omp_array_sections,
9846 : the containing loop (here) iterates through the new nodes
9847 : created by that expansion. Avoid expanding those again (just
9848 : by checking the node type). */
9849 4693 : if (!remove
9850 13182 : && !processing_template_decl
9851 13006 : && ort != C_ORT_DECLARE_SIMD
9852 13006 : && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP
9853 9979 : || (OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_FIRSTPRIVATE_POINTER
9854 8017 : && (OMP_CLAUSE_MAP_KIND (c)
9855 : != GOMP_MAP_FIRSTPRIVATE_REFERENCE)
9856 7902 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ALWAYS_POINTER
9857 7902 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH_DETACH
9858 6903 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_ATTACH
9859 6854 : && OMP_CLAUSE_MAP_KIND (c) != GOMP_MAP_DETACH)))
9860 : {
9861 9856 : grp_start_p = pc;
9862 9856 : grp_sentinel = OMP_CLAUSE_CHAIN (c);
9863 9856 : tree nc = ai.expand_map_clause (c, OMP_CLAUSE_DECL (c),
9864 : addr_tokens, ort);
9865 9856 : if (nc != error_mark_node)
9866 9856 : c = nc;
9867 : }
9868 20344 : }
9869 13287 : break;
9870 :
9871 645 : case OMP_CLAUSE_ENTER:
9872 645 : case OMP_CLAUSE_LINK:
9873 645 : case OMP_CLAUSE_LOCAL:
9874 645 : t = OMP_CLAUSE_DECL (c);
9875 645 : const char *cname;
9876 645 : cname = omp_clause_code_name[OMP_CLAUSE_CODE (c)];
9877 645 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER
9878 645 : && OMP_CLAUSE_ENTER_TO (c))
9879 : cname = "to";
9880 645 : if (TREE_CODE (t) == FUNCTION_DECL
9881 645 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9882 : ;
9883 428 : else if (!VAR_P (t))
9884 : {
9885 12 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
9886 : {
9887 9 : if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
9888 6 : error_at (OMP_CLAUSE_LOCATION (c),
9889 : "template %qE in clause %qs", t, cname);
9890 3 : else if (really_overloaded_fn (t))
9891 3 : error_at (OMP_CLAUSE_LOCATION (c),
9892 : "overloaded function name %qE in clause %qs", t,
9893 : cname);
9894 : else
9895 0 : error_at (OMP_CLAUSE_LOCATION (c),
9896 : "%qE is neither a variable nor a function name "
9897 : "in clause %qs", t, cname);
9898 : }
9899 : else
9900 3 : error_at (OMP_CLAUSE_LOCATION (c),
9901 : "%qE is not a variable in clause %qs", t, cname);
9902 : remove = true;
9903 : }
9904 416 : else if (DECL_THREAD_LOCAL_P (t))
9905 : {
9906 6 : error_at (OMP_CLAUSE_LOCATION (c),
9907 : "%qD is threadprivate variable in %qs clause", t,
9908 : cname);
9909 6 : remove = true;
9910 : }
9911 410 : else if (!omp_mappable_type (TREE_TYPE (t)))
9912 : {
9913 18 : auto_diagnostic_group d;
9914 18 : error_at (OMP_CLAUSE_LOCATION (c),
9915 : "%qD does not have a mappable type in %qs clause", t,
9916 : cname);
9917 18 : if (TREE_TYPE (t) != error_mark_node
9918 18 : && !COMPLETE_TYPE_P (TREE_TYPE (t)))
9919 18 : cxx_incomplete_type_inform (TREE_TYPE (t));
9920 18 : remove = true;
9921 18 : }
9922 36 : if (remove)
9923 : break;
9924 609 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
9925 : {
9926 30 : error_at (OMP_CLAUSE_LOCATION (c),
9927 : "%qE appears more than once on the same "
9928 : "%<declare target%> directive", t);
9929 30 : remove = true;
9930 : }
9931 : else
9932 579 : bitmap_set_bit (&generic_head, DECL_UID (t));
9933 : break;
9934 :
9935 457 : case OMP_CLAUSE_UNIFORM:
9936 457 : t = OMP_CLAUSE_DECL (c);
9937 457 : if (TREE_CODE (t) != PARM_DECL)
9938 : {
9939 0 : if (processing_template_decl)
9940 : break;
9941 0 : if (DECL_P (t))
9942 0 : error_at (OMP_CLAUSE_LOCATION (c),
9943 : "%qD is not an argument in %<uniform%> clause", t);
9944 : else
9945 0 : error_at (OMP_CLAUSE_LOCATION (c),
9946 : "%qE is not an argument in %<uniform%> clause", t);
9947 : remove = true;
9948 : break;
9949 : }
9950 : /* map_head bitmap is used as uniform_head if declare_simd. */
9951 457 : bitmap_set_bit (&map_head, DECL_UID (t));
9952 457 : goto check_dup_generic;
9953 :
9954 165 : case OMP_CLAUSE_GRAINSIZE:
9955 165 : t = OMP_CLAUSE_GRAINSIZE_EXPR (c);
9956 165 : if (t == error_mark_node)
9957 : remove = true;
9958 165 : else if (!type_dependent_expression_p (t)
9959 165 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9960 : {
9961 0 : error_at (OMP_CLAUSE_LOCATION (c),
9962 : "%<grainsize%> expression must be integral");
9963 0 : remove = true;
9964 : }
9965 : else
9966 : {
9967 165 : t = mark_rvalue_use (t);
9968 165 : if (!processing_template_decl)
9969 : {
9970 164 : t = maybe_constant_value (t);
9971 164 : if (TREE_CODE (t) == INTEGER_CST
9972 164 : && tree_int_cst_sgn (t) != 1)
9973 : {
9974 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
9975 : "%<grainsize%> value must be positive");
9976 0 : t = integer_one_node;
9977 : }
9978 164 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
9979 : }
9980 165 : OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
9981 : }
9982 : break;
9983 :
9984 276 : case OMP_CLAUSE_PRIORITY:
9985 276 : t = OMP_CLAUSE_PRIORITY_EXPR (c);
9986 276 : if (t == error_mark_node)
9987 : remove = true;
9988 276 : else if (!type_dependent_expression_p (t)
9989 276 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
9990 : {
9991 0 : error_at (OMP_CLAUSE_LOCATION (c),
9992 : "%<priority%> expression must be integral");
9993 0 : remove = true;
9994 : }
9995 : else
9996 : {
9997 276 : t = mark_rvalue_use (t);
9998 276 : if (!processing_template_decl)
9999 : {
10000 276 : t = maybe_constant_value (t);
10001 276 : if (TREE_CODE (t) == INTEGER_CST
10002 276 : && tree_int_cst_sgn (t) == -1)
10003 : {
10004 0 : warning_at (OMP_CLAUSE_LOCATION (c), OPT_Wopenmp,
10005 : "%<priority%> value must be non-negative");
10006 0 : t = integer_one_node;
10007 : }
10008 276 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
10009 : }
10010 276 : OMP_CLAUSE_PRIORITY_EXPR (c) = t;
10011 : }
10012 : break;
10013 :
10014 228 : case OMP_CLAUSE_HINT:
10015 228 : t = OMP_CLAUSE_HINT_EXPR (c);
10016 228 : if (t == error_mark_node)
10017 : remove = true;
10018 228 : else if (!type_dependent_expression_p (t)
10019 228 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10020 : {
10021 9 : error_at (OMP_CLAUSE_LOCATION (c),
10022 : "%<hint%> expression must be integral");
10023 9 : remove = true;
10024 : }
10025 : else
10026 : {
10027 219 : t = mark_rvalue_use (t);
10028 219 : if (!processing_template_decl)
10029 : {
10030 171 : t = maybe_constant_value (t);
10031 171 : if (TREE_CODE (t) != INTEGER_CST)
10032 : {
10033 16 : error_at (OMP_CLAUSE_LOCATION (c),
10034 : "%<hint%> expression must be constant integer "
10035 : "expression");
10036 16 : remove = true;
10037 : }
10038 : }
10039 219 : OMP_CLAUSE_HINT_EXPR (c) = t;
10040 : }
10041 : break;
10042 :
10043 186 : case OMP_CLAUSE_FILTER:
10044 186 : t = OMP_CLAUSE_FILTER_EXPR (c);
10045 186 : if (t == error_mark_node)
10046 : remove = true;
10047 186 : else if (!type_dependent_expression_p (t)
10048 186 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10049 : {
10050 6 : error_at (OMP_CLAUSE_LOCATION (c),
10051 : "%<filter%> expression must be integral");
10052 6 : remove = true;
10053 : }
10054 : else
10055 : {
10056 180 : t = mark_rvalue_use (t);
10057 180 : if (!processing_template_decl)
10058 : {
10059 177 : t = maybe_constant_value (t);
10060 177 : t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
10061 : }
10062 180 : OMP_CLAUSE_FILTER_EXPR (c) = t;
10063 : }
10064 : break;
10065 :
10066 433 : case OMP_CLAUSE_IS_DEVICE_PTR:
10067 433 : case OMP_CLAUSE_USE_DEVICE_PTR:
10068 433 : field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
10069 433 : t = OMP_CLAUSE_DECL (c);
10070 433 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IS_DEVICE_PTR)
10071 329 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
10072 433 : if (!type_dependent_expression_p (t))
10073 : {
10074 431 : tree type = TREE_TYPE (t);
10075 431 : if (!TYPE_PTR_P (type)
10076 431 : && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
10077 : {
10078 57 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
10079 57 : && ort == C_ORT_OMP)
10080 : {
10081 3 : error_at (OMP_CLAUSE_LOCATION (c),
10082 : "%qs variable is neither a pointer "
10083 : "nor reference to pointer",
10084 3 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10085 3 : remove = true;
10086 : }
10087 54 : else if (TREE_CODE (type) != ARRAY_TYPE
10088 54 : && (!TYPE_REF_P (type)
10089 2 : || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
10090 : {
10091 12 : error_at (OMP_CLAUSE_LOCATION (c),
10092 : "%qs variable is neither a pointer, nor an "
10093 : "array nor reference to pointer or array",
10094 12 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10095 12 : remove = true;
10096 : }
10097 : }
10098 : }
10099 433 : goto check_dup_generic;
10100 :
10101 267 : case OMP_CLAUSE_HAS_DEVICE_ADDR:
10102 267 : t = OMP_CLAUSE_DECL (c);
10103 267 : if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10104 : {
10105 28 : if (handle_omp_array_sections (c, ort))
10106 : remove = true;
10107 : else
10108 : {
10109 28 : t = OMP_CLAUSE_DECL (c);
10110 30 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10111 2 : t = TREE_OPERAND (t, 0);
10112 64 : while (INDIRECT_REF_P (t)
10113 64 : || TREE_CODE (t) == ARRAY_REF)
10114 36 : t = TREE_OPERAND (t, 0);
10115 : }
10116 : }
10117 267 : if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
10118 : {
10119 267 : bitmap_set_bit (&is_on_device_head, DECL_UID (t));
10120 267 : if (!processing_template_decl
10121 267 : && !cxx_mark_addressable (t))
10122 : remove = true;
10123 : }
10124 267 : goto check_dup_generic_t;
10125 :
10126 76 : case OMP_CLAUSE_USE_DEVICE_ADDR:
10127 76 : field_ok = true;
10128 76 : t = OMP_CLAUSE_DECL (c);
10129 76 : if (!processing_template_decl
10130 74 : && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
10131 74 : && !TYPE_REF_P (TREE_TYPE (t))
10132 143 : && !cxx_mark_addressable (t))
10133 : remove = true;
10134 76 : goto check_dup_generic;
10135 :
10136 : case OMP_CLAUSE_NOWAIT:
10137 : case OMP_CLAUSE_DEFAULT:
10138 : case OMP_CLAUSE_UNTIED:
10139 : case OMP_CLAUSE_COLLAPSE:
10140 : case OMP_CLAUSE_PARALLEL:
10141 : case OMP_CLAUSE_FOR:
10142 : case OMP_CLAUSE_SECTIONS:
10143 : case OMP_CLAUSE_TASKGROUP:
10144 : case OMP_CLAUSE_PROC_BIND:
10145 : case OMP_CLAUSE_DEVICE_TYPE:
10146 : case OMP_CLAUSE_NOGROUP:
10147 : case OMP_CLAUSE_THREADS:
10148 : case OMP_CLAUSE_SIMD:
10149 : case OMP_CLAUSE_DEFAULTMAP:
10150 : case OMP_CLAUSE_BIND:
10151 : case OMP_CLAUSE_AUTO:
10152 : case OMP_CLAUSE_INDEPENDENT:
10153 : case OMP_CLAUSE_SEQ:
10154 : case OMP_CLAUSE_IF_PRESENT:
10155 : case OMP_CLAUSE_FINALIZE:
10156 : case OMP_CLAUSE_NOHOST:
10157 : case OMP_CLAUSE_INDIRECT:
10158 : break;
10159 :
10160 231 : case OMP_CLAUSE_MERGEABLE:
10161 231 : mergeable_seen = true;
10162 231 : break;
10163 :
10164 322 : case OMP_CLAUSE_TILE:
10165 754 : for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list;
10166 432 : list = TREE_CHAIN (list))
10167 : {
10168 432 : t = TREE_VALUE (list);
10169 :
10170 432 : if (t == error_mark_node)
10171 : remove = true;
10172 403 : else if (!type_dependent_expression_p (t)
10173 403 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10174 : {
10175 3 : error_at (OMP_CLAUSE_LOCATION (c),
10176 : "%<tile%> argument needs integral type");
10177 3 : remove = true;
10178 : }
10179 : else
10180 : {
10181 400 : t = mark_rvalue_use (t);
10182 400 : if (!processing_template_decl)
10183 : {
10184 : /* Zero is used to indicate '*', we permit you
10185 : to get there via an ICE of value zero. */
10186 385 : t = maybe_constant_value (t);
10187 385 : if (!tree_fits_shwi_p (t)
10188 369 : || tree_to_shwi (t) < 0)
10189 : {
10190 40 : error_at (OMP_CLAUSE_LOCATION (c),
10191 : "%<tile%> argument needs positive "
10192 : "integral constant");
10193 40 : remove = true;
10194 : }
10195 : }
10196 : }
10197 :
10198 : /* Update list item. */
10199 432 : TREE_VALUE (list) = t;
10200 : }
10201 : break;
10202 :
10203 1027 : case OMP_CLAUSE_SIZES:
10204 1027 : for (tree list = OMP_CLAUSE_SIZES_LIST (c);
10205 2688 : !remove && list; list = TREE_CHAIN (list))
10206 : {
10207 1661 : t = TREE_VALUE (list);
10208 :
10209 1661 : if (t == error_mark_node)
10210 0 : t = integer_one_node;
10211 1661 : else if (!type_dependent_expression_p (t)
10212 1661 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10213 : {
10214 8 : error_at (OMP_CLAUSE_LOCATION (c),
10215 : "%<sizes%> argument needs positive integral "
10216 : "constant");
10217 8 : t = integer_one_node;
10218 : }
10219 : else
10220 : {
10221 1653 : t = mark_rvalue_use (t);
10222 1653 : if (!processing_template_decl)
10223 : {
10224 1636 : t = maybe_constant_value (t);
10225 1636 : HOST_WIDE_INT n;
10226 1636 : if (!tree_fits_shwi_p (t)
10227 1632 : || !INTEGRAL_TYPE_P (TREE_TYPE (t))
10228 1632 : || (n = tree_to_shwi (t)) <= 0
10229 3240 : || (int)n != n)
10230 : {
10231 32 : error_at (OMP_CLAUSE_LOCATION (c),
10232 : "%<sizes%> argument needs positive "
10233 : "integral constant");
10234 32 : t = integer_one_node;
10235 : }
10236 : }
10237 : }
10238 :
10239 : /* Update list item. */
10240 1661 : TREE_VALUE (list) = t;
10241 : }
10242 : break;
10243 :
10244 630 : case OMP_CLAUSE_ORDERED:
10245 630 : ordered_seen = true;
10246 630 : break;
10247 :
10248 1549 : case OMP_CLAUSE_ORDER:
10249 1549 : if (order_seen)
10250 : remove = true;
10251 : else
10252 : order_seen = true;
10253 : break;
10254 :
10255 638 : case OMP_CLAUSE_INBRANCH:
10256 638 : case OMP_CLAUSE_NOTINBRANCH:
10257 638 : if (branch_seen)
10258 : {
10259 3 : error_at (OMP_CLAUSE_LOCATION (c),
10260 : "%<inbranch%> clause is incompatible with "
10261 : "%<notinbranch%>");
10262 3 : remove = true;
10263 : }
10264 : branch_seen = true;
10265 : break;
10266 :
10267 306 : case OMP_CLAUSE_INCLUSIVE:
10268 306 : case OMP_CLAUSE_EXCLUSIVE:
10269 306 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10270 306 : if (!t)
10271 306 : t = OMP_CLAUSE_DECL (c);
10272 306 : if (t == current_class_ptr)
10273 : {
10274 0 : error_at (OMP_CLAUSE_LOCATION (c),
10275 : "%<this%> allowed in OpenMP only in %<declare simd%>"
10276 : " clauses");
10277 0 : remove = true;
10278 0 : break;
10279 : }
10280 306 : if (!VAR_P (t)
10281 : && TREE_CODE (t) != PARM_DECL
10282 : && TREE_CODE (t) != FIELD_DECL)
10283 : {
10284 0 : if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
10285 : break;
10286 0 : if (DECL_P (t))
10287 0 : error_at (OMP_CLAUSE_LOCATION (c),
10288 : "%qD is not a variable in clause %qs", t,
10289 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10290 : else
10291 0 : error_at (OMP_CLAUSE_LOCATION (c),
10292 : "%qE is not a variable in clause %qs", t,
10293 0 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10294 : remove = true;
10295 : }
10296 : break;
10297 :
10298 : case OMP_CLAUSE_FULL:
10299 : break;
10300 :
10301 470 : case OMP_CLAUSE_PARTIAL:
10302 470 : partial_seen = true;
10303 470 : t = OMP_CLAUSE_PARTIAL_EXPR (c);
10304 470 : if (!t)
10305 : break;
10306 :
10307 313 : if (t == error_mark_node)
10308 : t = NULL_TREE;
10309 313 : else if (!type_dependent_expression_p (t)
10310 313 : && !INTEGRAL_TYPE_P (TREE_TYPE (t)))
10311 : {
10312 3 : error_at (OMP_CLAUSE_LOCATION (c),
10313 : "%<partial%> argument needs positive constant "
10314 : "integer expression");
10315 3 : t = NULL_TREE;
10316 : }
10317 : else
10318 : {
10319 310 : t = mark_rvalue_use (t);
10320 310 : if (!processing_template_decl)
10321 : {
10322 292 : t = maybe_constant_value (t);
10323 :
10324 292 : HOST_WIDE_INT n;
10325 584 : if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
10326 292 : || !tree_fits_shwi_p (t)
10327 286 : || (n = tree_to_shwi (t)) <= 0
10328 560 : || (int)n != n)
10329 : {
10330 24 : error_at (OMP_CLAUSE_LOCATION (c),
10331 : "%<partial%> argument needs positive "
10332 : "constant integer expression");
10333 24 : t = NULL_TREE;
10334 : }
10335 : }
10336 : }
10337 :
10338 313 : OMP_CLAUSE_PARTIAL_EXPR (c) = t;
10339 313 : break;
10340 549 : case OMP_CLAUSE_INIT:
10341 549 : init_seen = true;
10342 549 : OMP_CLAUSE_INIT_PREFER_TYPE (c)
10343 549 : = cp_finish_omp_init_prefer_type (OMP_CLAUSE_INIT_PREFER_TYPE (c));
10344 549 : if (!OMP_CLAUSE_INIT_TARGETSYNC (c))
10345 271 : init_no_targetsync_clause = c;
10346 : /* FALLTHRU */
10347 844 : case OMP_CLAUSE_DESTROY:
10348 844 : case OMP_CLAUSE_USE:
10349 844 : init_use_destroy_seen = true;
10350 844 : t = OMP_CLAUSE_DECL (c);
10351 844 : if (bitmap_bit_p (&generic_head, DECL_UID (t)))
10352 : {
10353 9 : error_at (OMP_CLAUSE_LOCATION (c),
10354 : "%qD appears more than once in action clauses", t);
10355 9 : remove = true;
10356 9 : break;
10357 : }
10358 835 : bitmap_set_bit (&generic_head, DECL_UID (t));
10359 : /* FALLTHRU */
10360 1099 : case OMP_CLAUSE_INTEROP:
10361 1099 : if (!processing_template_decl)
10362 : {
10363 1003 : if (/* (ort == C_ORT_OMP_INTEROP [uncomment for depobj init]
10364 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INTEROP) && */
10365 1003 : !c_omp_interop_t_p (TREE_TYPE (OMP_CLAUSE_DECL (c))))
10366 : {
10367 126 : error_at (OMP_CLAUSE_LOCATION (c),
10368 : "%qD must be of %<omp_interop_t%>",
10369 63 : OMP_CLAUSE_DECL (c));
10370 63 : remove = true;
10371 : }
10372 940 : else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INIT
10373 481 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DESTROY)
10374 1058 : && TREE_READONLY (OMP_CLAUSE_DECL (c)))
10375 : {
10376 36 : error_at (OMP_CLAUSE_LOCATION (c),
10377 18 : "%qD shall not be const", OMP_CLAUSE_DECL (c));
10378 18 : remove = true;
10379 : }
10380 : }
10381 1099 : pc = &OMP_CLAUSE_CHAIN (c);
10382 1099 : break;
10383 0 : default:
10384 0 : gcc_unreachable ();
10385 55 : }
10386 :
10387 98524 : if (remove)
10388 : {
10389 2715 : if (grp_start_p)
10390 : {
10391 : /* If we found a clause to remove, we want to remove the whole
10392 : expanded group, otherwise gimplify
10393 : (omp_resolve_clause_dependencies) can get confused. */
10394 861 : *grp_start_p = grp_sentinel;
10395 861 : pc = grp_start_p;
10396 861 : grp_start_p = NULL;
10397 : }
10398 : else
10399 1854 : *pc = OMP_CLAUSE_CHAIN (c);
10400 : }
10401 : else
10402 95809 : pc = &OMP_CLAUSE_CHAIN (c);
10403 : }
10404 :
10405 63524 : if (grp_start_p
10406 63524 : && OMP_CLAUSE_HAS_ITERATORS (*grp_start_p))
10407 158 : for (tree gc = *grp_start_p; gc; gc = OMP_CLAUSE_CHAIN (gc))
10408 95 : OMP_CLAUSE_ITERATORS (gc) = OMP_CLAUSE_ITERATORS (*grp_start_p);
10409 :
10410 63524 : if (reduction_seen < 0 && (ordered_seen || schedule_seen))
10411 63524 : reduction_seen = -2;
10412 :
10413 160300 : for (pc = &clauses, c = clauses; c ; c = *pc)
10414 : {
10415 96776 : enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
10416 96776 : bool remove = false;
10417 96776 : bool need_complete_type = false;
10418 96776 : bool need_default_ctor = false;
10419 96776 : bool need_copy_ctor = false;
10420 96776 : bool need_copy_assignment = false;
10421 96776 : bool need_implicitly_determined = false;
10422 96776 : bool need_dtor = false;
10423 96776 : tree type, inner_type;
10424 :
10425 96776 : switch (c_kind)
10426 : {
10427 : case OMP_CLAUSE_SHARED:
10428 : need_implicitly_determined = true;
10429 : break;
10430 2550 : case OMP_CLAUSE_PRIVATE:
10431 2550 : need_complete_type = true;
10432 2550 : need_default_ctor = true;
10433 2550 : need_dtor = true;
10434 2550 : need_implicitly_determined = true;
10435 2550 : break;
10436 3169 : case OMP_CLAUSE_FIRSTPRIVATE:
10437 3169 : need_complete_type = true;
10438 3169 : need_copy_ctor = true;
10439 3169 : need_dtor = true;
10440 3169 : need_implicitly_determined = true;
10441 3169 : break;
10442 2766 : case OMP_CLAUSE_LASTPRIVATE:
10443 2766 : need_complete_type = true;
10444 2766 : need_copy_assignment = true;
10445 2766 : need_implicitly_determined = true;
10446 2766 : break;
10447 7497 : case OMP_CLAUSE_REDUCTION:
10448 7497 : if (reduction_seen == -2)
10449 27 : OMP_CLAUSE_REDUCTION_INSCAN (c) = 0;
10450 7497 : if (OMP_CLAUSE_REDUCTION_INSCAN (c))
10451 436 : need_copy_assignment = true;
10452 : need_implicitly_determined = true;
10453 : break;
10454 : case OMP_CLAUSE_IN_REDUCTION:
10455 : case OMP_CLAUSE_TASK_REDUCTION:
10456 : case OMP_CLAUSE_INCLUSIVE:
10457 : case OMP_CLAUSE_EXCLUSIVE:
10458 : need_implicitly_determined = true;
10459 : break;
10460 1550 : case OMP_CLAUSE_LINEAR:
10461 1550 : if (ort != C_ORT_OMP_DECLARE_SIMD)
10462 : need_implicitly_determined = true;
10463 679 : else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
10464 721 : && !bitmap_bit_p (&map_head,
10465 42 : DECL_UID (OMP_CLAUSE_LINEAR_STEP (c))))
10466 : {
10467 6 : error_at (OMP_CLAUSE_LOCATION (c),
10468 : "%<linear%> clause step is a parameter %qD not "
10469 : "specified in %<uniform%> clause",
10470 6 : OMP_CLAUSE_LINEAR_STEP (c));
10471 6 : *pc = OMP_CLAUSE_CHAIN (c);
10472 75043 : continue;
10473 : }
10474 : break;
10475 : case OMP_CLAUSE_COPYPRIVATE:
10476 369 : need_copy_assignment = true;
10477 : break;
10478 : case OMP_CLAUSE_COPYIN:
10479 369 : need_copy_assignment = true;
10480 : break;
10481 798 : case OMP_CLAUSE_SIMDLEN:
10482 798 : if (safelen
10483 345 : && !processing_template_decl
10484 1143 : && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen),
10485 345 : OMP_CLAUSE_SIMDLEN_EXPR (c)))
10486 : {
10487 0 : error_at (OMP_CLAUSE_LOCATION (c),
10488 : "%<simdlen%> clause value is bigger than "
10489 : "%<safelen%> clause value");
10490 0 : OMP_CLAUSE_SIMDLEN_EXPR (c)
10491 0 : = OMP_CLAUSE_SAFELEN_EXPR (safelen);
10492 : }
10493 798 : pc = &OMP_CLAUSE_CHAIN (c);
10494 798 : continue;
10495 3883 : case OMP_CLAUSE_SCHEDULE:
10496 3883 : if (ordered_seen
10497 3883 : && (OMP_CLAUSE_SCHEDULE_KIND (c)
10498 : & OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
10499 : {
10500 21 : error_at (OMP_CLAUSE_LOCATION (c),
10501 : "%<nonmonotonic%> schedule modifier specified "
10502 : "together with %<ordered%> clause");
10503 42 : OMP_CLAUSE_SCHEDULE_KIND (c)
10504 21 : = (enum omp_clause_schedule_kind)
10505 21 : (OMP_CLAUSE_SCHEDULE_KIND (c)
10506 : & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC);
10507 : }
10508 3883 : if (reduction_seen == -2)
10509 9 : error_at (OMP_CLAUSE_LOCATION (c),
10510 : "%qs clause specified together with %<inscan%> "
10511 : "%<reduction%> clause", "schedule");
10512 3883 : pc = &OMP_CLAUSE_CHAIN (c);
10513 3883 : continue;
10514 51 : case OMP_CLAUSE_NOGROUP:
10515 51 : if (reduction_seen)
10516 : {
10517 3 : error_at (OMP_CLAUSE_LOCATION (c),
10518 : "%<nogroup%> clause must not be used together with "
10519 : "%<reduction%> clause");
10520 3 : *pc = OMP_CLAUSE_CHAIN (c);
10521 3 : continue;
10522 : }
10523 48 : pc = &OMP_CLAUSE_CHAIN (c);
10524 48 : continue;
10525 165 : case OMP_CLAUSE_GRAINSIZE:
10526 165 : if (num_tasks_seen)
10527 : {
10528 6 : error_at (OMP_CLAUSE_LOCATION (c),
10529 : "%<grainsize%> clause must not be used together with "
10530 : "%<num_tasks%> clause");
10531 6 : *pc = OMP_CLAUSE_CHAIN (c);
10532 6 : continue;
10533 : }
10534 159 : pc = &OMP_CLAUSE_CHAIN (c);
10535 159 : continue;
10536 630 : case OMP_CLAUSE_ORDERED:
10537 630 : if (reduction_seen == -2)
10538 6 : error_at (OMP_CLAUSE_LOCATION (c),
10539 : "%qs clause specified together with %<inscan%> "
10540 : "%<reduction%> clause", "ordered");
10541 630 : pc = &OMP_CLAUSE_CHAIN (c);
10542 630 : continue;
10543 1525 : case OMP_CLAUSE_ORDER:
10544 1525 : if (ordered_seen)
10545 : {
10546 12 : error_at (OMP_CLAUSE_LOCATION (c),
10547 : "%<order%> clause must not be used together "
10548 : "with %<ordered%> clause");
10549 12 : *pc = OMP_CLAUSE_CHAIN (c);
10550 12 : continue;
10551 : }
10552 1513 : pc = &OMP_CLAUSE_CHAIN (c);
10553 1513 : continue;
10554 57 : case OMP_CLAUSE_DETACH:
10555 57 : if (mergeable_seen)
10556 : {
10557 6 : error_at (OMP_CLAUSE_LOCATION (c),
10558 : "%<detach%> clause must not be used together with "
10559 : "%<mergeable%> clause");
10560 6 : *pc = OMP_CLAUSE_CHAIN (c);
10561 6 : continue;
10562 : }
10563 51 : pc = &OMP_CLAUSE_CHAIN (c);
10564 51 : continue;
10565 16103 : case OMP_CLAUSE_MAP:
10566 16103 : if (target_in_reduction_seen && !processing_template_decl)
10567 : {
10568 684 : t = OMP_CLAUSE_DECL (c);
10569 684 : while (handled_component_p (t)
10570 : || INDIRECT_REF_P (t)
10571 : || TREE_CODE (t) == ADDR_EXPR
10572 : || TREE_CODE (t) == MEM_REF
10573 804 : || TREE_CODE (t) == NON_LVALUE_EXPR)
10574 120 : t = TREE_OPERAND (t, 0);
10575 684 : if (DECL_P (t)
10576 684 : && bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
10577 342 : OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1;
10578 : }
10579 16103 : pc = &OMP_CLAUSE_CHAIN (c);
10580 16103 : continue;
10581 225 : case OMP_CLAUSE_FULL:
10582 225 : if (partial_seen)
10583 : {
10584 12 : error_at (OMP_CLAUSE_LOCATION (c),
10585 : "%<full%> clause must not be used together "
10586 : "with %<partial%> clause");
10587 12 : *pc = OMP_CLAUSE_CHAIN (c);
10588 12 : continue;
10589 : }
10590 213 : pc = &OMP_CLAUSE_CHAIN (c);
10591 213 : continue;
10592 6952 : case OMP_CLAUSE_NOWAIT:
10593 6952 : if (copyprivate_seen)
10594 : {
10595 6 : error_at (OMP_CLAUSE_LOCATION (c),
10596 : "%<nowait%> clause must not be used together "
10597 : "with %<copyprivate%> clause");
10598 6 : *pc = OMP_CLAUSE_CHAIN (c);
10599 6 : continue;
10600 : }
10601 : /* FALLTHRU */
10602 50914 : default:
10603 50914 : pc = &OMP_CLAUSE_CHAIN (c);
10604 50914 : continue;
10605 : }
10606 :
10607 22413 : t = OMP_CLAUSE_DECL (c);
10608 22413 : switch (c_kind)
10609 : {
10610 2766 : case OMP_CLAUSE_LASTPRIVATE:
10611 2766 : if (DECL_P (t)
10612 2766 : && !bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
10613 : {
10614 2666 : need_default_ctor = true;
10615 2666 : need_dtor = true;
10616 : }
10617 : break;
10618 :
10619 9636 : case OMP_CLAUSE_REDUCTION:
10620 9636 : case OMP_CLAUSE_IN_REDUCTION:
10621 9636 : case OMP_CLAUSE_TASK_REDUCTION:
10622 9636 : if (allocate_seen)
10623 : {
10624 1711 : if (TREE_CODE (t) == MEM_REF)
10625 : {
10626 222 : t = TREE_OPERAND (t, 0);
10627 222 : if (TREE_CODE (t) == POINTER_PLUS_EXPR)
10628 0 : t = TREE_OPERAND (t, 0);
10629 222 : if (TREE_CODE (t) == ADDR_EXPR
10630 168 : || INDIRECT_REF_P (t))
10631 110 : t = TREE_OPERAND (t, 0);
10632 222 : if (DECL_P (t))
10633 222 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10634 : }
10635 1489 : else if (TREE_CODE (t) == OMP_ARRAY_SECTION)
10636 : {
10637 288 : while (TREE_CODE (t) == OMP_ARRAY_SECTION)
10638 144 : t = TREE_OPERAND (t, 0);
10639 144 : if (DECL_P (t))
10640 144 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10641 144 : t = OMP_CLAUSE_DECL (c);
10642 : }
10643 1345 : else if (DECL_P (t))
10644 1345 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10645 1711 : t = OMP_CLAUSE_DECL (c);
10646 : }
10647 9636 : if (processing_template_decl
10648 929 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10649 : break;
10650 9018 : if (finish_omp_reduction_clause (c, &need_default_ctor,
10651 : &need_dtor))
10652 : remove = true;
10653 : else
10654 8934 : t = OMP_CLAUSE_DECL (c);
10655 : break;
10656 :
10657 277 : case OMP_CLAUSE_COPYIN:
10658 277 : if (processing_template_decl
10659 0 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10660 : break;
10661 277 : if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t))
10662 : {
10663 15 : error_at (OMP_CLAUSE_LOCATION (c),
10664 : "%qE must be %<threadprivate%> for %<copyin%>", t);
10665 15 : remove = true;
10666 : }
10667 : break;
10668 :
10669 : default:
10670 : break;
10671 : }
10672 :
10673 22413 : if (processing_template_decl
10674 1610 : && !VAR_P (t) && TREE_CODE (t) != PARM_DECL)
10675 : {
10676 680 : pc = &OMP_CLAUSE_CHAIN (c);
10677 680 : continue;
10678 : }
10679 :
10680 21733 : if (need_complete_type || need_copy_assignment)
10681 : {
10682 9234 : t = require_complete_type (t);
10683 9234 : if (t == error_mark_node)
10684 : remove = true;
10685 9210 : else if (!processing_template_decl
10686 8827 : && TYPE_REF_P (TREE_TYPE (t))
10687 9766 : && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t))
10688 : remove = true;
10689 : }
10690 21733 : if (need_implicitly_determined)
10691 : {
10692 20692 : const char *share_name = NULL;
10693 :
10694 20692 : if (allocate_seen
10695 5114 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10696 24927 : && DECL_P (t))
10697 3950 : bitmap_clear_bit (&aligned_head, DECL_UID (t));
10698 :
10699 20692 : if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t))
10700 : share_name = "threadprivate";
10701 20650 : else switch (cxx_omp_predetermined_sharing_1 (t))
10702 : {
10703 : case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
10704 : break;
10705 47 : case OMP_CLAUSE_DEFAULT_SHARED:
10706 47 : if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10707 30 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
10708 64 : && c_omp_predefined_variable (t))
10709 : /* The __func__ variable and similar function-local predefined
10710 : variables may be listed in a shared or firstprivate
10711 : clause. */
10712 : break;
10713 31 : if (VAR_P (t)
10714 31 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10715 9 : && TREE_STATIC (t)
10716 40 : && cxx_omp_const_qual_no_mutable (t))
10717 : {
10718 6 : tree ctx = CP_DECL_CONTEXT (t);
10719 : /* const qualified static data members without mutable
10720 : member may be specified in firstprivate clause. */
10721 6 : if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
10722 : break;
10723 : }
10724 : share_name = "shared";
10725 : break;
10726 : case OMP_CLAUSE_DEFAULT_PRIVATE:
10727 : share_name = "private";
10728 : break;
10729 0 : default:
10730 0 : gcc_unreachable ();
10731 : }
10732 : if (share_name)
10733 : {
10734 67 : error_at (OMP_CLAUSE_LOCATION (c),
10735 : "%qE is predetermined %qs for %qs",
10736 : omp_clause_printable_decl (t), share_name,
10737 67 : omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
10738 67 : remove = true;
10739 : }
10740 20625 : else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
10741 18566 : && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
10742 36051 : && cxx_omp_const_qual_no_mutable (t))
10743 : {
10744 126 : error_at (OMP_CLAUSE_LOCATION (c),
10745 : "%<const%> qualified %qE without %<mutable%> member "
10746 : "may appear only in %<shared%> or %<firstprivate%> "
10747 : "clauses", omp_clause_printable_decl (t));
10748 63 : remove = true;
10749 : }
10750 : }
10751 :
10752 21733 : if (detach_seen
10753 16 : && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
10754 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
10755 10 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
10756 0 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
10757 21749 : && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen))
10758 : {
10759 6 : error_at (OMP_CLAUSE_LOCATION (c),
10760 : "the event handle of a %<detach%> clause "
10761 : "should not be in a data-sharing clause");
10762 6 : remove = true;
10763 : }
10764 :
10765 : /* We're interested in the base element, not arrays. */
10766 21733 : inner_type = type = TREE_TYPE (t);
10767 21733 : if ((need_complete_type
10768 : || need_copy_assignment
10769 12499 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
10770 5717 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION
10771 4244 : || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)
10772 30315 : && TYPE_REF_P (inner_type))
10773 899 : inner_type = TREE_TYPE (inner_type);
10774 24411 : while (TREE_CODE (inner_type) == ARRAY_TYPE)
10775 2678 : inner_type = TREE_TYPE (inner_type);
10776 :
10777 : /* Check for special function availability by building a call to one.
10778 : Save the results, because later we won't be in the right context
10779 : for making these queries. */
10780 2397 : if (CLASS_TYPE_P (inner_type)
10781 2397 : && COMPLETE_TYPE_P (inner_type)
10782 2328 : && (need_default_ctor || need_copy_ctor
10783 1091 : || need_copy_assignment || need_dtor)
10784 2004 : && !type_dependent_expression_p (t)
10785 23737 : && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
10786 : need_copy_ctor, need_copy_assignment,
10787 : need_dtor))
10788 : remove = true;
10789 :
10790 21733 : if (!remove
10791 21733 : && c_kind == OMP_CLAUSE_SHARED
10792 2056 : && processing_template_decl)
10793 : {
10794 125 : t = omp_clause_decl_field (OMP_CLAUSE_DECL (c));
10795 125 : if (t)
10796 5 : OMP_CLAUSE_DECL (c) = t;
10797 : }
10798 :
10799 21733 : if (remove)
10800 292 : *pc = OMP_CLAUSE_CHAIN (c);
10801 : else
10802 21441 : pc = &OMP_CLAUSE_CHAIN (c);
10803 : }
10804 :
10805 63524 : if (allocate_seen)
10806 17449 : for (pc = &clauses, c = clauses; c ; c = *pc)
10807 : {
10808 14948 : bool remove = false;
10809 14948 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE
10810 2764 : && !OMP_CLAUSE_ALLOCATE_COMBINED (c)
10811 2312 : && DECL_P (OMP_CLAUSE_DECL (c))
10812 17260 : && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c))))
10813 : {
10814 15 : error_at (OMP_CLAUSE_LOCATION (c),
10815 : "%qD specified in %<allocate%> clause but not in "
10816 15 : "an explicit privatization clause", OMP_CLAUSE_DECL (c));
10817 15 : remove = true;
10818 : }
10819 14948 : if (remove)
10820 15 : *pc = OMP_CLAUSE_CHAIN (c);
10821 : else
10822 14933 : pc = &OMP_CLAUSE_CHAIN (c);
10823 : }
10824 :
10825 63524 : if (ort == C_ORT_OMP_INTEROP
10826 63524 : && depend_clause
10827 60 : && (!init_use_destroy_seen
10828 57 : || (init_seen && init_no_targetsync_clause)))
10829 : {
10830 9 : auto_diagnostic_group d;
10831 9 : error_at (OMP_CLAUSE_LOCATION (depend_clause),
10832 : "%<depend%> clause requires action clauses with "
10833 : "%<targetsync%> interop-type");
10834 9 : if (init_no_targetsync_clause)
10835 6 : inform (OMP_CLAUSE_LOCATION (init_no_targetsync_clause),
10836 : "%<init%> clause lacks the %<targetsync%> modifier");
10837 9 : }
10838 :
10839 63524 : bitmap_obstack_release (NULL);
10840 63524 : return clauses;
10841 : }
10842 :
10843 : /* Start processing OpenMP clauses that can include any
10844 : privatization clauses for non-static data members. */
10845 :
10846 : tree
10847 49209 : push_omp_privatization_clauses (bool ignore_next)
10848 : {
10849 49209 : if (omp_private_member_ignore_next)
10850 : {
10851 722 : omp_private_member_ignore_next = ignore_next;
10852 722 : return NULL_TREE;
10853 : }
10854 48487 : omp_private_member_ignore_next = ignore_next;
10855 48487 : if (omp_private_member_map)
10856 24 : omp_private_member_vec.safe_push (error_mark_node);
10857 48487 : return push_stmt_list ();
10858 : }
10859 :
10860 : /* Revert remapping of any non-static data members since
10861 : the last push_omp_privatization_clauses () call. */
10862 :
10863 : void
10864 49203 : pop_omp_privatization_clauses (tree stmt)
10865 : {
10866 49203 : if (stmt == NULL_TREE)
10867 : return;
10868 48481 : stmt = pop_stmt_list (stmt);
10869 48481 : if (omp_private_member_map)
10870 : {
10871 1280 : while (!omp_private_member_vec.is_empty ())
10872 : {
10873 850 : tree t = omp_private_member_vec.pop ();
10874 850 : if (t == error_mark_node)
10875 : {
10876 24 : add_stmt (stmt);
10877 24 : return;
10878 : }
10879 826 : bool no_decl_expr = t == integer_zero_node;
10880 826 : if (no_decl_expr)
10881 136 : t = omp_private_member_vec.pop ();
10882 826 : tree *v = omp_private_member_map->get (t);
10883 826 : gcc_assert (v);
10884 826 : if (!no_decl_expr)
10885 690 : add_decl_expr (*v);
10886 826 : omp_private_member_map->remove (t);
10887 : }
10888 860 : delete omp_private_member_map;
10889 430 : omp_private_member_map = NULL;
10890 : }
10891 48457 : add_stmt (stmt);
10892 : }
10893 :
10894 : /* Remember OpenMP privatization clauses mapping and clear it.
10895 : Used for lambdas. */
10896 :
10897 : void
10898 16483232 : save_omp_privatization_clauses (vec<tree> &save)
10899 : {
10900 16483232 : save = vNULL;
10901 16483232 : if (omp_private_member_ignore_next)
10902 2 : save.safe_push (integer_one_node);
10903 16483232 : omp_private_member_ignore_next = false;
10904 16483232 : if (!omp_private_member_map)
10905 : return;
10906 :
10907 0 : while (!omp_private_member_vec.is_empty ())
10908 : {
10909 0 : tree t = omp_private_member_vec.pop ();
10910 0 : if (t == error_mark_node)
10911 : {
10912 0 : save.safe_push (t);
10913 0 : continue;
10914 : }
10915 0 : tree n = t;
10916 0 : if (t == integer_zero_node)
10917 0 : t = omp_private_member_vec.pop ();
10918 0 : tree *v = omp_private_member_map->get (t);
10919 0 : gcc_assert (v);
10920 0 : save.safe_push (*v);
10921 0 : save.safe_push (t);
10922 0 : if (n != t)
10923 0 : save.safe_push (n);
10924 : }
10925 0 : delete omp_private_member_map;
10926 0 : omp_private_member_map = NULL;
10927 : }
10928 :
10929 : /* Restore OpenMP privatization clauses mapping saved by the
10930 : above function. */
10931 :
10932 : void
10933 16483232 : restore_omp_privatization_clauses (vec<tree> &save)
10934 : {
10935 16483232 : gcc_assert (omp_private_member_vec.is_empty ());
10936 16483232 : omp_private_member_ignore_next = false;
10937 16483232 : if (save.is_empty ())
10938 : return;
10939 4 : if (save.length () == 1 && save[0] == integer_one_node)
10940 : {
10941 2 : omp_private_member_ignore_next = true;
10942 2 : save.release ();
10943 2 : return;
10944 : }
10945 :
10946 0 : omp_private_member_map = new hash_map <tree, tree>;
10947 0 : while (!save.is_empty ())
10948 : {
10949 0 : tree t = save.pop ();
10950 0 : tree n = t;
10951 0 : if (t != error_mark_node)
10952 : {
10953 0 : if (t == integer_one_node)
10954 : {
10955 0 : omp_private_member_ignore_next = true;
10956 0 : gcc_assert (save.is_empty ());
10957 0 : break;
10958 : }
10959 0 : if (t == integer_zero_node)
10960 0 : t = save.pop ();
10961 0 : tree &v = omp_private_member_map->get_or_insert (t);
10962 0 : v = save.pop ();
10963 : }
10964 0 : omp_private_member_vec.safe_push (t);
10965 0 : if (n != t)
10966 0 : omp_private_member_vec.safe_push (n);
10967 : }
10968 0 : save.release ();
10969 : }
10970 :
10971 : /* For all variables in the tree_list VARS, mark them as thread local. */
10972 :
10973 : void
10974 244 : finish_omp_threadprivate (tree vars)
10975 : {
10976 244 : tree t;
10977 :
10978 : /* Mark every variable in VARS to be assigned thread local storage. */
10979 521 : for (t = vars; t; t = TREE_CHAIN (t))
10980 : {
10981 277 : tree v = TREE_PURPOSE (t);
10982 277 : location_t loc = EXPR_LOCATION (TREE_VALUE (t));
10983 :
10984 277 : if (error_operand_p (v))
10985 : ;
10986 277 : else if (!VAR_P (v))
10987 6 : error_at (loc, "%<threadprivate%> %qD is not file, namespace "
10988 : "or block scope variable", v);
10989 : /* If V had already been marked threadprivate, it doesn't matter
10990 : whether it had been used prior to this point. */
10991 271 : else if (TREE_USED (v)
10992 271 : && (DECL_LANG_SPECIFIC (v) == NULL
10993 3 : || !CP_DECL_THREADPRIVATE_P (v)))
10994 6 : error_at (loc, "%qE declared %<threadprivate%> after first use", v);
10995 265 : else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
10996 6 : error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
10997 259 : else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v))))
10998 3 : error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
10999 207 : else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v))
11000 279 : && CP_DECL_CONTEXT (v) != current_class_type)
11001 6 : error_at (loc, "%<threadprivate%> %qE directive not "
11002 6 : "in %qT definition", v, CP_DECL_CONTEXT (v));
11003 : else
11004 : {
11005 : /* Allocate a LANG_SPECIFIC structure for V, if needed. */
11006 250 : if (DECL_LANG_SPECIFIC (v) == NULL)
11007 206 : retrofit_lang_decl (v);
11008 :
11009 250 : if (! CP_DECL_THREAD_LOCAL_P (v))
11010 : {
11011 250 : CP_DECL_THREAD_LOCAL_P (v) = true;
11012 250 : set_decl_tls_model (v, decl_default_tls_model (v));
11013 : /* If rtl has been already set for this var, call
11014 : make_decl_rtl once again, so that encode_section_info
11015 : has a chance to look at the new decl flags. */
11016 250 : if (DECL_RTL_SET_P (v))
11017 0 : make_decl_rtl (v);
11018 : }
11019 250 : CP_DECL_THREADPRIVATE_P (v) = 1;
11020 : }
11021 : }
11022 244 : }
11023 :
11024 : /* Build an OpenMP structured block. */
11025 :
11026 : tree
11027 64723 : begin_omp_structured_block (void)
11028 : {
11029 64723 : return do_pushlevel (sk_omp);
11030 : }
11031 :
11032 : tree
11033 64708 : finish_omp_structured_block (tree block)
11034 : {
11035 64708 : return do_poplevel (block);
11036 : }
11037 :
11038 : /* Similarly, except force the retention of the BLOCK. */
11039 :
11040 : tree
11041 14970 : begin_omp_parallel (void)
11042 : {
11043 14970 : keep_next_level (true);
11044 14970 : return begin_omp_structured_block ();
11045 : }
11046 :
11047 : /* Generate OACC_DATA, with CLAUSES and BLOCK as its compound
11048 : statement. */
11049 :
11050 : tree
11051 768 : finish_oacc_data (tree clauses, tree block)
11052 : {
11053 768 : tree stmt;
11054 :
11055 768 : block = finish_omp_structured_block (block);
11056 :
11057 768 : stmt = make_node (OACC_DATA);
11058 768 : TREE_TYPE (stmt) = void_type_node;
11059 768 : OACC_DATA_CLAUSES (stmt) = clauses;
11060 768 : OACC_DATA_BODY (stmt) = block;
11061 :
11062 768 : return add_stmt (stmt);
11063 : }
11064 :
11065 : /* Generate OACC_HOST_DATA, with CLAUSES and BLOCK as its compound
11066 : statement. */
11067 :
11068 : tree
11069 55 : finish_oacc_host_data (tree clauses, tree block)
11070 : {
11071 55 : tree stmt;
11072 :
11073 55 : block = finish_omp_structured_block (block);
11074 :
11075 55 : stmt = make_node (OACC_HOST_DATA);
11076 55 : TREE_TYPE (stmt) = void_type_node;
11077 55 : OACC_HOST_DATA_CLAUSES (stmt) = clauses;
11078 55 : OACC_HOST_DATA_BODY (stmt) = block;
11079 :
11080 55 : return add_stmt (stmt);
11081 : }
11082 :
11083 : /* Generate OMP construct CODE, with BODY and CLAUSES as its compound
11084 : statement. */
11085 :
11086 : tree
11087 4689 : finish_omp_construct (enum tree_code code, tree body, tree clauses)
11088 : {
11089 4689 : body = finish_omp_structured_block (body);
11090 :
11091 4689 : tree stmt = make_node (code);
11092 4689 : TREE_TYPE (stmt) = void_type_node;
11093 4689 : OMP_BODY (stmt) = body;
11094 4689 : OMP_CLAUSES (stmt) = clauses;
11095 :
11096 4689 : return add_stmt (stmt);
11097 : }
11098 :
11099 : /* Used to walk OpenMP target directive body. */
11100 :
11101 : struct omp_target_walk_data
11102 : {
11103 : /* Holds the 'this' expression found in current function. */
11104 : tree current_object;
11105 :
11106 : /* True if the 'this' expression was accessed in the target body. */
11107 : bool this_expr_accessed;
11108 :
11109 : /* For non-static functions, record which pointer-typed members were
11110 : accessed, and the whole expression. */
11111 : hash_map<tree, tree> ptr_members_accessed;
11112 :
11113 : /* Record which lambda objects were accessed in target body. */
11114 : hash_set<tree> lambda_objects_accessed;
11115 :
11116 : /* For lambda functions, the __closure object expression of the current
11117 : function, and the set of captured variables accessed in target body. */
11118 : tree current_closure;
11119 : hash_set<tree> closure_vars_accessed;
11120 :
11121 : /* Local variables declared inside a BIND_EXPR, used to filter out such
11122 : variables when recording lambda_objects_accessed. */
11123 : hash_set<tree> local_decls;
11124 :
11125 : omp_mapper_list<tree> *mappers;
11126 : };
11127 :
11128 : /* Helper function of finish_omp_target_clauses, called via
11129 : cp_walk_tree_without_duplicates. Traverse body of OpenMP target
11130 : directive *TP, and fill out omp_target_walk_data passed in *PTR. */
11131 :
11132 : static tree
11133 228984 : finish_omp_target_clauses_r (tree *tp, int *walk_subtrees, void *ptr)
11134 : {
11135 228984 : tree t = *tp;
11136 228984 : struct omp_target_walk_data *data = (struct omp_target_walk_data *) ptr;
11137 228984 : tree current_object = data->current_object;
11138 228984 : tree current_closure = data->current_closure;
11139 228984 : omp_mapper_list<tree> *mlist = data->mappers;
11140 :
11141 : /* References inside of these expression codes shouldn't incur any
11142 : form of mapping, so return early. */
11143 228984 : if (TREE_CODE (t) == SIZEOF_EXPR
11144 228976 : || TREE_CODE (t) == ALIGNOF_EXPR)
11145 : {
11146 8 : *walk_subtrees = 0;
11147 8 : return NULL_TREE;
11148 : }
11149 :
11150 228976 : if (TREE_CODE (t) == OMP_CLAUSE)
11151 : return NULL_TREE;
11152 :
11153 216378 : if (!processing_template_decl)
11154 : {
11155 216378 : tree aggr_type = NULL_TREE;
11156 :
11157 216378 : if (TREE_CODE (t) == COMPONENT_REF
11158 216378 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
11159 2257 : aggr_type = TREE_TYPE (TREE_OPERAND (t, 0));
11160 214121 : else if ((TREE_CODE (t) == VAR_DECL
11161 : || TREE_CODE (t) == PARM_DECL
11162 : || TREE_CODE (t) == RESULT_DECL)
11163 17004 : && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
11164 1216 : aggr_type = TREE_TYPE (t);
11165 :
11166 3473 : if (aggr_type)
11167 : {
11168 3473 : tree mapper_fn = cxx_omp_mapper_lookup (NULL_TREE, aggr_type);
11169 3473 : if (mapper_fn)
11170 199 : mlist->add_mapper (NULL_TREE, aggr_type, mapper_fn);
11171 : }
11172 : }
11173 :
11174 216378 : if (current_object)
11175 : {
11176 2565 : tree this_expr = TREE_OPERAND (current_object, 0);
11177 :
11178 2565 : if (operand_equal_p (t, this_expr))
11179 : {
11180 35 : data->this_expr_accessed = true;
11181 35 : *walk_subtrees = 0;
11182 35 : return NULL_TREE;
11183 : }
11184 :
11185 2530 : if (TREE_CODE (t) == COMPONENT_REF
11186 115 : && POINTER_TYPE_P (TREE_TYPE (t))
11187 36 : && operand_equal_p (TREE_OPERAND (t, 0), current_object)
11188 2564 : && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL)
11189 : {
11190 34 : data->this_expr_accessed = true;
11191 34 : tree fld = TREE_OPERAND (t, 1);
11192 34 : if (data->ptr_members_accessed.get (fld) == NULL)
11193 : {
11194 14 : if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
11195 4 : t = convert_from_reference (t);
11196 14 : data->ptr_members_accessed.put (fld, t);
11197 : }
11198 34 : *walk_subtrees = 0;
11199 34 : return NULL_TREE;
11200 : }
11201 : }
11202 :
11203 : /* When the current_function_decl is a lambda function, the closure object
11204 : argument's type seems to not yet have fields laid out, so a recording
11205 : of DECL_VALUE_EXPRs during the target body walk seems the only way to
11206 : find them. */
11207 216309 : if (current_closure
11208 301 : && (VAR_P (t)
11209 : || TREE_CODE (t) == PARM_DECL
11210 : || TREE_CODE (t) == RESULT_DECL)
11211 24 : && DECL_HAS_VALUE_EXPR_P (t)
11212 10 : && TREE_CODE (DECL_VALUE_EXPR (t)) == COMPONENT_REF
11213 216319 : && operand_equal_p (current_closure,
11214 10 : TREE_OPERAND (DECL_VALUE_EXPR (t), 0)))
11215 : {
11216 9 : if (!data->closure_vars_accessed.contains (t))
11217 9 : data->closure_vars_accessed.add (t);
11218 9 : *walk_subtrees = 0;
11219 9 : return NULL_TREE;
11220 : }
11221 :
11222 216300 : if (TREE_CODE (t) == BIND_EXPR)
11223 : {
11224 20020 : if (tree block = BIND_EXPR_BLOCK (t))
11225 22476 : for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
11226 2460 : if (!data->local_decls.contains (var))
11227 2460 : data->local_decls.add (var);
11228 : return NULL_TREE;
11229 : }
11230 :
11231 200883 : if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
11232 : {
11233 39 : tree lt = TREE_TYPE (t);
11234 39 : gcc_assert (CLASS_TYPE_P (lt));
11235 :
11236 39 : if (!data->lambda_objects_accessed.contains (t)
11237 : /* Do not prepare to create target maps for locally declared
11238 : lambdas or anonymous ones. */
11239 39 : && !data->local_decls.contains (t)
11240 72 : && TREE_CODE (t) != TARGET_EXPR)
11241 13 : data->lambda_objects_accessed.add (t);
11242 39 : *walk_subtrees = 0;
11243 39 : return NULL_TREE;
11244 : }
11245 :
11246 : return NULL_TREE;
11247 : }
11248 :
11249 : /* Helper function for finish_omp_target, and also from tsubst_expr.
11250 : Create additional clauses for mapping of non-static members, lambda objects,
11251 : etc. */
11252 :
11253 : void
11254 6967 : finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr)
11255 : {
11256 6967 : omp_target_walk_data data;
11257 6967 : data.this_expr_accessed = false;
11258 6967 : data.current_object = NULL_TREE;
11259 :
11260 6967 : if (DECL_NONSTATIC_MEMBER_P (current_function_decl) && current_class_ptr)
11261 96 : if (tree ct = current_nonlambda_class_type ())
11262 : {
11263 95 : tree object = maybe_dummy_object (ct, NULL);
11264 95 : object = maybe_resolve_dummy (object, true);
11265 95 : data.current_object = object;
11266 : }
11267 :
11268 6967 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11269 : {
11270 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11271 8 : data.current_closure = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11272 : }
11273 : else
11274 : data.current_closure = NULL_TREE;
11275 :
11276 6967 : auto_vec<tree, 16> new_clauses;
11277 :
11278 6967 : if (!processing_template_decl)
11279 : {
11280 6967 : hash_set<omp_name_type<tree> > seen_types;
11281 6967 : auto_vec<tree> mapper_fns;
11282 6967 : omp_mapper_list<tree> mlist (&seen_types, &mapper_fns);
11283 6967 : data.mappers = &mlist;
11284 :
11285 6967 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11286 : &data);
11287 :
11288 6967 : unsigned int i;
11289 6967 : tree mapper_fn;
11290 14027 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11291 93 : c_omp_find_nested_mappers (&mlist, mapper_fn);
11292 :
11293 7130 : FOR_EACH_VEC_ELT (mapper_fns, i, mapper_fn)
11294 : {
11295 93 : tree mapper = cxx_omp_extract_mapper_directive (mapper_fn);
11296 93 : if (mapper == error_mark_node)
11297 0 : continue;
11298 93 : tree mapper_name = OMP_DECLARE_MAPPER_ID (mapper);
11299 93 : tree decl = OMP_DECLARE_MAPPER_DECL (mapper);
11300 93 : if (BASELINK_P (mapper_fn))
11301 0 : mapper_fn = BASELINK_FUNCTIONS (mapper_fn);
11302 :
11303 93 : tree c = build_omp_clause (loc, OMP_CLAUSE__MAPPER_BINDING_);
11304 93 : OMP_CLAUSE__MAPPER_BINDING__ID (c) = mapper_name;
11305 93 : OMP_CLAUSE__MAPPER_BINDING__DECL (c) = decl;
11306 93 : OMP_CLAUSE__MAPPER_BINDING__MAPPER (c) = mapper_fn;
11307 :
11308 93 : new_clauses.safe_push (c);
11309 : }
11310 6967 : }
11311 : else
11312 : {
11313 0 : data.mappers = NULL;
11314 0 : cp_walk_tree_without_duplicates (&body, finish_omp_target_clauses_r,
11315 : &data);
11316 : }
11317 :
11318 6967 : tree omp_target_this_expr = NULL_TREE;
11319 6967 : tree *explicit_this_deref_map = NULL;
11320 6967 : if (data.this_expr_accessed)
11321 : {
11322 31 : omp_target_this_expr = TREE_OPERAND (data.current_object, 0);
11323 :
11324 : /* See if explicit user-specified map(this[:]) clause already exists.
11325 : If not, we create an implicit map(tofrom:this[:1]) clause. */
11326 80 : for (tree *cp = clauses_ptr; *cp; cp = &OMP_CLAUSE_CHAIN (*cp))
11327 50 : if (OMP_CLAUSE_CODE (*cp) == OMP_CLAUSE_MAP
11328 47 : && (TREE_CODE (OMP_CLAUSE_DECL (*cp)) == INDIRECT_REF
11329 40 : || TREE_CODE (OMP_CLAUSE_DECL (*cp)) == MEM_REF)
11330 57 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*cp), 0),
11331 : omp_target_this_expr))
11332 : {
11333 : explicit_this_deref_map = cp;
11334 : break;
11335 : }
11336 : }
11337 :
11338 6967 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11339 6967 : && (data.this_expr_accessed
11340 1 : || !data.closure_vars_accessed.is_empty ()))
11341 : {
11342 : /* For lambda functions, we need to first create a copy of the
11343 : __closure object. */
11344 8 : tree closure = DECL_ARGUMENTS (current_function_decl);
11345 8 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11346 8 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TO);
11347 8 : OMP_CLAUSE_DECL (c)
11348 8 : = build_indirect_ref (loc, closure, RO_UNARY_STAR);
11349 8 : OMP_CLAUSE_SIZE (c)
11350 8 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure)));
11351 8 : new_clauses.safe_push (c);
11352 :
11353 8 : tree closure_obj = OMP_CLAUSE_DECL (c);
11354 8 : tree closure_type = TREE_TYPE (closure_obj);
11355 :
11356 16 : gcc_assert (LAMBDA_TYPE_P (closure_type)
11357 : && CLASS_TYPE_P (closure_type));
11358 :
11359 8 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11360 8 : OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER);
11361 8 : OMP_CLAUSE_DECL (c2) = closure;
11362 8 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11363 8 : new_clauses.safe_push (c2);
11364 : }
11365 :
11366 6967 : if (data.this_expr_accessed)
11367 : {
11368 : /* If the this-expr was accessed, create a map(*this) clause. */
11369 31 : enum gomp_map_kind kind = GOMP_MAP_TOFROM;
11370 31 : if (explicit_this_deref_map)
11371 : {
11372 1 : tree this_map = *explicit_this_deref_map;
11373 1 : tree nc = OMP_CLAUSE_CHAIN (this_map);
11374 2 : gcc_assert (nc != NULL_TREE
11375 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11376 : && (OMP_CLAUSE_MAP_KIND (nc)
11377 : == GOMP_MAP_FIRSTPRIVATE_POINTER));
11378 1 : kind = OMP_CLAUSE_MAP_KIND (this_map);
11379 : /* Remove the original 'map(*this) map(firstprivate_ptr:this)'
11380 : two-map sequence away from the chain. */
11381 1 : *explicit_this_deref_map = OMP_CLAUSE_CHAIN (nc);
11382 : }
11383 31 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11384 31 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11385 31 : OMP_CLAUSE_DECL (c)
11386 31 : = build_indirect_ref (loc, omp_target_this_expr, RO_UNARY_STAR);
11387 31 : OMP_CLAUSE_SIZE (c)
11388 31 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (omp_target_this_expr)));
11389 31 : new_clauses.safe_push (c);
11390 :
11391 : /* If we're in a lambda function, the this-pointer will actually be
11392 : '__closure->this', a mapped member of __closure, hence always_pointer.
11393 : Otherwise it's a firstprivate pointer. */
11394 31 : enum gomp_map_kind ptr_kind
11395 31 : = (DECL_LAMBDA_FUNCTION_P (current_function_decl)
11396 31 : ? GOMP_MAP_ALWAYS_POINTER
11397 24 : : GOMP_MAP_FIRSTPRIVATE_POINTER);
11398 31 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11399 31 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11400 31 : OMP_CLAUSE_DECL (c) = omp_target_this_expr;
11401 31 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11402 31 : new_clauses.safe_push (c);
11403 : }
11404 :
11405 6967 : if (DECL_LAMBDA_FUNCTION_P (current_function_decl))
11406 : {
11407 8 : if (omp_target_this_expr)
11408 : {
11409 7 : STRIP_NOPS (omp_target_this_expr);
11410 7 : gcc_assert (DECL_HAS_VALUE_EXPR_P (omp_target_this_expr));
11411 7 : omp_target_this_expr = DECL_VALUE_EXPR (omp_target_this_expr);
11412 : }
11413 :
11414 17 : for (hash_set<tree>::iterator i = data.closure_vars_accessed.begin ();
11415 25 : i != data.closure_vars_accessed.end (); ++i)
11416 : {
11417 9 : tree orig_decl = *i;
11418 9 : tree closure_expr = DECL_VALUE_EXPR (orig_decl);
11419 :
11420 9 : if (TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE
11421 9 : || TREE_CODE (TREE_TYPE (orig_decl)) == REFERENCE_TYPE)
11422 : {
11423 : /* this-pointer is processed above, outside this loop. */
11424 3 : if (omp_target_this_expr
11425 3 : && operand_equal_p (closure_expr, omp_target_this_expr))
11426 0 : continue;
11427 :
11428 3 : bool ptr_p = TREE_CODE (TREE_TYPE (orig_decl)) == POINTER_TYPE;
11429 3 : enum gomp_map_kind kind, ptr_kind, nc_kind;
11430 3 : tree size;
11431 :
11432 3 : if (ptr_p)
11433 : {
11434 : /* For pointers, default mapped as zero-length array
11435 : section. */
11436 2 : kind = GOMP_MAP_ALLOC;
11437 2 : nc_kind = GOMP_MAP_FIRSTPRIVATE_POINTER;
11438 2 : ptr_kind = GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION;
11439 2 : size = size_zero_node;
11440 : }
11441 : else
11442 : {
11443 : /* For references, default mapped as appearing on map
11444 : clause. */
11445 1 : kind = GOMP_MAP_TOFROM;
11446 1 : nc_kind = GOMP_MAP_FIRSTPRIVATE_REFERENCE;
11447 1 : ptr_kind = GOMP_MAP_ALWAYS_POINTER;
11448 1 : size = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (closure_expr)));
11449 : }
11450 :
11451 6 : for (tree *p = clauses_ptr; *p; p = &OMP_CLAUSE_CHAIN (*p))
11452 3 : if (OMP_CLAUSE_CODE (*p) == OMP_CLAUSE_MAP
11453 1 : && (TREE_CODE (OMP_CLAUSE_DECL (*p)) == INDIRECT_REF
11454 1 : || TREE_CODE (OMP_CLAUSE_DECL (*p)) == MEM_REF)
11455 3 : && operand_equal_p (TREE_OPERAND (OMP_CLAUSE_DECL (*p), 0),
11456 : orig_decl))
11457 : {
11458 : /* If this was already specified by user as a map,
11459 : save the user specified map kind, delete the
11460 : "map(*ptr/ref), map(firstprivate ptr/ref)" sequence,
11461 : and insert our own sequence:
11462 : "map(*__closure->ptr/ref), map(<ptr_kind>:__closure->ref"
11463 : */
11464 0 : tree nc = OMP_CLAUSE_CHAIN (*p);
11465 0 : gcc_assert (nc != NULL_TREE
11466 : && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
11467 : && OMP_CLAUSE_MAP_KIND (nc) == nc_kind);
11468 : /* Update with user specified kind and size. */
11469 0 : kind = OMP_CLAUSE_MAP_KIND (*p);
11470 0 : size = OMP_CLAUSE_SIZE (*p);
11471 0 : *p = OMP_CLAUSE_CHAIN (nc);
11472 0 : break;
11473 : }
11474 :
11475 3 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11476 3 : OMP_CLAUSE_SET_MAP_KIND (c, kind);
11477 3 : OMP_CLAUSE_DECL (c)
11478 3 : = build_indirect_ref (loc, closure_expr, RO_UNARY_STAR);
11479 3 : OMP_CLAUSE_SIZE (c) = size;
11480 3 : if (ptr_p)
11481 2 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11482 3 : new_clauses.safe_push (c);
11483 :
11484 3 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11485 3 : OMP_CLAUSE_SET_MAP_KIND (c, ptr_kind);
11486 3 : OMP_CLAUSE_DECL (c) = closure_expr;
11487 3 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11488 3 : new_clauses.safe_push (c);
11489 : }
11490 : }
11491 : }
11492 :
11493 6967 : if (!data.ptr_members_accessed.is_empty ())
11494 14 : for (hash_map<tree, tree>::iterator i = data.ptr_members_accessed.begin ();
11495 42 : i != data.ptr_members_accessed.end (); ++i)
11496 : {
11497 : /* For each referenced member that is of pointer or reference-to-pointer
11498 : type, create the equivalent of map(alloc:this->ptr[:0]). */
11499 14 : tree field_decl = (*i).first;
11500 14 : tree ptr_member = (*i).second;
11501 :
11502 26 : for (tree c = *clauses_ptr; c; c = OMP_CLAUSE_CHAIN (c))
11503 : {
11504 16 : if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP)
11505 2 : continue;
11506 : /* If map(this->ptr[:N]) already exists, avoid creating another
11507 : such map. */
11508 14 : tree decl = OMP_CLAUSE_DECL (c);
11509 14 : if ((TREE_CODE (decl) == INDIRECT_REF
11510 10 : || TREE_CODE (decl) == MEM_REF)
11511 14 : && operand_equal_p (TREE_OPERAND (decl, 0), ptr_member))
11512 4 : goto next_ptr_member;
11513 : }
11514 :
11515 10 : if (!cxx_mark_addressable (ptr_member))
11516 0 : gcc_unreachable ();
11517 :
11518 10 : if (TREE_CODE (TREE_TYPE (field_decl)) == REFERENCE_TYPE)
11519 : {
11520 : /* For reference to pointers, we need to map the referenced
11521 : pointer first for things to be correct. */
11522 4 : tree ptr_member_type = TREE_TYPE (ptr_member);
11523 :
11524 : /* Map pointer target as zero-length array section. */
11525 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11526 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11527 4 : OMP_CLAUSE_DECL (c)
11528 4 : = build1 (INDIRECT_REF, TREE_TYPE (ptr_member_type), ptr_member);
11529 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11530 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11531 :
11532 : /* Map pointer to zero-length array section. */
11533 4 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11534 4 : OMP_CLAUSE_SET_MAP_KIND
11535 : (c2, GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION);
11536 4 : OMP_CLAUSE_DECL (c2) = ptr_member;
11537 4 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11538 :
11539 : /* Attach reference-to-pointer field to pointer. */
11540 4 : tree c3 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11541 4 : OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH);
11542 4 : OMP_CLAUSE_DECL (c3) = TREE_OPERAND (ptr_member, 0);
11543 4 : OMP_CLAUSE_SIZE (c3) = size_zero_node;
11544 :
11545 4 : new_clauses.safe_push (c);
11546 4 : new_clauses.safe_push (c2);
11547 4 : new_clauses.safe_push (c3);
11548 : }
11549 6 : else if (TREE_CODE (TREE_TYPE (field_decl)) == POINTER_TYPE)
11550 : {
11551 : /* Map pointer target as zero-length array section. */
11552 6 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11553 6 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11554 6 : OMP_CLAUSE_DECL (c) = build_indirect_ref (loc, ptr_member,
11555 : RO_UNARY_STAR);
11556 6 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11557 6 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11558 :
11559 : /* Attach zero-length array section to pointer. */
11560 6 : tree c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
11561 6 : OMP_CLAUSE_SET_MAP_KIND
11562 : (c2, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11563 6 : OMP_CLAUSE_DECL (c2) = ptr_member;
11564 6 : OMP_CLAUSE_SIZE (c2) = size_zero_node;
11565 :
11566 6 : new_clauses.safe_push (c);
11567 6 : new_clauses.safe_push (c2);
11568 : }
11569 : else
11570 0 : gcc_unreachable ();
11571 :
11572 14 : next_ptr_member:
11573 14 : ;
11574 : }
11575 :
11576 6980 : for (hash_set<tree>::iterator i = data.lambda_objects_accessed.begin ();
11577 6980 : i != data.lambda_objects_accessed.end (); ++i)
11578 : {
11579 13 : tree lobj = *i;
11580 13 : if (TREE_CODE (lobj) == TARGET_EXPR)
11581 0 : lobj = TARGET_EXPR_SLOT (lobj);
11582 :
11583 13 : tree lt = TREE_TYPE (lobj);
11584 26 : gcc_assert (LAMBDA_TYPE_P (lt) && CLASS_TYPE_P (lt));
11585 :
11586 13 : tree lc = build_omp_clause (loc, OMP_CLAUSE_MAP);
11587 13 : OMP_CLAUSE_SET_MAP_KIND (lc, GOMP_MAP_TO);
11588 13 : OMP_CLAUSE_DECL (lc) = lobj;
11589 13 : OMP_CLAUSE_SIZE (lc) = TYPE_SIZE_UNIT (lt);
11590 13 : new_clauses.safe_push (lc);
11591 :
11592 180 : for (tree fld = TYPE_FIELDS (lt); fld; fld = DECL_CHAIN (fld))
11593 : {
11594 167 : if (TREE_CODE (TREE_TYPE (fld)) == POINTER_TYPE)
11595 : {
11596 4 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11597 : lobj, fld, NULL_TREE);
11598 4 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11599 4 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALLOC);
11600 4 : OMP_CLAUSE_DECL (c)
11601 4 : = build_indirect_ref (loc, exp, RO_UNARY_STAR);
11602 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11603 4 : OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1;
11604 4 : new_clauses.safe_push (c);
11605 :
11606 4 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11607 4 : OMP_CLAUSE_SET_MAP_KIND
11608 : (c, GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION);
11609 4 : OMP_CLAUSE_DECL (c) = exp;
11610 4 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11611 4 : new_clauses.safe_push (c);
11612 : }
11613 163 : else if (TREE_CODE (TREE_TYPE (fld)) == REFERENCE_TYPE)
11614 : {
11615 0 : tree exp = build3 (COMPONENT_REF, TREE_TYPE (fld),
11616 : lobj, fld, NULL_TREE);
11617 0 : tree c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11618 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM);
11619 0 : OMP_CLAUSE_DECL (c)
11620 0 : = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
11621 0 : OMP_CLAUSE_SIZE (c)
11622 0 : = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (exp)));
11623 0 : new_clauses.safe_push (c);
11624 :
11625 0 : c = build_omp_clause (loc, OMP_CLAUSE_MAP);
11626 0 : OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_ALWAYS_POINTER);
11627 0 : OMP_CLAUSE_DECL (c) = exp;
11628 0 : OMP_CLAUSE_SIZE (c) = size_zero_node;
11629 0 : new_clauses.safe_push (c);
11630 : }
11631 : }
11632 : }
11633 :
11634 6967 : tree c = *clauses_ptr;
11635 14156 : for (int i = new_clauses.length () - 1; i >= 0; i--)
11636 : {
11637 222 : OMP_CLAUSE_CHAIN (new_clauses[i]) = c;
11638 222 : c = new_clauses[i];
11639 : }
11640 6967 : *clauses_ptr = c;
11641 6967 : }
11642 :
11643 : /* Called from cp_parser_omp_target. Create additional implicit clauses for
11644 : OpenMP target directives, and do sanity checks. */
11645 :
11646 : tree
11647 6957 : finish_omp_target (location_t loc, tree clauses, tree body, bool combined_p)
11648 : {
11649 6957 : if (!processing_template_decl)
11650 6151 : finish_omp_target_clauses (loc, body, &clauses);
11651 :
11652 6957 : tree stmt = make_node (OMP_TARGET);
11653 6957 : TREE_TYPE (stmt) = void_type_node;
11654 6957 : OMP_TARGET_CLAUSES (stmt) = clauses;
11655 6957 : OMP_TARGET_BODY (stmt) = body;
11656 6957 : OMP_TARGET_COMBINED (stmt) = combined_p;
11657 6957 : SET_EXPR_LOCATION (stmt, loc);
11658 :
11659 6957 : tree c = clauses;
11660 16739 : while (c)
11661 : {
11662 9782 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP)
11663 5685 : switch (OMP_CLAUSE_MAP_KIND (c))
11664 : {
11665 : case GOMP_MAP_TO:
11666 : case GOMP_MAP_ALWAYS_TO:
11667 : case GOMP_MAP_PRESENT_TO:
11668 : case GOMP_MAP_ALWAYS_PRESENT_TO:
11669 : case GOMP_MAP_FROM:
11670 : case GOMP_MAP_ALWAYS_FROM:
11671 : case GOMP_MAP_PRESENT_FROM:
11672 : case GOMP_MAP_ALWAYS_PRESENT_FROM:
11673 : case GOMP_MAP_TOFROM:
11674 : case GOMP_MAP_ALWAYS_TOFROM:
11675 : case GOMP_MAP_PRESENT_TOFROM:
11676 : case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
11677 : case GOMP_MAP_ALLOC:
11678 : case GOMP_MAP_PRESENT_ALLOC:
11679 : case GOMP_MAP_FIRSTPRIVATE_POINTER:
11680 : case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
11681 : case GOMP_MAP_ALWAYS_POINTER:
11682 : case GOMP_MAP_ATTACH_DETACH:
11683 : case GOMP_MAP_ATTACH:
11684 : case GOMP_MAP_ATTACH_ZERO_LENGTH_ARRAY_SECTION:
11685 : case GOMP_MAP_POINTER:
11686 : case GOMP_MAP_POINTER_TO_ZERO_LENGTH_ARRAY_SECTION:
11687 : break;
11688 3 : default:
11689 3 : error_at (OMP_CLAUSE_LOCATION (c),
11690 : "%<#pragma omp target%> with map-type other "
11691 : "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
11692 : "on %<map%> clause");
11693 3 : break;
11694 : }
11695 9782 : c = OMP_CLAUSE_CHAIN (c);
11696 : }
11697 6957 : return add_stmt (stmt);
11698 : }
11699 :
11700 : tree
11701 9458 : finish_omp_parallel (tree clauses, tree body)
11702 : {
11703 9458 : tree stmt;
11704 :
11705 9458 : body = finish_omp_structured_block (body);
11706 :
11707 9458 : stmt = make_node (OMP_PARALLEL);
11708 9458 : TREE_TYPE (stmt) = void_type_node;
11709 9458 : OMP_PARALLEL_CLAUSES (stmt) = clauses;
11710 9458 : OMP_PARALLEL_BODY (stmt) = body;
11711 :
11712 9458 : return add_stmt (stmt);
11713 : }
11714 :
11715 : tree
11716 2411 : begin_omp_task (void)
11717 : {
11718 2411 : keep_next_level (true);
11719 2411 : return begin_omp_structured_block ();
11720 : }
11721 :
11722 : tree
11723 2411 : finish_omp_task (tree clauses, tree body)
11724 : {
11725 2411 : tree stmt;
11726 :
11727 2411 : body = finish_omp_structured_block (body);
11728 :
11729 2411 : stmt = make_node (OMP_TASK);
11730 2411 : TREE_TYPE (stmt) = void_type_node;
11731 2411 : OMP_TASK_CLAUSES (stmt) = clauses;
11732 2411 : OMP_TASK_BODY (stmt) = body;
11733 :
11734 2411 : return add_stmt (stmt);
11735 : }
11736 :
11737 : /* Helper function for finish_omp_for. Convert Ith random access iterator
11738 : into integral iterator. Return FALSE if successful. */
11739 :
11740 : static bool
11741 813 : handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
11742 : tree declv, tree orig_declv, tree initv,
11743 : tree condv, tree incrv, tree *body,
11744 : tree *pre_body, tree &clauses,
11745 : int collapse, int ordered)
11746 : {
11747 813 : tree diff, iter_init, iter_incr = NULL, last;
11748 813 : tree incr_var = NULL, orig_pre_body, orig_body, c;
11749 813 : tree decl = TREE_VEC_ELT (declv, i);
11750 813 : tree init = TREE_VEC_ELT (initv, i);
11751 813 : tree cond = TREE_VEC_ELT (condv, i);
11752 813 : tree incr = TREE_VEC_ELT (incrv, i);
11753 813 : tree iter = decl;
11754 813 : location_t elocus = locus;
11755 :
11756 813 : if (init && EXPR_HAS_LOCATION (init))
11757 12 : elocus = EXPR_LOCATION (init);
11758 :
11759 813 : switch (TREE_CODE (cond))
11760 : {
11761 810 : case GT_EXPR:
11762 810 : case GE_EXPR:
11763 810 : case LT_EXPR:
11764 810 : case LE_EXPR:
11765 810 : case NE_EXPR:
11766 810 : if (TREE_OPERAND (cond, 1) == iter)
11767 42 : cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
11768 42 : TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
11769 810 : if (TREE_OPERAND (cond, 0) != iter)
11770 0 : cond = error_mark_node;
11771 : else
11772 : {
11773 810 : tree tem = build_x_binary_op (EXPR_LOCATION (cond),
11774 810 : TREE_CODE (cond),
11775 : iter, ERROR_MARK,
11776 810 : TREE_OPERAND (cond, 1), ERROR_MARK,
11777 : NULL_TREE, NULL, tf_warning_or_error);
11778 810 : if (error_operand_p (tem))
11779 : return true;
11780 : }
11781 : break;
11782 3 : default:
11783 3 : cond = error_mark_node;
11784 3 : break;
11785 : }
11786 810 : if (cond == error_mark_node)
11787 : {
11788 3 : error_at (elocus, "invalid controlling predicate");
11789 3 : return true;
11790 : }
11791 807 : diff = build_x_binary_op (elocus, MINUS_EXPR,
11792 807 : TREE_OPERAND (cond, 1), ERROR_MARK,
11793 : iter, ERROR_MARK,
11794 : NULL_TREE, NULL, tf_warning_or_error);
11795 807 : diff = cp_fully_fold (diff);
11796 807 : if (error_operand_p (diff))
11797 : return true;
11798 807 : if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE)
11799 : {
11800 0 : error_at (elocus, "difference between %qE and %qD does not have integer type",
11801 0 : TREE_OPERAND (cond, 1), iter);
11802 0 : return true;
11803 : }
11804 807 : if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
11805 807 : TREE_VEC_ELT (declv, i), NULL_TREE,
11806 : cond, cp_walk_subtrees))
11807 : return true;
11808 :
11809 762 : switch (TREE_CODE (incr))
11810 : {
11811 370 : case PREINCREMENT_EXPR:
11812 370 : case PREDECREMENT_EXPR:
11813 370 : case POSTINCREMENT_EXPR:
11814 370 : case POSTDECREMENT_EXPR:
11815 370 : if (TREE_OPERAND (incr, 0) != iter)
11816 : {
11817 0 : incr = error_mark_node;
11818 0 : break;
11819 : }
11820 370 : iter_incr = build_x_unary_op (EXPR_LOCATION (incr),
11821 370 : TREE_CODE (incr), iter,
11822 : NULL_TREE, tf_warning_or_error);
11823 370 : if (error_operand_p (iter_incr))
11824 : return true;
11825 370 : else if (TREE_CODE (incr) == PREINCREMENT_EXPR
11826 219 : || TREE_CODE (incr) == POSTINCREMENT_EXPR)
11827 299 : incr = integer_one_node;
11828 : else
11829 71 : incr = integer_minus_one_node;
11830 : break;
11831 392 : case MODIFY_EXPR:
11832 392 : if (TREE_OPERAND (incr, 0) != iter)
11833 0 : incr = error_mark_node;
11834 392 : else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
11835 392 : || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
11836 : {
11837 392 : tree rhs = TREE_OPERAND (incr, 1);
11838 392 : if (TREE_OPERAND (rhs, 0) == iter)
11839 : {
11840 299 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1)))
11841 : != INTEGER_TYPE)
11842 0 : incr = error_mark_node;
11843 : else
11844 : {
11845 299 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11846 299 : iter, TREE_CODE (rhs),
11847 299 : TREE_OPERAND (rhs, 1),
11848 : NULL_TREE,
11849 : tf_warning_or_error);
11850 299 : if (error_operand_p (iter_incr))
11851 : return true;
11852 299 : incr = TREE_OPERAND (rhs, 1);
11853 299 : incr = cp_convert (TREE_TYPE (diff), incr,
11854 : tf_warning_or_error);
11855 299 : if (TREE_CODE (rhs) == MINUS_EXPR)
11856 : {
11857 16 : incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr);
11858 16 : incr = fold_simple (incr);
11859 : }
11860 299 : if (TREE_CODE (incr) != INTEGER_CST
11861 299 : && (TREE_CODE (incr) != NOP_EXPR
11862 66 : || (TREE_CODE (TREE_OPERAND (incr, 0))
11863 : != INTEGER_CST)))
11864 : iter_incr = NULL;
11865 : }
11866 : }
11867 93 : else if (TREE_OPERAND (rhs, 1) == iter)
11868 : {
11869 93 : if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE
11870 93 : || TREE_CODE (rhs) != PLUS_EXPR)
11871 0 : incr = error_mark_node;
11872 : else
11873 : {
11874 93 : iter_incr = build_x_binary_op (EXPR_LOCATION (rhs),
11875 : PLUS_EXPR,
11876 93 : TREE_OPERAND (rhs, 0),
11877 : ERROR_MARK, iter,
11878 : ERROR_MARK, NULL_TREE, NULL,
11879 : tf_warning_or_error);
11880 93 : if (error_operand_p (iter_incr))
11881 : return true;
11882 93 : iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs),
11883 : iter, NOP_EXPR,
11884 : iter_incr, NULL_TREE,
11885 : tf_warning_or_error);
11886 93 : if (error_operand_p (iter_incr))
11887 : return true;
11888 93 : incr = TREE_OPERAND (rhs, 0);
11889 93 : iter_incr = NULL;
11890 : }
11891 : }
11892 : else
11893 0 : incr = error_mark_node;
11894 : }
11895 : else
11896 0 : incr = error_mark_node;
11897 : break;
11898 0 : default:
11899 0 : incr = error_mark_node;
11900 0 : break;
11901 : }
11902 :
11903 762 : if (incr == error_mark_node)
11904 : {
11905 0 : error_at (elocus, "invalid increment expression");
11906 0 : return true;
11907 : }
11908 :
11909 762 : incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
11910 762 : incr = cp_fully_fold (incr);
11911 762 : tree loop_iv_seen = NULL_TREE;
11912 1735 : for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
11913 1093 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
11914 1093 : && OMP_CLAUSE_DECL (c) == iter)
11915 : {
11916 120 : if (code == OMP_TASKLOOP || code == OMP_LOOP)
11917 : {
11918 60 : loop_iv_seen = c;
11919 60 : OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
11920 : }
11921 : break;
11922 : }
11923 973 : else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
11924 113 : && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
11925 1007 : && OMP_CLAUSE_DECL (c) == iter)
11926 : {
11927 30 : loop_iv_seen = c;
11928 30 : if (code == OMP_TASKLOOP)
11929 25 : OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
11930 : }
11931 :
11932 762 : decl = create_temporary_var (TREE_TYPE (diff));
11933 762 : pushdecl (decl);
11934 762 : add_decl_expr (decl);
11935 762 : last = create_temporary_var (TREE_TYPE (diff));
11936 762 : pushdecl (last);
11937 762 : add_decl_expr (last);
11938 762 : if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST
11939 10 : && (!ordered || (i < collapse && collapse > 1)))
11940 : {
11941 10 : incr_var = create_temporary_var (TREE_TYPE (diff));
11942 10 : pushdecl (incr_var);
11943 10 : add_decl_expr (incr_var);
11944 : }
11945 762 : gcc_assert (stmts_are_full_exprs_p ());
11946 762 : tree diffvar = NULL_TREE;
11947 762 : if (code == OMP_TASKLOOP)
11948 : {
11949 101 : if (!loop_iv_seen)
11950 : {
11951 38 : tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11952 38 : OMP_CLAUSE_DECL (ivc) = iter;
11953 38 : cxx_omp_finish_clause (ivc, NULL, false);
11954 38 : OMP_CLAUSE_CHAIN (ivc) = clauses;
11955 38 : clauses = ivc;
11956 : }
11957 101 : tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11958 101 : OMP_CLAUSE_DECL (lvc) = last;
11959 101 : OMP_CLAUSE_CHAIN (lvc) = clauses;
11960 101 : clauses = lvc;
11961 101 : diffvar = create_temporary_var (TREE_TYPE (diff));
11962 101 : pushdecl (diffvar);
11963 101 : add_decl_expr (diffvar);
11964 : }
11965 661 : else if (code == OMP_LOOP)
11966 : {
11967 43 : if (!loop_iv_seen)
11968 : {
11969 : /* While iterators on the loop construct are predetermined
11970 : lastprivate, if the decl is not declared inside of the
11971 : loop, OMP_CLAUSE_LASTPRIVATE should have been added
11972 : already. */
11973 16 : loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
11974 16 : OMP_CLAUSE_DECL (loop_iv_seen) = iter;
11975 16 : OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
11976 16 : clauses = loop_iv_seen;
11977 : }
11978 27 : else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
11979 : {
11980 5 : OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
11981 5 : OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
11982 5 : OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
11983 : }
11984 43 : if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
11985 21 : cxx_omp_finish_clause (loop_iv_seen, NULL, false);
11986 : }
11987 :
11988 762 : orig_pre_body = *pre_body;
11989 762 : *pre_body = push_stmt_list ();
11990 762 : if (orig_pre_body)
11991 610 : add_stmt (orig_pre_body);
11992 762 : if (init != NULL)
11993 61 : finish_expr_stmt (build_x_modify_expr (elocus,
11994 : iter, NOP_EXPR, init,
11995 : NULL_TREE, tf_warning_or_error));
11996 762 : init = build_int_cst (TREE_TYPE (diff), 0);
11997 762 : if (c && iter_incr == NULL
11998 28 : && (!ordered || (i < collapse && collapse > 1)))
11999 : {
12000 28 : if (incr_var)
12001 : {
12002 10 : finish_expr_stmt (build_x_modify_expr (elocus,
12003 : incr_var, NOP_EXPR,
12004 : incr, NULL_TREE,
12005 : tf_warning_or_error));
12006 10 : incr = incr_var;
12007 : }
12008 28 : iter_incr = build_x_modify_expr (elocus,
12009 : iter, PLUS_EXPR, incr,
12010 : NULL_TREE, tf_warning_or_error);
12011 : }
12012 762 : if (c && ordered && i < collapse && collapse > 1)
12013 762 : iter_incr = incr;
12014 762 : finish_expr_stmt (build_x_modify_expr (elocus,
12015 : last, NOP_EXPR, init,
12016 : NULL_TREE, tf_warning_or_error));
12017 762 : if (diffvar)
12018 : {
12019 101 : finish_expr_stmt (build_x_modify_expr (elocus,
12020 : diffvar, NOP_EXPR,
12021 : diff, NULL_TREE, tf_warning_or_error));
12022 101 : diff = diffvar;
12023 : }
12024 762 : *pre_body = pop_stmt_list (*pre_body);
12025 :
12026 1524 : cond = cp_build_binary_op (elocus,
12027 762 : TREE_CODE (cond), decl, diff,
12028 : tf_warning_or_error);
12029 762 : incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
12030 : elocus, incr, NULL_TREE);
12031 :
12032 762 : orig_body = *body;
12033 762 : *body = push_stmt_list ();
12034 762 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last);
12035 762 : iter_init = build_x_modify_expr (elocus,
12036 : iter, PLUS_EXPR, iter_init,
12037 : NULL_TREE, tf_warning_or_error);
12038 762 : if (iter_init != error_mark_node)
12039 759 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
12040 762 : finish_expr_stmt (iter_init);
12041 762 : finish_expr_stmt (build_x_modify_expr (elocus,
12042 : last, NOP_EXPR, decl,
12043 : NULL_TREE, tf_warning_or_error));
12044 762 : add_stmt (orig_body);
12045 762 : *body = pop_stmt_list (*body);
12046 :
12047 762 : if (c)
12048 : {
12049 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list ();
12050 120 : if (!ordered)
12051 114 : finish_expr_stmt (iter_incr);
12052 : else
12053 : {
12054 6 : iter_init = decl;
12055 6 : if (i < collapse && collapse > 1 && !error_operand_p (iter_incr))
12056 2 : iter_init = build2 (PLUS_EXPR, TREE_TYPE (diff),
12057 : iter_init, iter_incr);
12058 6 : iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), iter_init, last);
12059 6 : iter_init = build_x_modify_expr (elocus,
12060 : iter, PLUS_EXPR, iter_init,
12061 : NULL_TREE, tf_warning_or_error);
12062 6 : if (iter_init != error_mark_node)
12063 6 : iter_init = build1 (NOP_EXPR, void_type_node, iter_init);
12064 6 : finish_expr_stmt (iter_init);
12065 : }
12066 120 : OMP_CLAUSE_LASTPRIVATE_STMT (c)
12067 240 : = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c));
12068 : }
12069 :
12070 762 : if (TREE_CODE (TREE_VEC_ELT (orig_declv, i)) == TREE_LIST)
12071 : {
12072 116 : tree t = TREE_VEC_ELT (orig_declv, i);
12073 116 : gcc_assert (TREE_PURPOSE (t) == NULL_TREE
12074 : && TREE_VALUE (t) == NULL_TREE
12075 : && TREE_CODE (TREE_CHAIN (t)) == TREE_VEC);
12076 116 : TREE_PURPOSE (t) = TREE_VEC_ELT (declv, i);
12077 116 : TREE_VALUE (t) = last;
12078 : }
12079 : else
12080 646 : TREE_VEC_ELT (orig_declv, i)
12081 1292 : = tree_cons (TREE_VEC_ELT (declv, i), last, NULL_TREE);
12082 762 : TREE_VEC_ELT (declv, i) = decl;
12083 762 : TREE_VEC_ELT (initv, i) = init;
12084 762 : TREE_VEC_ELT (condv, i) = cond;
12085 762 : TREE_VEC_ELT (incrv, i) = incr;
12086 :
12087 762 : return false;
12088 : }
12089 :
12090 : /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR
12091 : are directly for their associated operands in the statement. DECL
12092 : and INIT are a combo; if DECL is NULL then INIT ought to be a
12093 : MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are
12094 : optional statements that need to go before the loop into its
12095 : sk_omp scope. */
12096 :
12097 : tree
12098 21246 : finish_omp_for (location_t locus, enum tree_code code, tree declv,
12099 : tree orig_declv, tree initv, tree condv, tree incrv,
12100 : tree body, tree pre_body, vec<tree> *orig_inits, tree clauses)
12101 : {
12102 21246 : tree omp_for = NULL, orig_incr = NULL;
12103 21246 : tree decl = NULL, init, cond, incr;
12104 21246 : location_t elocus;
12105 21246 : int i;
12106 21246 : int collapse = 1;
12107 21246 : int ordered = 0;
12108 21246 : auto_vec<location_t> init_locv;
12109 :
12110 21246 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
12111 21246 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
12112 21246 : gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
12113 21246 : if (TREE_VEC_LENGTH (declv) > 1)
12114 : {
12115 4054 : if (tree ti = omp_find_clause (clauses, OMP_CLAUSE_TILE))
12116 83 : collapse = list_length (OMP_CLAUSE_TILE_LIST (ti));
12117 : else
12118 : {
12119 3971 : if (tree co = omp_find_clause (clauses, OMP_CLAUSE_COLLAPSE))
12120 3501 : collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (co));
12121 470 : else if (tree si = omp_find_clause (clauses, OMP_CLAUSE_SIZES))
12122 394 : collapse = list_length (OMP_CLAUSE_SIZES_LIST (si));
12123 3971 : if (collapse != TREE_VEC_LENGTH (declv))
12124 100 : ordered = TREE_VEC_LENGTH (declv);
12125 : }
12126 : }
12127 48837 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12128 : {
12129 27627 : decl = TREE_VEC_ELT (declv, i);
12130 27627 : init = TREE_VEC_ELT (initv, i);
12131 27627 : cond = TREE_VEC_ELT (condv, i);
12132 27627 : incr = TREE_VEC_ELT (incrv, i);
12133 27627 : elocus = locus;
12134 :
12135 27627 : if (decl == global_namespace)
12136 : {
12137 1101 : gcc_assert (init == NULL_TREE && cond == NULL_TREE && incr == NULL_TREE);
12138 1101 : TREE_VEC_ELT (declv, i) = NULL_TREE;
12139 1101 : init_locv.safe_push (UNKNOWN_LOCATION);
12140 1101 : continue;
12141 : }
12142 : /* We are going to throw out the init's original MODIFY_EXPR or
12143 : MODOP_EXPR below. Save its location so we can use it when
12144 : reconstructing the expression farther down. Alternatively, if the
12145 : initializer is a binding of the iteration variable, save
12146 : that location. Any of these locations in the initialization clause
12147 : for the current nested loop are better than using the argument locus,
12148 : that points to the "for" of the outermost loop in the nest. */
12149 26526 : if (init && EXPR_HAS_LOCATION (init))
12150 17962 : elocus = EXPR_LOCATION (init);
12151 8564 : else if (decl && INDIRECT_REF_P (decl) && EXPR_HAS_LOCATION (decl))
12152 : /* This can happen for class iterators. */
12153 0 : elocus = EXPR_LOCATION (decl);
12154 8564 : else if (decl && DECL_P (decl))
12155 : {
12156 8537 : if (DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION)
12157 8537 : elocus = DECL_SOURCE_LOCATION (decl);
12158 0 : else if (DECL_INITIAL (decl)
12159 0 : && EXPR_HAS_LOCATION (DECL_INITIAL (decl)))
12160 0 : elocus = EXPR_LOCATION (DECL_INITIAL (decl));
12161 : }
12162 26526 : init_locv.safe_push (elocus);
12163 :
12164 26526 : if (decl == NULL)
12165 : {
12166 16654 : if (init != NULL)
12167 16651 : switch (TREE_CODE (init))
12168 : {
12169 16244 : case MODIFY_EXPR:
12170 16244 : decl = TREE_OPERAND (init, 0);
12171 16244 : init = TREE_OPERAND (init, 1);
12172 16244 : break;
12173 389 : case MODOP_EXPR:
12174 389 : if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR)
12175 : {
12176 389 : decl = TREE_OPERAND (init, 0);
12177 389 : init = TREE_OPERAND (init, 2);
12178 : }
12179 : break;
12180 : default:
12181 : break;
12182 : }
12183 :
12184 16654 : if (decl == NULL)
12185 : {
12186 21 : error_at (locus,
12187 : "expected iteration declaration or initialization");
12188 21 : return NULL;
12189 : }
12190 : }
12191 :
12192 26505 : if (cond == global_namespace)
12193 170 : continue;
12194 :
12195 26335 : if (cond == NULL)
12196 : {
12197 9 : error_at (elocus, "missing controlling predicate");
12198 9 : return NULL;
12199 : }
12200 :
12201 26326 : if (incr == NULL)
12202 : {
12203 6 : error_at (elocus, "missing increment expression");
12204 6 : return NULL;
12205 : }
12206 :
12207 26320 : TREE_VEC_ELT (declv, i) = decl;
12208 26320 : TREE_VEC_ELT (initv, i) = init;
12209 : }
12210 :
12211 21210 : if (orig_inits)
12212 : {
12213 : bool fail = false;
12214 : tree orig_init;
12215 21310 : FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
12216 1181 : if (orig_init
12217 3396 : && !c_omp_check_loop_iv_exprs (locus, code,
12218 : orig_declv ? orig_declv : declv, i,
12219 1164 : TREE_VEC_ELT (declv, i), orig_init,
12220 : NULL_TREE, cp_walk_subtrees))
12221 : fail = true;
12222 20129 : if (fail)
12223 21246 : return NULL;
12224 : }
12225 :
12226 21153 : if (dependent_omp_for_p (declv, initv, condv, incrv, body))
12227 : {
12228 453 : tree stmt;
12229 :
12230 453 : stmt = make_node (code);
12231 :
12232 1499 : for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
12233 : {
12234 593 : if (TREE_VEC_ELT (declv, i) == NULL_TREE)
12235 9 : continue;
12236 : /* This is really just a place-holder. We'll be decomposing this
12237 : again and going through the cp_build_modify_expr path below when
12238 : we instantiate the thing. */
12239 584 : TREE_VEC_ELT (initv, i)
12240 1168 : = build2_loc (init_locv[i], MODIFY_EXPR, void_type_node,
12241 584 : TREE_VEC_ELT (declv, i), TREE_VEC_ELT (initv, i));
12242 : }
12243 :
12244 453 : TREE_TYPE (stmt) = void_type_node;
12245 453 : OMP_FOR_INIT (stmt) = initv;
12246 453 : OMP_FOR_COND (stmt) = condv;
12247 453 : OMP_FOR_INCR (stmt) = incrv;
12248 453 : OMP_FOR_BODY (stmt) = body;
12249 453 : OMP_FOR_PRE_BODY (stmt) = pre_body;
12250 453 : OMP_FOR_CLAUSES (stmt) = clauses;
12251 :
12252 453 : SET_EXPR_LOCATION (stmt, locus);
12253 453 : return add_stmt (stmt);
12254 : }
12255 :
12256 20700 : if (!orig_declv)
12257 19891 : orig_declv = copy_node (declv);
12258 :
12259 20700 : if (processing_template_decl)
12260 634 : orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv));
12261 :
12262 48266 : for (i = 0; i < TREE_VEC_LENGTH (declv); )
12263 : {
12264 27658 : decl = TREE_VEC_ELT (declv, i);
12265 27658 : init = TREE_VEC_ELT (initv, i);
12266 27658 : cond = TREE_VEC_ELT (condv, i);
12267 27658 : incr = TREE_VEC_ELT (incrv, i);
12268 27658 : if (orig_incr)
12269 866 : TREE_VEC_ELT (orig_incr, i) = incr;
12270 27658 : elocus = init_locv[i];
12271 :
12272 27658 : if (decl == NULL_TREE)
12273 : {
12274 1092 : i++;
12275 1092 : continue;
12276 : }
12277 :
12278 26566 : if (!DECL_P (decl))
12279 : {
12280 6 : error_at (elocus, "expected iteration declaration or initialization");
12281 6 : return NULL;
12282 : }
12283 :
12284 26560 : if (incr && TREE_CODE (incr) == MODOP_EXPR)
12285 : {
12286 1 : if (orig_incr)
12287 1 : TREE_VEC_ELT (orig_incr, i) = incr;
12288 1 : incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
12289 1 : TREE_CODE (TREE_OPERAND (incr, 1)),
12290 1 : TREE_OPERAND (incr, 2),
12291 : tf_warning_or_error);
12292 : }
12293 :
12294 26560 : if (CLASS_TYPE_P (TREE_TYPE (decl)))
12295 : {
12296 825 : if (code == OMP_SIMD)
12297 : {
12298 12 : error_at (elocus, "%<#pragma omp simd%> used with class "
12299 : "iteration variable %qE", decl);
12300 12 : return NULL;
12301 : }
12302 813 : if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv,
12303 : initv, condv, incrv, &body,
12304 : &pre_body, clauses,
12305 : collapse, ordered))
12306 : return NULL;
12307 762 : continue;
12308 : }
12309 :
12310 51470 : if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
12311 27321 : && !TYPE_PTR_P (TREE_TYPE (decl)))
12312 : {
12313 14 : error_at (elocus, "invalid type for iteration variable %qE", decl);
12314 14 : return NULL;
12315 : }
12316 :
12317 25721 : if (!processing_template_decl && TREE_CODE (init) != TREE_VEC)
12318 24938 : init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
12319 : tf_warning_or_error);
12320 : else
12321 783 : init = build2_loc (elocus, MODIFY_EXPR, void_type_node, decl, init);
12322 25721 : if (decl == error_mark_node || init == error_mark_node)
12323 : return NULL;
12324 :
12325 25712 : TREE_VEC_ELT (declv, i) = decl;
12326 25712 : TREE_VEC_ELT (initv, i) = init;
12327 25712 : TREE_VEC_ELT (condv, i) = cond;
12328 25712 : TREE_VEC_ELT (incrv, i) = incr;
12329 25712 : i++;
12330 : }
12331 :
12332 20608 : if (pre_body && IS_EMPTY_STMT (pre_body))
12333 0 : pre_body = NULL;
12334 :
12335 41216 : omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv,
12336 : incrv, body, pre_body,
12337 20608 : !processing_template_decl);
12338 :
12339 : /* Check for iterators appearing in lb, b or incr expressions. */
12340 20608 : if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees))
12341 : omp_for = NULL_TREE;
12342 :
12343 20122 : if (omp_for == NULL)
12344 : return NULL;
12345 :
12346 19906 : add_stmt (omp_for);
12347 :
12348 65590 : for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++)
12349 : {
12350 25778 : init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i);
12351 25778 : if (init == NULL_TREE)
12352 1032 : continue;
12353 24746 : decl = TREE_OPERAND (init, 0);
12354 24746 : cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i);
12355 24746 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i);
12356 :
12357 24746 : if (!processing_template_decl)
12358 : {
12359 24203 : if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC)
12360 : {
12361 106 : tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1);
12362 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 1)
12363 106 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12364 106 : t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2);
12365 106 : TREE_VEC_ELT (TREE_OPERAND (init, 1), 2)
12366 212 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12367 : }
12368 : else
12369 : {
12370 24097 : tree t = TREE_OPERAND (init, 1);
12371 24097 : TREE_OPERAND (init, 1)
12372 48194 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12373 : }
12374 24203 : if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC)
12375 : {
12376 121 : tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1);
12377 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1)
12378 121 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12379 121 : t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2);
12380 121 : TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2)
12381 242 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12382 : }
12383 : else
12384 : {
12385 24082 : tree t = TREE_OPERAND (cond, 1);
12386 24082 : TREE_OPERAND (cond, 1)
12387 48164 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12388 : }
12389 : }
12390 :
12391 24746 : if (TREE_CODE (incr) != MODIFY_EXPR)
12392 18541 : continue;
12393 :
12394 6205 : if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1))
12395 70 : && BINARY_CLASS_P (TREE_OPERAND (incr, 1))
12396 6275 : && !processing_template_decl)
12397 : {
12398 64 : tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0);
12399 64 : if (TREE_SIDE_EFFECTS (t)
12400 8 : && t != decl
12401 70 : && (TREE_CODE (t) != NOP_EXPR
12402 0 : || TREE_OPERAND (t, 0) != decl))
12403 6 : TREE_OPERAND (TREE_OPERAND (incr, 1), 0)
12404 12 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12405 :
12406 64 : t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1);
12407 64 : if (TREE_SIDE_EFFECTS (t)
12408 56 : && t != decl
12409 120 : && (TREE_CODE (t) != NOP_EXPR
12410 5 : || TREE_OPERAND (t, 0) != decl))
12411 56 : TREE_OPERAND (TREE_OPERAND (incr, 1), 1)
12412 112 : = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
12413 : }
12414 :
12415 6205 : if (orig_incr)
12416 177 : TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i);
12417 : }
12418 19906 : OMP_FOR_CLAUSES (omp_for) = clauses;
12419 :
12420 : /* For simd loops with non-static data member iterators, we could have added
12421 : OMP_CLAUSE_LINEAR clauses without OMP_CLAUSE_LINEAR_STEP. As we know the
12422 : step at this point, fill it in. */
12423 4741 : if (code == OMP_SIMD && !processing_template_decl
12424 24603 : && TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)) == 1)
12425 4625 : for (tree c = omp_find_clause (clauses, OMP_CLAUSE_LINEAR); c;
12426 561 : c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_LINEAR))
12427 561 : if (OMP_CLAUSE_LINEAR_STEP (c) == NULL_TREE)
12428 : {
12429 4 : decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0), 0);
12430 4 : gcc_assert (decl == OMP_CLAUSE_DECL (c));
12431 4 : incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0);
12432 4 : tree step, stept;
12433 4 : switch (TREE_CODE (incr))
12434 : {
12435 0 : case PREINCREMENT_EXPR:
12436 0 : case POSTINCREMENT_EXPR:
12437 : /* c_omp_for_incr_canonicalize_ptr() should have been
12438 : called to massage things appropriately. */
12439 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12440 0 : OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1);
12441 0 : break;
12442 0 : case PREDECREMENT_EXPR:
12443 0 : case POSTDECREMENT_EXPR:
12444 : /* c_omp_for_incr_canonicalize_ptr() should have been
12445 : called to massage things appropriately. */
12446 0 : gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl)));
12447 0 : OMP_CLAUSE_LINEAR_STEP (c)
12448 0 : = build_int_cst (TREE_TYPE (decl), -1);
12449 0 : break;
12450 4 : case MODIFY_EXPR:
12451 4 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12452 4 : incr = TREE_OPERAND (incr, 1);
12453 4 : switch (TREE_CODE (incr))
12454 : {
12455 4 : case PLUS_EXPR:
12456 4 : if (TREE_OPERAND (incr, 1) == decl)
12457 0 : step = TREE_OPERAND (incr, 0);
12458 : else
12459 4 : step = TREE_OPERAND (incr, 1);
12460 : break;
12461 0 : case MINUS_EXPR:
12462 0 : case POINTER_PLUS_EXPR:
12463 0 : gcc_assert (TREE_OPERAND (incr, 0) == decl);
12464 0 : step = TREE_OPERAND (incr, 1);
12465 0 : break;
12466 0 : default:
12467 0 : gcc_unreachable ();
12468 : }
12469 4 : stept = TREE_TYPE (decl);
12470 4 : if (INDIRECT_TYPE_P (stept))
12471 0 : stept = sizetype;
12472 4 : step = fold_convert (stept, step);
12473 4 : if (TREE_CODE (incr) == MINUS_EXPR)
12474 0 : step = fold_build1 (NEGATE_EXPR, stept, step);
12475 4 : OMP_CLAUSE_LINEAR_STEP (c) = step;
12476 4 : break;
12477 0 : default:
12478 0 : gcc_unreachable ();
12479 : }
12480 : }
12481 : /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
12482 : clauses, we need copy ctor for those rather than default ctor,
12483 : plus as for other lastprivates assignment op and dtor. */
12484 19906 : if (code == OMP_LOOP && !processing_template_decl)
12485 1993 : for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
12486 1285 : if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
12487 204 : && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
12488 1307 : && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
12489 : false, true, true, true))
12490 0 : CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
12491 :
12492 : return omp_for;
12493 21246 : }
12494 :
12495 : /* Code walker for finish_omp_for_block: extract binding of DP->var
12496 : from its current block and move it to a new BIND_EXPR DP->b
12497 : surrounding the body of DP->omp_for. */
12498 :
12499 : struct fofb_data {
12500 : tree var;
12501 : tree b;
12502 : tree omp_for;
12503 : };
12504 :
12505 : static tree
12506 389 : finish_omp_for_block_walker (tree *tp, int *walk_subtrees, void *dp)
12507 : {
12508 389 : struct fofb_data *fofb = (struct fofb_data *)dp;
12509 389 : if (TREE_CODE (*tp) == BIND_EXPR)
12510 578 : for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
12511 : {
12512 576 : if (*p == fofb->var)
12513 : {
12514 363 : *p = DECL_CHAIN (*p);
12515 363 : if (fofb->b == NULL_TREE)
12516 : {
12517 214 : fofb->b = make_node (BLOCK);
12518 214 : fofb->b = build3 (BIND_EXPR, void_type_node, NULL_TREE,
12519 214 : OMP_FOR_BODY (fofb->omp_for), fofb->b);
12520 214 : TREE_SIDE_EFFECTS (fofb->b) = 1;
12521 214 : OMP_FOR_BODY (fofb->omp_for) = fofb->b;
12522 : }
12523 363 : DECL_CHAIN (fofb->var) = BIND_EXPR_VARS (fofb->b);
12524 363 : BIND_EXPR_VARS (fofb->b) = fofb->var;
12525 363 : BLOCK_VARS (BIND_EXPR_BLOCK (fofb->b)) = fofb->var;
12526 363 : BLOCK_VARS (BIND_EXPR_BLOCK (*tp)) = BIND_EXPR_VARS (*tp);
12527 363 : return *tp;
12528 : }
12529 : }
12530 26 : if (TREE_CODE (*tp) != BIND_EXPR && TREE_CODE (*tp) != STATEMENT_LIST)
12531 22 : *walk_subtrees = false;
12532 : return NULL_TREE;
12533 : }
12534 :
12535 : /* Fix up range for decls. Those decls were pushed into BIND's
12536 : BIND_EXPR_VARS, or that of a nested BIND_EXPR inside its body,
12537 : and need to be moved into a new BIND_EXPR surrounding OMP_FOR's body
12538 : so that processing of combined loop directives can find them. */
12539 : tree
12540 14665 : finish_omp_for_block (tree bind, tree omp_for)
12541 : {
12542 14665 : if (omp_for == NULL_TREE
12543 14618 : || !OMP_FOR_ORIG_DECLS (omp_for)
12544 28693 : || bind == NULL_TREE)
12545 637 : return bind;
12546 14028 : struct fofb_data fofb;
12547 14028 : fofb.b = NULL_TREE;
12548 14028 : fofb.omp_for = omp_for;
12549 33583 : for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (omp_for)); i++)
12550 19555 : if (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i)
12551 19333 : && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i))
12552 : == TREE_LIST)
12553 20386 : && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)))
12554 : {
12555 237 : tree v = TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i));
12556 602 : for (int j = 2; j < TREE_VEC_LENGTH (v); j++)
12557 : {
12558 365 : fofb.var = TREE_VEC_ELT (v, j);
12559 365 : cp_walk_tree (&bind, finish_omp_for_block_walker,
12560 : (void *)&fofb, NULL);
12561 : }
12562 : }
12563 14028 : return bind;
12564 : }
12565 :
12566 : void
12567 3345 : finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode,
12568 : tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r,
12569 : tree clauses, enum omp_memory_order mo, bool weak)
12570 : {
12571 3345 : tree orig_lhs;
12572 3345 : tree orig_rhs;
12573 3345 : tree orig_v;
12574 3345 : tree orig_lhs1;
12575 3345 : tree orig_rhs1;
12576 3345 : tree orig_r;
12577 3345 : bool dependent_p;
12578 3345 : tree stmt;
12579 :
12580 3345 : orig_lhs = lhs;
12581 3345 : orig_rhs = rhs;
12582 3345 : orig_v = v;
12583 3345 : orig_lhs1 = lhs1;
12584 3345 : orig_rhs1 = rhs1;
12585 3345 : orig_r = r;
12586 3345 : dependent_p = false;
12587 3345 : stmt = NULL_TREE;
12588 :
12589 : /* Even in a template, we can detect invalid uses of the atomic
12590 : pragma if neither LHS nor RHS is type-dependent. */
12591 3345 : if (processing_template_decl)
12592 : {
12593 600 : dependent_p = (type_dependent_expression_p (lhs)
12594 237 : || (rhs && type_dependent_expression_p (rhs))
12595 234 : || (v && type_dependent_expression_p (v))
12596 234 : || (lhs1 && type_dependent_expression_p (lhs1))
12597 234 : || (rhs1 && type_dependent_expression_p (rhs1))
12598 834 : || (r
12599 25 : && r != void_list_node
12600 16 : && type_dependent_expression_p (r)));
12601 600 : if (clauses)
12602 : {
12603 30 : gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE
12604 : && OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT
12605 : && OMP_CLAUSE_CHAIN (clauses) == NULL_TREE);
12606 30 : if (type_dependent_expression_p (OMP_CLAUSE_HINT_EXPR (clauses))
12607 30 : || TREE_CODE (OMP_CLAUSE_HINT_EXPR (clauses)) != INTEGER_CST)
12608 : dependent_p = true;
12609 : }
12610 : }
12611 576 : if (!dependent_p)
12612 : {
12613 2961 : bool swapped = false;
12614 2961 : if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs))
12615 : {
12616 143 : std::swap (rhs, rhs1);
12617 143 : swapped = !commutative_tree_code (opcode);
12618 : }
12619 2961 : if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1))
12620 : {
12621 0 : if (code == OMP_ATOMIC)
12622 0 : error ("%<#pragma omp atomic update%> uses two different "
12623 : "expressions for memory");
12624 : else
12625 0 : error ("%<#pragma omp atomic capture%> uses two different "
12626 : "expressions for memory");
12627 : return;
12628 : }
12629 2961 : if (lhs1 && !cp_tree_equal (lhs, lhs1))
12630 : {
12631 0 : if (code == OMP_ATOMIC)
12632 0 : error ("%<#pragma omp atomic update%> uses two different "
12633 : "expressions for memory");
12634 : else
12635 0 : error ("%<#pragma omp atomic capture%> uses two different "
12636 : "expressions for memory");
12637 : return;
12638 : }
12639 5922 : stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs,
12640 : v, lhs1, rhs1, r, swapped, mo, weak,
12641 2961 : processing_template_decl != 0);
12642 2961 : if (stmt == error_mark_node)
12643 : return;
12644 : }
12645 3315 : if (processing_template_decl)
12646 : {
12647 591 : if (code == OMP_ATOMIC_READ)
12648 : {
12649 167 : stmt = build_min_nt_loc (loc, OMP_ATOMIC_READ, orig_lhs);
12650 167 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12651 167 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12652 : }
12653 : else
12654 : {
12655 424 : if (opcode == NOP_EXPR)
12656 35 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs);
12657 389 : else if (opcode == COND_EXPR)
12658 : {
12659 124 : stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs);
12660 124 : if (orig_r)
12661 50 : stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r,
12662 : stmt);
12663 124 : stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1,
12664 : orig_lhs);
12665 124 : orig_rhs1 = NULL_TREE;
12666 : }
12667 : else
12668 265 : stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs);
12669 424 : if (orig_rhs1)
12670 182 : stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1),
12671 : COMPOUND_EXPR, orig_rhs1, stmt);
12672 424 : if (code != OMP_ATOMIC)
12673 : {
12674 233 : stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt);
12675 233 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12676 233 : OMP_ATOMIC_WEAK (stmt) = weak;
12677 233 : stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt);
12678 : }
12679 : }
12680 591 : stmt = build2 (OMP_ATOMIC, void_type_node,
12681 : clauses ? clauses : integer_zero_node, stmt);
12682 591 : OMP_ATOMIC_MEMORY_ORDER (stmt) = mo;
12683 591 : OMP_ATOMIC_WEAK (stmt) = weak;
12684 591 : SET_EXPR_LOCATION (stmt, loc);
12685 : }
12686 :
12687 : /* Avoid -Wunused-value warnings here, the whole construct has side-effects
12688 : and even if it might be wrapped from fold-const.cc or c-omp.cc wrapped
12689 : in some tree that appears to be unused, the value is not unused. */
12690 3315 : warning_sentinel w (warn_unused_value);
12691 3315 : finish_expr_stmt (stmt);
12692 3315 : }
12693 :
12694 : void
12695 359 : finish_omp_barrier (void)
12696 : {
12697 359 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
12698 359 : releasing_vec vec;
12699 359 : vec->quick_push (build_int_cst (integer_type_node, GOMP_BARRIER_EXPLICIT));
12700 359 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12701 359 : finish_expr_stmt (stmt);
12702 359 : }
12703 :
12704 : void
12705 397 : finish_omp_depobj (location_t loc, tree depobj,
12706 : enum omp_clause_depend_kind kind, tree clause)
12707 : {
12708 397 : if (!error_operand_p (depobj) && !type_dependent_expression_p (depobj))
12709 : {
12710 343 : if (!lvalue_p (depobj))
12711 : {
12712 6 : error_at (EXPR_LOC_OR_LOC (depobj, loc),
12713 : "%<depobj%> expression is not lvalue expression");
12714 6 : depobj = error_mark_node;
12715 : }
12716 : }
12717 :
12718 397 : if (processing_template_decl)
12719 : {
12720 114 : if (clause == NULL_TREE)
12721 47 : clause = build_int_cst (integer_type_node, kind);
12722 114 : add_stmt (build_min_nt_loc (loc, OMP_DEPOBJ, depobj, clause));
12723 114 : return;
12724 : }
12725 :
12726 283 : if (!error_operand_p (depobj))
12727 : {
12728 274 : tree addr = cp_build_addr_expr (depobj, tf_warning_or_error);
12729 274 : if (addr == error_mark_node)
12730 : depobj = error_mark_node;
12731 : else
12732 274 : depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR,
12733 : tf_warning_or_error);
12734 : }
12735 :
12736 283 : c_finish_omp_depobj (loc, depobj, kind, clause);
12737 : }
12738 :
12739 : void
12740 162 : finish_omp_flush (int mo)
12741 : {
12742 162 : tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
12743 162 : releasing_vec vec;
12744 162 : if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST)
12745 : {
12746 54 : fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE);
12747 54 : vec->quick_push (build_int_cst (integer_type_node, mo));
12748 : }
12749 162 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12750 162 : finish_expr_stmt (stmt);
12751 162 : }
12752 :
12753 : void
12754 111 : finish_omp_taskwait (void)
12755 : {
12756 111 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
12757 111 : releasing_vec vec;
12758 111 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12759 111 : finish_expr_stmt (stmt);
12760 111 : }
12761 :
12762 : void
12763 16 : finish_omp_taskyield (void)
12764 : {
12765 16 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
12766 16 : releasing_vec vec;
12767 16 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12768 16 : finish_expr_stmt (stmt);
12769 16 : }
12770 :
12771 : void
12772 596 : finish_omp_cancel (tree clauses)
12773 : {
12774 596 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL);
12775 596 : int mask = 0;
12776 596 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12777 : mask = 1;
12778 414 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12779 : mask = 2;
12780 285 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12781 : mask = 4;
12782 164 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12783 : mask = 8;
12784 : else
12785 : {
12786 0 : error ("%<#pragma omp cancel%> must specify one of "
12787 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12788 0 : return;
12789 : }
12790 596 : releasing_vec vec;
12791 596 : tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF);
12792 596 : if (ifc != NULL_TREE)
12793 : {
12794 70 : if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK
12795 70 : && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST)
12796 6 : error_at (OMP_CLAUSE_LOCATION (ifc),
12797 : "expected %<cancel%> %<if%> clause modifier");
12798 : else
12799 : {
12800 64 : tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF);
12801 64 : if (ifc2 != NULL_TREE)
12802 : {
12803 3 : gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST
12804 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK
12805 : && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST);
12806 3 : error_at (OMP_CLAUSE_LOCATION (ifc2),
12807 : "expected %<cancel%> %<if%> clause modifier");
12808 : }
12809 : }
12810 :
12811 70 : if (!processing_template_decl)
12812 61 : ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc));
12813 : else
12814 9 : ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR,
12815 9 : OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK,
12816 : integer_zero_node, ERROR_MARK,
12817 : NULL_TREE, NULL, tf_warning_or_error);
12818 : }
12819 : else
12820 526 : ifc = boolean_true_node;
12821 596 : vec->quick_push (build_int_cst (integer_type_node, mask));
12822 596 : vec->quick_push (ifc);
12823 596 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12824 596 : finish_expr_stmt (stmt);
12825 596 : }
12826 :
12827 : void
12828 494 : finish_omp_cancellation_point (tree clauses)
12829 : {
12830 494 : tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT);
12831 494 : int mask = 0;
12832 494 : if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL))
12833 : mask = 1;
12834 366 : else if (omp_find_clause (clauses, OMP_CLAUSE_FOR))
12835 : mask = 2;
12836 261 : else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS))
12837 : mask = 4;
12838 156 : else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP))
12839 : mask = 8;
12840 : else
12841 : {
12842 3 : error ("%<#pragma omp cancellation point%> must specify one of "
12843 : "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses");
12844 3 : return;
12845 : }
12846 491 : releasing_vec vec
12847 491 : = make_tree_vector_single (build_int_cst (integer_type_node, mask));
12848 491 : tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error);
12849 491 : finish_expr_stmt (stmt);
12850 491 : }
12851 :
12852 : /* Begin a __transaction_atomic or __transaction_relaxed statement.
12853 : If PCOMPOUND is non-null, this is for a function-transaction-block, and we
12854 : should create an extra compound stmt. */
12855 :
12856 : tree
12857 303 : begin_transaction_stmt (location_t loc, tree *pcompound, int flags)
12858 : {
12859 303 : tree r;
12860 :
12861 303 : if (pcompound)
12862 21 : *pcompound = begin_compound_stmt (0);
12863 :
12864 303 : r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE);
12865 :
12866 : /* Only add the statement to the function if support enabled. */
12867 303 : if (flag_tm)
12868 297 : add_stmt (r);
12869 : else
12870 12 : error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0
12871 : ? G_("%<__transaction_relaxed%> without "
12872 : "transactional memory support enabled")
12873 : : G_("%<__transaction_atomic%> without "
12874 : "transactional memory support enabled")));
12875 :
12876 303 : TRANSACTION_EXPR_BODY (r) = push_stmt_list ();
12877 303 : TREE_SIDE_EFFECTS (r) = 1;
12878 303 : return r;
12879 : }
12880 :
12881 : /* End a __transaction_atomic or __transaction_relaxed statement.
12882 : If COMPOUND_STMT is non-null, this is for a function-transaction-block,
12883 : and we should end the compound. If NOEX is non-NULL, we wrap the body in
12884 : a MUST_NOT_THROW_EXPR with NOEX as condition. */
12885 :
12886 : void
12887 303 : finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
12888 : {
12889 303 : TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt));
12890 303 : TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0;
12891 303 : TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0;
12892 303 : TRANSACTION_EXPR_IS_STMT (stmt) = 1;
12893 :
12894 : /* noexcept specifications are not allowed for function transactions. */
12895 303 : gcc_assert (!(noex && compound_stmt));
12896 303 : if (noex)
12897 : {
12898 51 : tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt),
12899 : noex);
12900 51 : protected_set_expr_location
12901 51 : (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt)));
12902 51 : TREE_SIDE_EFFECTS (body) = 1;
12903 51 : TRANSACTION_EXPR_BODY (stmt) = body;
12904 : }
12905 :
12906 303 : if (compound_stmt)
12907 21 : finish_compound_stmt (compound_stmt);
12908 303 : }
12909 :
12910 : /* Build a __transaction_atomic or __transaction_relaxed expression. If
12911 : NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as
12912 : condition. */
12913 :
12914 : tree
12915 116 : build_transaction_expr (location_t loc, tree expr, int flags, tree noex)
12916 : {
12917 116 : tree ret;
12918 116 : if (noex)
12919 : {
12920 57 : expr = build_must_not_throw_expr (expr, noex);
12921 57 : protected_set_expr_location (expr, loc);
12922 57 : TREE_SIDE_EFFECTS (expr) = 1;
12923 : }
12924 116 : ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr);
12925 116 : if (flags & TM_STMT_ATTR_RELAXED)
12926 4 : TRANSACTION_EXPR_RELAXED (ret) = 1;
12927 116 : TREE_SIDE_EFFECTS (ret) = 1;
12928 116 : SET_EXPR_LOCATION (ret, loc);
12929 116 : return ret;
12930 : }
12931 :
12932 : void
12933 101500 : init_cp_semantics (void)
12934 : {
12935 101500 : }
12936 :
12937 :
12938 : /* Get constant string at LOCATION. Returns true if successful,
12939 : otherwise false. */
12940 :
12941 : bool
12942 11450609 : cexpr_str::type_check (location_t location, bool allow_char8_t /*=false*/)
12943 : {
12944 11450609 : tsubst_flags_t complain = tf_warning_or_error;
12945 :
12946 11450609 : if (message == NULL_TREE
12947 11450609 : || message == error_mark_node
12948 22901215 : || check_for_bare_parameter_packs (message))
12949 : return false;
12950 :
12951 11450606 : if (TREE_CODE (message) != STRING_CST
12952 11450606 : && !type_dependent_expression_p (message))
12953 : {
12954 1053 : message_sz
12955 1053 : = finish_class_member_access_expr (message,
12956 : get_identifier ("size"),
12957 : false, complain);
12958 1053 : if (message_sz != error_mark_node)
12959 952 : message_data
12960 952 : = finish_class_member_access_expr (message,
12961 : get_identifier ("data"),
12962 : false, complain);
12963 1053 : if (message_sz == error_mark_node || message_data == error_mark_node)
12964 : {
12965 139 : error_at (location, "constexpr string must be a string "
12966 : "literal or object with %<size%> and "
12967 : "%<data%> members");
12968 322 : return false;
12969 : }
12970 914 : releasing_vec size_args, data_args;
12971 914 : message_sz = finish_call_expr (message_sz, &size_args, false, false,
12972 : complain);
12973 914 : message_data = finish_call_expr (message_data, &data_args, false, false,
12974 : complain);
12975 914 : if (message_sz == error_mark_node || message_data == error_mark_node)
12976 : return false;
12977 800 : message_sz = build_converted_constant_expr (size_type_node, message_sz,
12978 : complain);
12979 800 : if (message_sz == error_mark_node)
12980 : {
12981 15 : error_at (location, "constexpr string %<size()%> "
12982 : "must be implicitly convertible to "
12983 : "%<std::size_t%>");
12984 15 : return false;
12985 : }
12986 :
12987 785 : if (allow_char8_t
12988 74 : && POINTER_TYPE_P (TREE_TYPE (message_data))
12989 74 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
12990 74 : == char8_type_node)
12991 805 : && (TYPE_QUALS (TREE_TYPE (TREE_TYPE (message_data)))
12992 : == TYPE_QUAL_CONST))
12993 : return true;
12994 :
12995 765 : message_data = build_converted_constant_expr (const_string_type_node,
12996 : message_data, complain);
12997 765 : if (message_data == error_mark_node)
12998 : {
12999 34 : error_at (location, "constexpr string %<data()%> "
13000 : "must be implicitly convertible to "
13001 : "%<const char*%>");
13002 34 : return false;
13003 : }
13004 914 : }
13005 : return true;
13006 : }
13007 :
13008 : /* Extract constant string at LOCATON into output string STR.
13009 : Returns true if successful, otherwise false. */
13010 :
13011 : bool
13012 405 : cexpr_str::extract (location_t location, tree &str)
13013 : {
13014 405 : const char *msg;
13015 405 : int len;
13016 405 : if (!extract (location, msg, len))
13017 : return false;
13018 343 : str = build_string (len, msg);
13019 343 : return true;
13020 : }
13021 :
13022 : /* Extract constant string at LOCATION into output string MSG with LEN.
13023 : Returns true if successful, otherwise false. */
13024 :
13025 : bool
13026 2705 : cexpr_str::extract (location_t location, const char * &msg, int &len,
13027 : const constexpr_ctx *ctx /* = NULL */,
13028 : bool *non_constant_p /* = NULL */,
13029 : bool *overflow_p /* = NULL */,
13030 : tree *jump_target /* = NULL */)
13031 : {
13032 2705 : tsubst_flags_t complain = tf_warning_or_error;
13033 :
13034 2705 : msg = NULL;
13035 2705 : if (message_sz && message_data)
13036 : {
13037 677 : tree msz;
13038 677 : if (ctx)
13039 : {
13040 110 : msz = cxx_eval_constant_expression (ctx, message_sz, vc_prvalue,
13041 : non_constant_p, overflow_p,
13042 : jump_target);
13043 110 : if (*jump_target || *non_constant_p)
13044 : return false;
13045 : }
13046 : else
13047 567 : msz = cxx_constant_value (message_sz, NULL_TREE, complain);
13048 669 : if (!tree_fits_uhwi_p (msz))
13049 : {
13050 35 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
13051 35 : error_at (location,
13052 : "constexpr string %<size()%> "
13053 : "must be a constant expression");
13054 : return false;
13055 : }
13056 634 : else if ((unsigned HOST_WIDE_INT) (int) tree_to_uhwi (msz)
13057 : != tree_to_uhwi (msz))
13058 : {
13059 0 : if (!ctx || !cxx_constexpr_quiet_p (ctx))
13060 0 : error_at (location,
13061 : "constexpr string message %<size()%> "
13062 : "%qE too large", msz);
13063 : return false;
13064 : }
13065 634 : len = tree_to_uhwi (msz);
13066 634 : tree data;
13067 634 : if (ctx)
13068 : {
13069 102 : data = cxx_eval_constant_expression (ctx, message_data, vc_prvalue,
13070 : non_constant_p, overflow_p,
13071 : jump_target);
13072 102 : if (*jump_target || *non_constant_p)
13073 : return false;
13074 94 : STRIP_NOPS (data);
13075 94 : if (TREE_CODE (data) != ADDR_EXPR)
13076 : {
13077 0 : unhandled:
13078 0 : if (!cxx_constexpr_quiet_p (ctx))
13079 0 : error_at (location, "unhandled return from %<data()%>");
13080 : return false;
13081 : }
13082 94 : tree str = TREE_OPERAND (data, 0);
13083 94 : unsigned HOST_WIDE_INT off = 0;
13084 94 : if (TREE_CODE (str) == ARRAY_REF
13085 94 : && tree_fits_uhwi_p (TREE_OPERAND (str, 1)))
13086 : {
13087 12 : off = tree_to_uhwi (TREE_OPERAND (str, 1));
13088 12 : str = TREE_OPERAND (str, 0);
13089 : }
13090 94 : str = cxx_eval_constant_expression (ctx, str, vc_prvalue,
13091 : non_constant_p, overflow_p,
13092 : jump_target);
13093 94 : if (*jump_target || *non_constant_p)
13094 : return false;
13095 94 : if (TREE_CODE (str) == STRING_CST)
13096 : {
13097 84 : if (TREE_STRING_LENGTH (str) < len
13098 84 : || (unsigned) TREE_STRING_LENGTH (str) < off
13099 168 : || (unsigned) TREE_STRING_LENGTH (str) < off + len)
13100 0 : goto unhandled;
13101 84 : msg = TREE_STRING_POINTER (str) + off;
13102 84 : goto translate;
13103 : }
13104 10 : if (TREE_CODE (str) != CONSTRUCTOR
13105 10 : || TREE_CODE (TREE_TYPE (str)) != ARRAY_TYPE)
13106 0 : goto unhandled;
13107 10 : char *b;
13108 10 : if (len < 64)
13109 10 : b = XALLOCAVEC (char, len + 1);
13110 : else
13111 : {
13112 0 : buf = XNEWVEC (char, len + 1);
13113 0 : b = buf;
13114 : }
13115 10 : msg = b;
13116 10 : memset (b, 0, len + 1);
13117 10 : tree field, value;
13118 10 : unsigned k;
13119 10 : unsigned HOST_WIDE_INT l = 0;
13120 158 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (str), k, field, value)
13121 158 : if (!tree_fits_shwi_p (value))
13122 0 : goto unhandled;
13123 158 : else if (field == NULL_TREE)
13124 : {
13125 0 : if (integer_zerop (value))
13126 : break;
13127 0 : if (l >= off && l < off + len)
13128 0 : b[l - off] = tree_to_shwi (value);
13129 0 : ++l;
13130 : }
13131 158 : else if (TREE_CODE (field) == RANGE_EXPR)
13132 : {
13133 0 : tree lo = TREE_OPERAND (field, 0);
13134 0 : tree hi = TREE_OPERAND (field, 1);
13135 0 : if (!tree_fits_uhwi_p (lo) || !tree_fits_uhwi_p (hi))
13136 0 : goto unhandled;
13137 0 : if (integer_zerop (value))
13138 : break;
13139 0 : unsigned HOST_WIDE_INT m = tree_to_uhwi (hi);
13140 0 : for (l = tree_to_uhwi (lo); l <= m; ++l)
13141 0 : if (l >= off && l < off + len)
13142 0 : b[l - off] = tree_to_shwi (value);
13143 : }
13144 158 : else if (tree_fits_uhwi_p (field))
13145 : {
13146 158 : l = tree_to_uhwi (field);
13147 158 : if (integer_zerop (value))
13148 : break;
13149 148 : if (l >= off && l < off + len)
13150 148 : b[l - off] = tree_to_shwi (value);
13151 148 : l++;
13152 : }
13153 10 : b[len] = '\0';
13154 : }
13155 : else
13156 : {
13157 532 : data = maybe_constant_value (message_data, NULL_TREE, mce_true);
13158 532 : if (!reduced_constant_expression_p (data))
13159 96 : data = NULL_TREE;
13160 532 : if (len)
13161 : {
13162 455 : if (data)
13163 381 : msg = c_getstr (data);
13164 455 : if (msg == NULL)
13165 119 : buf = XNEWVEC (char, len);
13166 1458 : for (int i = 0; i < len; ++i)
13167 : {
13168 1033 : tree t = message_data;
13169 1033 : if (i)
13170 1156 : t = build2 (POINTER_PLUS_EXPR,
13171 578 : TREE_TYPE (message_data), message_data,
13172 578 : size_int (i));
13173 1033 : t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
13174 1033 : tree t2 = cxx_constant_value (t, NULL_TREE, complain);
13175 1033 : if (!tree_fits_shwi_p (t2))
13176 : {
13177 30 : error_at (location,
13178 : "constexpr string %<data()[%d]%> "
13179 : "must be a constant expression", i);
13180 30 : return false;
13181 : }
13182 1003 : if (msg == NULL)
13183 362 : buf[i] = tree_to_shwi (t2);
13184 : /* If c_getstr worked, just verify the first and
13185 : last characters using constant evaluation. */
13186 641 : else if (len > 2 && i == 0)
13187 268 : i = len - 2;
13188 : }
13189 425 : if (msg == NULL)
13190 104 : msg = buf;
13191 : }
13192 77 : else if (!data)
13193 : {
13194 : /* We don't have any function to test whether some
13195 : expression is a core constant expression. So, instead
13196 : test whether (message.data (), 0) is a constant
13197 : expression. */
13198 22 : data = build2 (COMPOUND_EXPR, integer_type_node,
13199 : message_data, integer_zero_node);
13200 22 : tree t = cxx_constant_value (data, NULL_TREE, complain);
13201 22 : if (!integer_zerop (t))
13202 : {
13203 22 : error_at (location,
13204 : "constexpr string %<data()%> "
13205 : "must be a core constant expression");
13206 22 : return false;
13207 : }
13208 : }
13209 : }
13210 : }
13211 : else
13212 : {
13213 2028 : tree eltype = TREE_TYPE (TREE_TYPE (message));
13214 2028 : int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (eltype));
13215 2028 : msg = TREE_STRING_POINTER (message);
13216 2028 : len = TREE_STRING_LENGTH (message) / sz - 1;
13217 : }
13218 2602 : translate:
13219 2602 : if ((message_sz && message_data) || ctx)
13220 : {
13221 : /* Convert the string from execution charset to SOURCE_CHARSET. */
13222 768 : cpp_string istr, ostr;
13223 768 : istr.len = len;
13224 768 : istr.text = (const unsigned char *) msg;
13225 768 : enum cpp_ttype type = CPP_STRING;
13226 768 : if (message_sz && message_data)
13227 : {
13228 574 : if (POINTER_TYPE_P (TREE_TYPE (message_data))
13229 574 : && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message_data)))
13230 574 : == char8_type_node))
13231 : type = CPP_UTF8STRING;
13232 : }
13233 194 : else if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (message)))
13234 194 : == char8_type_node)
13235 768 : type = CPP_UTF8STRING;
13236 768 : if (len == 0)
13237 : ;
13238 643 : else if (!cpp_translate_string (parse_in, &istr, &ostr, type,
13239 : true))
13240 : {
13241 0 : if (type == CPP_UTF8STRING)
13242 0 : error_at (location, "could not convert constexpr string from "
13243 : "UTF-8 encoding to source character "
13244 : "set");
13245 : else
13246 0 : error_at (location, "could not convert constexpr string from "
13247 : "ordinary literal encoding to source character "
13248 : "set");
13249 0 : return false;
13250 : }
13251 : else
13252 : {
13253 643 : if (buf)
13254 104 : XDELETEVEC (buf);
13255 643 : msg = buf = const_cast <char *> ((const char *) ostr.text);
13256 643 : len = ostr.len;
13257 : }
13258 : }
13259 :
13260 : return true;
13261 : }
13262 :
13263 : /* Build a STATIC_ASSERT for a static assertion with the condition
13264 : CONDITION and the message text MESSAGE. LOCATION is the location
13265 : of the static assertion in the source code. When MEMBER_P, this
13266 : static assertion is a member of a class. If SHOW_EXPR_P is true,
13267 : print the condition (because it was instantiation-dependent).
13268 : If CONSTEVAL_BLOCK_P is true, this static assertion represents
13269 : a consteval block. */
13270 :
13271 : void
13272 11449918 : finish_static_assert (tree condition, tree message, location_t location,
13273 : bool member_p, bool show_expr_p,
13274 : bool consteval_block_p/*=false*/)
13275 : {
13276 11449918 : tsubst_flags_t complain = tf_warning_or_error;
13277 :
13278 11449918 : if (condition == NULL_TREE
13279 11449918 : || condition == error_mark_node)
13280 4846675 : return;
13281 :
13282 11449692 : if (check_for_bare_parameter_packs (condition))
13283 : return;
13284 :
13285 11449689 : cexpr_str cstr(message);
13286 11449689 : if (!cstr.type_check (location))
13287 : return;
13288 :
13289 : /* Save the condition in case it was a concept check. */
13290 11449595 : tree orig_condition = condition;
13291 :
13292 11449595 : if (instantiation_dependent_expression_p (condition)
13293 11449595 : || instantiation_dependent_expression_p (message))
13294 : {
13295 : /* We're in a template; build a STATIC_ASSERT and put it in
13296 : the right place. */
13297 4845811 : defer:
13298 4845811 : tree assertion = make_node (STATIC_ASSERT);
13299 4845811 : STATIC_ASSERT_CONDITION (assertion) = orig_condition;
13300 4845811 : STATIC_ASSERT_MESSAGE (assertion) = cstr.message;
13301 4845811 : STATIC_ASSERT_SOURCE_LOCATION (assertion) = location;
13302 4845811 : CONSTEVAL_BLOCK_P (assertion) = consteval_block_p;
13303 :
13304 4845811 : if (member_p)
13305 2486821 : maybe_add_class_template_decl_list (current_class_type,
13306 : assertion,
13307 : /*friend_p=*/0);
13308 : else
13309 2358990 : add_stmt (assertion);
13310 :
13311 : return;
13312 : }
13313 :
13314 : /* Evaluate the consteval { }. This must be done only once. */
13315 6609809 : if (consteval_block_p)
13316 : {
13317 516 : cxx_constant_value (condition);
13318 516 : return;
13319 : }
13320 :
13321 : /* Fold the expression and convert it to a boolean value. */
13322 6609293 : condition = contextual_conv_bool (condition, complain);
13323 6609293 : condition = fold_non_dependent_expr (condition, complain,
13324 : /*manifestly_const_eval=*/true);
13325 :
13326 6609291 : if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
13327 : /* Do nothing; the condition is satisfied. */
13328 : ;
13329 : else
13330 : {
13331 8887 : iloc_sentinel ils (location);
13332 :
13333 8887 : if (integer_zerop (condition))
13334 : {
13335 : /* CWG2518: static_assert failure in a template is not IFNDR. */
13336 8021 : if (processing_template_decl)
13337 6025 : goto defer;
13338 :
13339 1996 : int len;
13340 1996 : const char *msg = NULL;
13341 1996 : if (!cstr.extract (location, msg, len))
13342 25 : return;
13343 :
13344 : /* See if we can find which clause was failing (for logical AND). */
13345 1971 : tree bad = find_failing_clause (NULL, orig_condition);
13346 : /* If not, or its location is unusable, fall back to the previous
13347 : location. */
13348 1971 : location_t cloc = cp_expr_loc_or_loc (bad, location);
13349 :
13350 1971 : auto_diagnostic_group d;
13351 :
13352 : /* Report the error. */
13353 1971 : if (len == 0)
13354 1259 : error_at (cloc, "static assertion failed");
13355 : else
13356 712 : error_at (cloc, "static assertion failed: %.*s", len, msg);
13357 :
13358 1971 : diagnose_failing_condition (bad, cloc, show_expr_p);
13359 :
13360 : /* Suppress -Wreturn-type for functions with failed static_asserts.
13361 : Otherwise templates like:
13362 : if constexpr (whatever)
13363 : return something (args);
13364 : else
13365 : static_assert (false, "explanation");
13366 : get a useless extra -Wreturn-type warning. */
13367 1971 : if (current_function_decl)
13368 756 : suppress_warning (current_function_decl, OPT_Wreturn_type);
13369 1971 : }
13370 866 : else if (condition && condition != error_mark_node)
13371 : {
13372 860 : error ("non-constant condition for static assertion");
13373 860 : if (require_rvalue_constant_expression (condition))
13374 798 : cxx_constant_value (condition);
13375 : }
13376 8887 : }
13377 11449687 : }
13378 :
13379 : /* Implements the C++0x decltype keyword. Returns the type of EXPR,
13380 : suitable for use as a type-specifier.
13381 :
13382 : ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an
13383 : id-expression or a class member access, FALSE when it was parsed as
13384 : a full expression. */
13385 :
13386 : tree
13387 44135364 : finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
13388 : tsubst_flags_t complain)
13389 : {
13390 44135364 : tree type = NULL_TREE;
13391 :
13392 44135364 : if (!expr || error_operand_p (expr))
13393 242804 : return error_mark_node;
13394 :
13395 43892560 : if (TYPE_P (expr)
13396 43892560 : || TREE_CODE (expr) == TYPE_DECL
13397 87785100 : || (TREE_CODE (expr) == BIT_NOT_EXPR
13398 16503 : && TYPE_P (TREE_OPERAND (expr, 0))))
13399 : {
13400 29 : if (complain & tf_error)
13401 29 : error ("argument to %<decltype%> must be an expression");
13402 29 : return error_mark_node;
13403 : }
13404 :
13405 : /* decltype is an unevaluated context. */
13406 43892531 : cp_unevaluated u;
13407 :
13408 43892531 : processing_template_decl_sentinel ptds (/*reset=*/false);
13409 :
13410 : /* Depending on the resolution of DR 1172, we may later need to distinguish
13411 : instantiation-dependent but not type-dependent expressions so that, say,
13412 : A<decltype(sizeof(T))>::U doesn't require 'typename'. */
13413 43892531 : if (instantiation_dependent_uneval_expression_p (expr))
13414 : {
13415 7432976 : dependent:
13416 7433552 : type = cxx_make_type (DECLTYPE_TYPE);
13417 7433552 : DECLTYPE_TYPE_EXPR (type) = expr;
13418 14867104 : DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
13419 7433552 : = id_expression_or_member_access_p;
13420 7433552 : SET_TYPE_STRUCTURAL_EQUALITY (type);
13421 :
13422 7433552 : return type;
13423 : }
13424 36459555 : else if (processing_template_decl)
13425 : {
13426 7449 : expr = instantiate_non_dependent_expr (expr, complain|tf_decltype);
13427 7449 : if (expr == error_mark_node)
13428 : return error_mark_node;
13429 : /* Keep processing_template_decl cleared for the rest of the function
13430 : (for sake of the call to lvalue_kind below, which handles templated
13431 : and non-templated COND_EXPR differently). */
13432 7412 : processing_template_decl = 0;
13433 : }
13434 :
13435 : /* The type denoted by decltype(e) is defined as follows: */
13436 :
13437 36459518 : expr = resolve_nondeduced_context (expr, complain);
13438 36459518 : if (!mark_single_function (expr, complain))
13439 0 : return error_mark_node;
13440 :
13441 36459518 : if (invalid_nonstatic_memfn_p (input_location, expr, complain))
13442 18 : return error_mark_node;
13443 :
13444 36459500 : if (type_unknown_p (expr))
13445 : {
13446 18 : if (complain & tf_error)
13447 6 : error ("%<decltype%> cannot resolve address of overloaded function");
13448 18 : return error_mark_node;
13449 : }
13450 :
13451 36459482 : if (id_expression_or_member_access_p)
13452 : {
13453 : /* If e is an id-expression or a class member access (5.2.5
13454 : [expr.ref]), decltype(e) is defined as the type of the entity
13455 : named by e. If there is no such entity, or e names a set of
13456 : overloaded functions, the program is ill-formed. */
13457 549470 : if (identifier_p (expr))
13458 0 : expr = lookup_name (expr);
13459 :
13460 : /* If e is a constified expression inside a contract assertion,
13461 : strip the const wrapper. Per P2900R14, "For a function f with the
13462 : return type T , the result name is an lvalue of type const T , decltype(r)
13463 : is T , and decltype((r)) is const T&." */
13464 549470 : expr = strip_contract_const_wrapper (expr);
13465 :
13466 374545 : if (REFERENCE_REF_P (expr)
13467 549475 : || TREE_CODE (expr) == VIEW_CONVERT_EXPR)
13468 : /* This can happen when the expression is, e.g., "a.b". Just
13469 : look at the underlying operand. */
13470 377816 : expr = TREE_OPERAND (expr, 0);
13471 :
13472 549470 : if (TREE_CODE (expr) == OFFSET_REF
13473 549470 : || TREE_CODE (expr) == MEMBER_REF
13474 549470 : || TREE_CODE (expr) == SCOPE_REF)
13475 : /* We're only interested in the field itself. If it is a
13476 : BASELINK, we will need to see through it in the next
13477 : step. */
13478 0 : expr = TREE_OPERAND (expr, 1);
13479 :
13480 549470 : if (BASELINK_P (expr))
13481 : /* See through BASELINK nodes to the underlying function. */
13482 7 : expr = BASELINK_FUNCTIONS (expr);
13483 :
13484 : /* decltype of a decomposition name drops references in the tuple case
13485 : (unlike decltype of a normal variable) and keeps cv-qualifiers from
13486 : the containing object in the other cases (unlike decltype of a member
13487 : access expression). */
13488 549470 : if (DECL_DECOMPOSITION_P (expr))
13489 : {
13490 1449 : if (ptds.saved)
13491 : {
13492 275 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr)
13493 : || (DECL_CONTEXT (expr)
13494 : != current_function_decl));
13495 : /* DECL_HAS_VALUE_EXPR_P is always set if
13496 : processing_template_decl at least for structured bindings
13497 : within the template. If lookup_decomp_type
13498 : returns non-NULL, it is the tuple case. */
13499 275 : if (tree ret = lookup_decomp_type (expr))
13500 : return ret;
13501 191 : gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (expr));
13502 : }
13503 1365 : if (DECL_HAS_VALUE_EXPR_P (expr))
13504 : /* Expr is an array or struct subobject proxy, handle
13505 : bit-fields properly. */
13506 1021 : return unlowered_expr_type (expr);
13507 : else
13508 : /* Expr is a reference variable for the tuple case. */
13509 344 : return lookup_decomp_type (expr);
13510 : }
13511 :
13512 548021 : switch (TREE_CODE (expr))
13513 : {
13514 650 : case FIELD_DECL:
13515 650 : if (DECL_BIT_FIELD_TYPE (expr))
13516 : {
13517 : type = DECL_BIT_FIELD_TYPE (expr);
13518 : break;
13519 : }
13520 : /* Fall through for fields that aren't bitfields. */
13521 147648 : gcc_fallthrough ();
13522 :
13523 147648 : case VAR_DECL:
13524 147648 : if (is_capture_proxy (expr))
13525 : {
13526 99 : if (is_normal_capture_proxy (expr))
13527 : {
13528 21 : expr = DECL_CAPTURED_VARIABLE (expr);
13529 21 : type = TREE_TYPE (expr);
13530 : }
13531 : else
13532 : {
13533 78 : expr = DECL_VALUE_EXPR (expr);
13534 78 : gcc_assert (TREE_CODE (expr) == COMPONENT_REF);
13535 78 : expr = TREE_OPERAND (expr, 1);
13536 78 : type = TREE_TYPE (expr);
13537 : }
13538 : break;
13539 : }
13540 : /* Fall through for variables that aren't capture proxies. */
13541 536964 : gcc_fallthrough ();
13542 :
13543 536964 : case FUNCTION_DECL:
13544 536964 : case CONST_DECL:
13545 536964 : case PARM_DECL:
13546 536964 : case RESULT_DECL:
13547 536964 : case TEMPLATE_PARM_INDEX:
13548 536964 : expr = mark_type_use (expr);
13549 536964 : type = TREE_TYPE (expr);
13550 536964 : if (VAR_P (expr) && DECL_NTTP_OBJECT_P (expr))
13551 : {
13552 : /* decltype of an NTTP object is the type of the template
13553 : parameter, which is the object type modulo cv-quals. */
13554 2643 : int quals = cp_type_quals (type);
13555 2643 : gcc_checking_assert (quals & TYPE_QUAL_CONST);
13556 2643 : type = cv_unqualified (type);
13557 : }
13558 : break;
13559 :
13560 0 : case ERROR_MARK:
13561 0 : type = error_mark_node;
13562 0 : break;
13563 :
13564 3512 : case COMPONENT_REF:
13565 3512 : case COMPOUND_EXPR:
13566 3512 : mark_type_use (expr);
13567 3512 : type = is_bitfield_expr_with_lowered_type (expr);
13568 3512 : if (!type)
13569 3475 : type = TREE_TYPE (TREE_OPERAND (expr, 1));
13570 : break;
13571 :
13572 0 : case BIT_FIELD_REF:
13573 0 : gcc_unreachable ();
13574 :
13575 3501 : case INTEGER_CST:
13576 3501 : case PTRMEM_CST:
13577 : /* We can get here when the id-expression refers to an
13578 : enumerator or non-type template parameter. */
13579 3501 : type = TREE_TYPE (expr);
13580 3501 : break;
13581 :
13582 3945 : default:
13583 : /* Handle instantiated template non-type arguments. */
13584 3945 : type = TREE_TYPE (expr);
13585 3945 : break;
13586 : }
13587 : }
13588 : else
13589 : {
13590 35910012 : tree decl = STRIP_REFERENCE_REF (expr);
13591 35910012 : tree lam = current_lambda_expr ();
13592 35910012 : if (lam && outer_automatic_var_p (decl))
13593 : {
13594 : /* [expr.prim.id.unqual]/3: If naming the entity from outside of an
13595 : unevaluated operand within S would refer to an entity captured by
13596 : copy in some intervening lambda-expression, then let E be the
13597 : innermost such lambda-expression.
13598 :
13599 : If there is such a lambda-expression and if P is in E's function
13600 : parameter scope but not its parameter-declaration-clause, then the
13601 : type of the expression is the type of a class member access
13602 : expression naming the non-static data member that would be declared
13603 : for such a capture in the object parameter of the function call
13604 : operator of E." */
13605 : /* FIXME: This transformation needs to happen for all uses of an outer
13606 : local variable inside decltype, not just decltype((x)) (PR83167).
13607 : And we don't handle nested lambdas properly, where we need to
13608 : consider the outer lambdas as well (PR112926). */
13609 1379 : tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK,
13610 : LOOK_want::HIDDEN_LAMBDA);
13611 :
13612 1379 : if (cap && is_capture_proxy (cap))
13613 467 : type = TREE_TYPE (cap);
13614 912 : else if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_COPY)
13615 : {
13616 738 : type = TREE_TYPE (decl);
13617 738 : if (TYPE_REF_P (type)
13618 738 : && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
13619 36 : type = TREE_TYPE (type);
13620 : }
13621 :
13622 1205 : if (type && !TYPE_REF_P (type))
13623 : {
13624 1121 : int quals;
13625 1121 : if (current_function_decl
13626 2104 : && LAMBDA_FUNCTION_P (current_function_decl)
13627 2104 : && DECL_XOBJ_MEMBER_FUNCTION_P (current_function_decl))
13628 : {
13629 900 : tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl));
13630 900 : if (WILDCARD_TYPE_P (non_reference (obtype)))
13631 : /* We don't know what the eventual obtype quals will be. */
13632 576 : goto dependent;
13633 648 : auto direct_type = [](tree t){
13634 324 : if (INDIRECT_TYPE_P (t))
13635 162 : return TREE_TYPE (t);
13636 : return t;
13637 : };
13638 648 : quals = (cp_type_quals (type)
13639 324 : | cp_type_quals (direct_type (obtype)));
13640 : }
13641 : else
13642 : /* We are in the parameter clause, trailing return type, or
13643 : the requires clause and have no relevant c_f_decl yet. */
13644 349 : quals = (LAMBDA_EXPR_CONST_QUAL_P (lam)
13645 221 : ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED);
13646 545 : type = cp_build_qualified_type (type, quals);
13647 545 : type = build_reference_type (type);
13648 : }
13649 : }
13650 35908633 : else if (error_operand_p (expr))
13651 0 : type = error_mark_node;
13652 35908633 : else if (expr == current_class_ptr)
13653 : /* If the expression is just "this", we want the
13654 : cv-unqualified pointer for the "this" type. */
13655 0 : type = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
13656 :
13657 545 : if (!type)
13658 : {
13659 : /* Otherwise, where T is the type of e, if e is an lvalue,
13660 : decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */
13661 35908807 : cp_lvalue_kind clk = lvalue_kind (expr);
13662 35908807 : type = unlowered_expr_type (expr);
13663 35908807 : gcc_assert (!TYPE_REF_P (type));
13664 :
13665 : /* For vector types, pick a non-opaque variant. */
13666 35908807 : if (VECTOR_TYPE_P (type))
13667 4421 : type = strip_typedefs (type);
13668 :
13669 35908807 : if (clk != clk_none && !(clk & clk_class))
13670 9142850 : type = cp_build_reference_type (type, (clk & clk_rvalueref));
13671 : }
13672 : }
13673 :
13674 : return type;
13675 43892531 : }
13676 :
13677 : /* Called from trait_expr_value to evaluate either __has_nothrow_assign or
13678 : __has_nothrow_copy, depending on assign_p. Returns true iff all
13679 : the copy {ctor,assign} fns are nothrow. */
13680 :
13681 : static bool
13682 351 : classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p)
13683 : {
13684 351 : tree fns = NULL_TREE;
13685 :
13686 351 : if (assign_p || TYPE_HAS_COPY_CTOR (type))
13687 348 : fns = get_class_binding (type, assign_p ? assign_op_identifier
13688 : : ctor_identifier);
13689 :
13690 351 : bool saw_copy = false;
13691 894 : for (ovl_iterator iter (fns); iter; ++iter)
13692 : {
13693 561 : tree fn = *iter;
13694 :
13695 561 : if (copy_fn_p (fn) > 0)
13696 : {
13697 525 : saw_copy = true;
13698 525 : if (!maybe_instantiate_noexcept (fn)
13699 525 : || !TYPE_NOTHROW_P (TREE_TYPE (fn)))
13700 234 : return false;
13701 : }
13702 : }
13703 :
13704 117 : return saw_copy;
13705 : }
13706 :
13707 : /* Return true if BASE is a pointer-interconvertible base of DERIVED. */
13708 :
13709 : bool
13710 183 : pointer_interconvertible_base_of_p (tree base, tree derived,
13711 : bool explain/*=false*/)
13712 : {
13713 183 : if (base == error_mark_node || derived == error_mark_node)
13714 : return false;
13715 :
13716 183 : base = TYPE_MAIN_VARIANT (base);
13717 183 : derived = TYPE_MAIN_VARIANT (derived);
13718 183 : if (!NON_UNION_CLASS_TYPE_P (base))
13719 : {
13720 17 : if (explain)
13721 3 : inform (location_of (base),
13722 : "%qT is not a non-union class type", base);
13723 : return false;
13724 : }
13725 166 : if (!NON_UNION_CLASS_TYPE_P (derived))
13726 : {
13727 8 : if (explain)
13728 3 : inform (location_of (derived),
13729 : "%qT is not a non-union class type", derived);
13730 : return false;
13731 : }
13732 :
13733 158 : if (same_type_p (base, derived))
13734 : return true;
13735 :
13736 117 : if (!std_layout_type_p (derived))
13737 : {
13738 18 : if (explain)
13739 6 : inform (location_of (derived),
13740 : "%qT is not a standard-layout type", derived);
13741 : return false;
13742 : }
13743 :
13744 99 : if (!uniquely_derived_from_p (base, derived))
13745 : {
13746 18 : if (explain)
13747 : {
13748 : /* An ambiguous base should already be impossible due to
13749 : the std_layout_type_p check. */
13750 3 : gcc_checking_assert (!DERIVED_FROM_P (base, derived));
13751 3 : inform (location_of (derived),
13752 : "%qT is not a base of %qT", base, derived);
13753 : }
13754 : return false;
13755 : }
13756 :
13757 : return true;
13758 : }
13759 :
13760 : /* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
13761 : return true if MEMBERTYPE is the type of the first non-static data member
13762 : of TYPE or for unions of any members. */
13763 : static bool
13764 637 : first_nonstatic_data_member_p (tree type, tree membertype)
13765 : {
13766 1297 : for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
13767 : {
13768 1222 : if (TREE_CODE (field) != FIELD_DECL)
13769 135 : continue;
13770 1087 : if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
13771 60 : continue;
13772 1027 : if (DECL_FIELD_IS_BASE (field))
13773 45 : return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
13774 982 : if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13775 : {
13776 216 : if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
13777 138 : || std_layout_type_p (TREE_TYPE (field)))
13778 294 : && first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
13779 : return true;
13780 : }
13781 766 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13782 : membertype))
13783 : return true;
13784 537 : if (TREE_CODE (type) != UNION_TYPE)
13785 : return false;
13786 : }
13787 : return false;
13788 : }
13789 :
13790 : /* Fold __builtin_is_pointer_interconvertible_with_class call. */
13791 :
13792 : tree
13793 536 : fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
13794 : tree *args)
13795 : {
13796 : /* Unless users call the builtin directly, the following 3 checks should be
13797 : ensured from std::is_pointer_interconvertible_with_class function
13798 : template. */
13799 536 : if (nargs != 1)
13800 : {
13801 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13802 : "needs a single argument");
13803 6 : return boolean_false_node;
13804 : }
13805 530 : tree arg = args[0];
13806 530 : if (error_operand_p (arg))
13807 0 : return boolean_false_node;
13808 530 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
13809 : {
13810 6 : error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
13811 : "argument is not pointer to member");
13812 6 : return boolean_false_node;
13813 : }
13814 :
13815 524 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
13816 18 : return boolean_false_node;
13817 :
13818 506 : tree membertype = TREE_TYPE (TREE_TYPE (arg));
13819 506 : tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
13820 506 : if (!complete_type_or_else (basetype, NULL_TREE))
13821 3 : return boolean_false_node;
13822 :
13823 503 : if (TREE_CODE (basetype) != UNION_TYPE
13824 503 : && !std_layout_type_p (basetype))
13825 22 : return boolean_false_node;
13826 :
13827 481 : if (!first_nonstatic_data_member_p (basetype, membertype))
13828 132 : return boolean_false_node;
13829 :
13830 349 : if (TREE_CODE (arg) == PTRMEM_CST)
13831 68 : arg = cplus_expand_constant (arg);
13832 :
13833 349 : if (integer_nonzerop (arg))
13834 10 : return boolean_false_node;
13835 339 : if (integer_zerop (arg))
13836 71 : return boolean_true_node;
13837 :
13838 268 : return fold_build2 (EQ_EXPR, boolean_type_node, arg,
13839 : build_zero_cst (TREE_TYPE (arg)));
13840 : }
13841 :
13842 : /* Helper function for is_corresponding_member_aggr. Return true if
13843 : MEMBERTYPE pointer-to-data-member ARG can be found in anonymous
13844 : union or structure BASETYPE. */
13845 :
13846 : static bool
13847 90 : is_corresponding_member_union (tree basetype, tree membertype, tree arg)
13848 : {
13849 222 : for (tree field = TYPE_FIELDS (basetype); field; field = DECL_CHAIN (field))
13850 192 : if (TREE_CODE (field) != FIELD_DECL || DECL_BIT_FIELD_TYPE (field))
13851 36 : continue;
13852 156 : else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
13853 : membertype))
13854 : {
13855 48 : if (TREE_CODE (arg) != INTEGER_CST
13856 48 : || tree_int_cst_equal (arg, byte_position (field)))
13857 : return true;
13858 : }
13859 108 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
13860 : {
13861 18 : tree narg = arg;
13862 18 : if (TREE_CODE (basetype) != UNION_TYPE
13863 0 : && TREE_CODE (narg) == INTEGER_CST)
13864 0 : narg = size_binop (MINUS_EXPR, arg, byte_position (field));
13865 18 : if (is_corresponding_member_union (TREE_TYPE (field),
13866 : membertype, narg))
13867 : return true;
13868 : }
13869 : return false;
13870 : }
13871 :
13872 : /* Helper function for fold_builtin_is_corresponding_member call.
13873 : Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and
13874 : MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members,
13875 : boolean_true_node if they are corresponding members, or for
13876 : non-constant ARG2 the highest member offset for corresponding
13877 : members. */
13878 :
13879 : static tree
13880 550 : is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1,
13881 : tree arg1, tree basetype2, tree membertype2,
13882 : tree arg2)
13883 : {
13884 550 : tree field1 = TYPE_FIELDS (basetype1);
13885 550 : tree field2 = TYPE_FIELDS (basetype2);
13886 550 : tree ret = boolean_false_node;
13887 2376 : while (1)
13888 : {
13889 1463 : bool r = next_common_initial_sequence (field1, field2);
13890 1463 : if (field1 == NULL_TREE || field2 == NULL_TREE)
13891 : break;
13892 1331 : if (r
13893 1038 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field1),
13894 : membertype1)
13895 1841 : && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field2),
13896 : membertype2))
13897 : {
13898 504 : tree pos = byte_position (field1);
13899 504 : if (TREE_CODE (arg1) == INTEGER_CST
13900 504 : && tree_int_cst_equal (arg1, pos))
13901 : {
13902 92 : if (TREE_CODE (arg2) == INTEGER_CST)
13903 92 : return boolean_true_node;
13904 : return pos;
13905 : }
13906 412 : else if (TREE_CODE (arg1) != INTEGER_CST)
13907 1188 : ret = pos;
13908 : }
13909 1654 : else if (ANON_AGGR_TYPE_P (TREE_TYPE (field1))
13910 944 : && ANON_AGGR_TYPE_P (TREE_TYPE (field2)))
13911 : {
13912 117 : if ((!lookup_attribute ("no_unique_address",
13913 117 : DECL_ATTRIBUTES (field1)))
13914 117 : != !lookup_attribute ("no_unique_address",
13915 117 : DECL_ATTRIBUTES (field2)))
13916 : break;
13917 117 : if (!tree_int_cst_equal (bit_position (field1),
13918 117 : bit_position (field2)))
13919 : break;
13920 99 : bool overlap = true;
13921 99 : tree pos = byte_position (field1);
13922 99 : if (TREE_CODE (arg1) == INTEGER_CST)
13923 : {
13924 27 : tree off1 = fold_convert (sizetype, arg1);
13925 27 : tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (field1));
13926 27 : if (tree_int_cst_lt (off1, pos)
13927 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz1), off1))
13928 : overlap = false;
13929 : }
13930 99 : if (TREE_CODE (arg2) == INTEGER_CST)
13931 : {
13932 27 : tree off2 = fold_convert (sizetype, arg2);
13933 27 : tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (field2));
13934 27 : if (tree_int_cst_lt (off2, pos)
13935 27 : || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz2), off2))
13936 : overlap = false;
13937 : }
13938 87 : if (overlap
13939 87 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field1))
13940 126 : && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field2)))
13941 : {
13942 39 : tree narg1 = arg1;
13943 39 : if (TREE_CODE (arg1) == INTEGER_CST)
13944 9 : narg1 = size_binop (MINUS_EXPR,
13945 : fold_convert (sizetype, arg1), pos);
13946 39 : tree narg2 = arg2;
13947 39 : if (TREE_CODE (arg2) == INTEGER_CST)
13948 9 : narg2 = size_binop (MINUS_EXPR,
13949 : fold_convert (sizetype, arg2), pos);
13950 39 : tree t1 = TREE_TYPE (field1);
13951 39 : tree t2 = TREE_TYPE (field2);
13952 39 : tree nret = is_corresponding_member_aggr (loc, t1, membertype1,
13953 : narg1, t2, membertype2,
13954 : narg2);
13955 39 : if (nret != boolean_false_node)
13956 : {
13957 39 : if (nret == boolean_true_node)
13958 : return nret;
13959 30 : if (TREE_CODE (arg1) == INTEGER_CST)
13960 0 : return size_binop (PLUS_EXPR, nret, pos);
13961 30 : ret = size_binop (PLUS_EXPR, nret, pos);
13962 : }
13963 : }
13964 60 : else if (overlap
13965 48 : && TREE_CODE (TREE_TYPE (field1)) == UNION_TYPE
13966 108 : && TREE_CODE (TREE_TYPE (field2)) == UNION_TYPE)
13967 : {
13968 48 : tree narg1 = arg1;
13969 48 : if (TREE_CODE (arg1) == INTEGER_CST)
13970 6 : narg1 = size_binop (MINUS_EXPR,
13971 : fold_convert (sizetype, arg1), pos);
13972 48 : tree narg2 = arg2;
13973 48 : if (TREE_CODE (arg2) == INTEGER_CST)
13974 6 : narg2 = size_binop (MINUS_EXPR,
13975 : fold_convert (sizetype, arg2), pos);
13976 48 : if (is_corresponding_member_union (TREE_TYPE (field1),
13977 : membertype1, narg1)
13978 48 : && is_corresponding_member_union (TREE_TYPE (field2),
13979 : membertype2, narg2))
13980 : {
13981 24 : sorry_at (loc, "%<__builtin_is_corresponding_member%> "
13982 : "not well defined for anonymous unions");
13983 24 : return boolean_false_node;
13984 : }
13985 : }
13986 : }
13987 1188 : if (!r)
13988 : break;
13989 913 : field1 = DECL_CHAIN (field1);
13990 913 : field2 = DECL_CHAIN (field2);
13991 913 : }
13992 : return ret;
13993 : }
13994 :
13995 : /* Fold __builtin_is_corresponding_member call. */
13996 :
13997 : tree
13998 699 : fold_builtin_is_corresponding_member (location_t loc, int nargs,
13999 : tree *args)
14000 : {
14001 : /* Unless users call the builtin directly, the following 3 checks should be
14002 : ensured from std::is_corresponding_member function template. */
14003 699 : if (nargs != 2)
14004 : {
14005 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
14006 : "needs two arguments");
14007 9 : return boolean_false_node;
14008 : }
14009 690 : tree arg1 = args[0];
14010 690 : tree arg2 = args[1];
14011 690 : if (error_operand_p (arg1) || error_operand_p (arg2))
14012 0 : return boolean_false_node;
14013 711 : if (!TYPE_PTRMEM_P (TREE_TYPE (arg1))
14014 705 : || !TYPE_PTRMEM_P (TREE_TYPE (arg2)))
14015 : {
14016 9 : error_at (loc, "%<__builtin_is_corresponding_member%> "
14017 : "argument is not pointer to member");
14018 9 : return boolean_false_node;
14019 : }
14020 :
14021 681 : if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg1))
14022 681 : || !TYPE_PTRDATAMEM_P (TREE_TYPE (arg2)))
14023 15 : return boolean_false_node;
14024 :
14025 666 : tree membertype1 = TREE_TYPE (TREE_TYPE (arg1));
14026 666 : tree basetype1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg1));
14027 666 : if (!complete_type_or_else (basetype1, NULL_TREE))
14028 12 : return boolean_false_node;
14029 :
14030 654 : tree membertype2 = TREE_TYPE (TREE_TYPE (arg2));
14031 654 : tree basetype2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg2));
14032 654 : if (!complete_type_or_else (basetype2, NULL_TREE))
14033 12 : return boolean_false_node;
14034 :
14035 627 : if (!NON_UNION_CLASS_TYPE_P (basetype1)
14036 627 : || !NON_UNION_CLASS_TYPE_P (basetype2)
14037 627 : || !std_layout_type_p (basetype1)
14038 1233 : || !std_layout_type_p (basetype2))
14039 51 : return boolean_false_node;
14040 :
14041 : /* If the member types aren't layout compatible, then they
14042 : can't be corresponding members. */
14043 591 : if (!layout_compatible_type_p (membertype1, membertype2))
14044 18 : return boolean_false_node;
14045 :
14046 573 : if (TREE_CODE (arg1) == PTRMEM_CST)
14047 176 : arg1 = cplus_expand_constant (arg1);
14048 573 : if (TREE_CODE (arg2) == PTRMEM_CST)
14049 182 : arg2 = cplus_expand_constant (arg2);
14050 :
14051 573 : if (null_member_pointer_value_p (arg1)
14052 573 : || null_member_pointer_value_p (arg2))
14053 9 : return boolean_false_node;
14054 :
14055 564 : if (TREE_CODE (arg1) == INTEGER_CST
14056 182 : && TREE_CODE (arg2) == INTEGER_CST
14057 746 : && !tree_int_cst_equal (arg1, arg2))
14058 53 : return boolean_false_node;
14059 :
14060 511 : if (TREE_CODE (arg2) == INTEGER_CST
14061 129 : && TREE_CODE (arg1) != INTEGER_CST)
14062 : {
14063 : std::swap (arg1, arg2);
14064 : std::swap (membertype1, membertype2);
14065 : std::swap (basetype1, basetype2);
14066 : }
14067 :
14068 511 : tree ret = is_corresponding_member_aggr (loc, basetype1, membertype1, arg1,
14069 : basetype2, membertype2, arg2);
14070 511 : if (TREE_TYPE (ret) == boolean_type_node)
14071 : return ret;
14072 : /* If both arg1 and arg2 are INTEGER_CSTs, is_corresponding_member_aggr
14073 : already returns boolean_{true,false}_node whether those particular
14074 : members are corresponding members or not. Otherwise, if only
14075 : one of them is INTEGER_CST (canonicalized to first being INTEGER_CST
14076 : above), it returns boolean_false_node if it is certainly not a
14077 : corresponding member and otherwise we need to do a runtime check that
14078 : those two OFFSET_TYPE offsets are equal.
14079 : If neither of the operands is INTEGER_CST, is_corresponding_member_aggr
14080 : returns the largest offset at which the members would be corresponding
14081 : members, so perform arg1 <= ret && arg1 == arg2 runtime check. */
14082 304 : gcc_assert (TREE_CODE (arg2) != INTEGER_CST);
14083 304 : if (TREE_CODE (arg1) == INTEGER_CST)
14084 0 : return fold_build2 (EQ_EXPR, boolean_type_node, arg1,
14085 : fold_convert (TREE_TYPE (arg1), arg2));
14086 304 : ret = fold_build2 (LE_EXPR, boolean_type_node,
14087 : fold_convert (pointer_sized_int_node, arg1),
14088 : fold_convert (pointer_sized_int_node, ret));
14089 304 : return fold_build2 (TRUTH_AND_EXPR, boolean_type_node, ret,
14090 : fold_build2 (EQ_EXPR, boolean_type_node, arg1,
14091 : fold_convert (TREE_TYPE (arg1), arg2)));
14092 : }
14093 :
14094 : /* Fold __builtin_is_string_literal call. */
14095 :
14096 : tree
14097 4296 : fold_builtin_is_string_literal (location_t loc, int nargs, tree *args)
14098 : {
14099 : /* Unless users call the builtin directly, the following 3 checks should be
14100 : ensured from std::is_string_literal overloads. */
14101 4296 : if (nargs != 1)
14102 : {
14103 0 : error_at (loc, "%<__builtin_is_string_literal%> needs a single "
14104 : "argument");
14105 0 : return boolean_false_node;
14106 : }
14107 4296 : tree arg = args[0];
14108 4296 : if (error_operand_p (arg))
14109 0 : return boolean_false_node;
14110 4296 : if (!TYPE_PTR_P (TREE_TYPE (arg))
14111 4296 : || !TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg)))
14112 8592 : || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (arg))))
14113 : {
14114 0 : arg_invalid:
14115 0 : error_at (loc, "%<__builtin_is_string_literal%> "
14116 : "argument is not %<const char*%>, %<const wchar_t*%>, "
14117 : "%<const char8_t*%>, %<const char16_t*%> or "
14118 : "%<const char32_t*%>");
14119 0 : return boolean_false_node;
14120 : }
14121 4296 : tree chart = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg)));
14122 4296 : if (chart != char_type_node
14123 3432 : && chart != wchar_type_node
14124 2574 : && chart != char8_type_node
14125 1716 : && chart != char16_type_node
14126 858 : && chart != char32_type_node)
14127 0 : goto arg_invalid;
14128 :
14129 4296 : STRIP_NOPS (arg);
14130 8604 : while (TREE_CODE (arg) == POINTER_PLUS_EXPR)
14131 : {
14132 12 : arg = TREE_OPERAND (arg, 0);
14133 12 : STRIP_NOPS (arg);
14134 : }
14135 4296 : if (TREE_CODE (arg) != ADDR_EXPR)
14136 4240 : return boolean_false_node;
14137 56 : arg = TREE_OPERAND (arg, 0);
14138 56 : if (TREE_CODE (arg) == ARRAY_REF)
14139 24 : arg = TREE_OPERAND (arg, 0);
14140 56 : if (TREE_CODE (arg) != STRING_CST)
14141 16 : return boolean_false_node;
14142 40 : return boolean_true_node;
14143 : }
14144 :
14145 : /* [basic.types] 8. True iff TYPE is an object type. */
14146 :
14147 : static bool
14148 2970031 : object_type_p (const_tree type)
14149 : {
14150 2970031 : return (TREE_CODE (type) != FUNCTION_TYPE
14151 0 : && !TYPE_REF_P (type)
14152 2970031 : && !VOID_TYPE_P (type));
14153 : }
14154 :
14155 : /* [defns.referenceable] True iff TYPE is a referenceable type. */
14156 :
14157 : static bool
14158 3626417 : referenceable_type_p (const_tree type)
14159 : {
14160 3626417 : return (TYPE_REF_P (type)
14161 3626873 : || object_type_p (type)
14162 3626873 : || (FUNC_OR_METHOD_TYPE_P (type)
14163 385 : && type_memfn_quals (type) == TYPE_UNQUALIFIED
14164 319 : && type_memfn_rqual (type) == REF_QUAL_NONE));
14165 : }
14166 :
14167 : /* Actually evaluates the trait. */
14168 :
14169 : static bool
14170 18377462 : trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
14171 : {
14172 18377462 : enum tree_code type_code1;
14173 18377462 : tree t;
14174 :
14175 18377462 : type_code1 = TREE_CODE (type1);
14176 :
14177 18377462 : switch (kind)
14178 : {
14179 377 : case CPTK_HAS_NOTHROW_ASSIGN:
14180 377 : type1 = strip_array_types (type1);
14181 715 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
14182 715 : && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2)
14183 206 : || (CLASS_TYPE_P (type1)
14184 156 : && classtype_has_nothrow_assign_or_copy_p (type1,
14185 : true))));
14186 :
14187 254 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14188 254 : type1 = strip_array_types (type1);
14189 254 : return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2)
14190 254 : || (CLASS_TYPE_P (type1)
14191 111 : && (t = locate_ctor (type1))
14192 72 : && maybe_instantiate_noexcept (t)
14193 70 : && TYPE_NOTHROW_P (TREE_TYPE (t))));
14194 :
14195 380 : case CPTK_HAS_NOTHROW_COPY:
14196 380 : type1 = strip_array_types (type1);
14197 380 : return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2)
14198 380 : || (CLASS_TYPE_P (type1)
14199 195 : && classtype_has_nothrow_assign_or_copy_p (type1, false)));
14200 :
14201 613 : case CPTK_HAS_TRIVIAL_ASSIGN:
14202 : /* ??? The standard seems to be missing the "or array of such a class
14203 : type" wording for this trait. */
14204 613 : type1 = strip_array_types (type1);
14205 1205 : return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE
14206 1187 : && (trivial_type_p (type1)
14207 364 : || (CLASS_TYPE_P (type1)
14208 267 : && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1))));
14209 :
14210 617 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14211 617 : type1 = strip_array_types (type1);
14212 617 : return (trivial_type_p (type1)
14213 617 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1)));
14214 :
14215 640 : case CPTK_HAS_TRIVIAL_COPY:
14216 : /* ??? The standard seems to be missing the "or array of such a class
14217 : type" wording for this trait. */
14218 640 : type1 = strip_array_types (type1);
14219 1073 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14220 1055 : || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1)));
14221 :
14222 808 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14223 808 : type1 = strip_array_types (type1);
14224 808 : if (CLASS_TYPE_P (type1) && type_build_dtor_call (type1))
14225 : {
14226 129 : deferring_access_check_sentinel dacs (dk_no_check);
14227 129 : cp_unevaluated un;
14228 129 : tree fn = get_dtor (type1, tf_none);
14229 129 : if (!fn && !seen_error ())
14230 3 : warning (0, "checking %qs for type %qT with a destructor that "
14231 : "cannot be called", "__has_trivial_destructor", type1);
14232 129 : }
14233 1160 : return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE
14234 1157 : || (CLASS_TYPE_P (type1)
14235 299 : && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1)));
14236 :
14237 61649 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14238 61649 : return type_has_unique_obj_representations (type1);
14239 :
14240 338 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14241 338 : return type_has_virtual_destructor (type1);
14242 :
14243 56898 : case CPTK_IS_ABSTRACT:
14244 56898 : return ABSTRACT_CLASS_TYPE_P (type1);
14245 :
14246 1156 : case CPTK_IS_AGGREGATE:
14247 1156 : return CP_AGGREGATE_TYPE_P (type1);
14248 :
14249 377120 : case CPTK_IS_ARRAY:
14250 377120 : return (type_code1 == ARRAY_TYPE
14251 : /* We don't want to report T[0] as being an array type.
14252 : This is for compatibility with an implementation of
14253 : std::is_array by template argument deduction, because
14254 : compute_array_index_type_loc rejects a zero-size array
14255 : in SFINAE context. */
14256 377120 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14257 :
14258 1040969 : case CPTK_IS_ASSIGNABLE:
14259 1040969 : return is_xible (MODIFY_EXPR, type1, type2);
14260 :
14261 526001 : case CPTK_IS_BASE_OF:
14262 525898 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14263 1032971 : && (same_type_ignoring_top_level_qualifiers_p (type1, type2)
14264 478340 : || DERIVED_FROM_P (type1, type2)));
14265 :
14266 58670 : case CPTK_IS_BOUNDED_ARRAY:
14267 58670 : return (type_code1 == ARRAY_TYPE
14268 1668 : && TYPE_DOMAIN (type1)
14269 : /* We don't want to report T[0] as being a bounded array type.
14270 : This is for compatibility with an implementation of
14271 : std::is_bounded_array by template argument deduction, because
14272 : compute_array_index_type_loc rejects a zero-size array
14273 : in SFINAE context. */
14274 60210 : && !(TYPE_SIZE (type1) && integer_zerop (TYPE_SIZE (type1))));
14275 :
14276 547617 : case CPTK_IS_CLASS:
14277 547617 : return NON_UNION_CLASS_TYPE_P (type1);
14278 :
14279 601629 : case CPTK_IS_CONST:
14280 601629 : return CP_TYPE_CONST_P (type1);
14281 :
14282 2429657 : case CPTK_IS_CONSTRUCTIBLE:
14283 2429657 : return is_xible (INIT_EXPR, type1, type2);
14284 :
14285 3226071 : case CPTK_IS_CONVERTIBLE:
14286 3226071 : return is_convertible (type1, type2);
14287 :
14288 3350 : case CPTK_IS_DESTRUCTIBLE:
14289 3350 : return is_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14290 :
14291 223617 : case CPTK_IS_EMPTY:
14292 223617 : return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1);
14293 :
14294 683249 : case CPTK_IS_ENUM:
14295 683249 : return type_code1 == ENUMERAL_TYPE;
14296 :
14297 440540 : case CPTK_IS_FINAL:
14298 440540 : return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1);
14299 :
14300 48524 : case CPTK_IS_FUNCTION:
14301 48524 : return type_code1 == FUNCTION_TYPE;
14302 :
14303 1397 : case CPTK_IS_IMPLICIT_LIFETIME:
14304 1397 : return implicit_lifetime_type_p (type1);
14305 :
14306 49446 : case CPTK_IS_INVOCABLE:
14307 49446 : return !error_operand_p (build_invoke (type1, type2, tf_none));
14308 :
14309 221 : case CPTK_IS_LAYOUT_COMPATIBLE:
14310 221 : return layout_compatible_type_p (type1, type2);
14311 :
14312 197 : case CPTK_IS_LITERAL_TYPE:
14313 197 : return literal_type_p (type1);
14314 :
14315 49172 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14316 49172 : return TYPE_PTRMEMFUNC_P (type1);
14317 :
14318 49159 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14319 49159 : return TYPE_PTRDATAMEM_P (type1);
14320 :
14321 11093 : case CPTK_IS_MEMBER_POINTER:
14322 11093 : return TYPE_PTRMEM_P (type1);
14323 :
14324 469065 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14325 469065 : return is_nothrow_xible (MODIFY_EXPR, type1, type2);
14326 :
14327 944618 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14328 944618 : return is_nothrow_xible (INIT_EXPR, type1, type2);
14329 :
14330 683 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14331 683 : return is_nothrow_convertible (type1, type2);
14332 :
14333 24472 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14334 24472 : return is_nothrow_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14335 :
14336 44301 : case CPTK_IS_NOTHROW_INVOCABLE:
14337 44301 : return expr_noexcept_p (build_invoke (type1, type2, tf_none), tf_none);
14338 :
14339 1149179 : case CPTK_IS_OBJECT:
14340 1149179 : return object_type_p (type1);
14341 :
14342 168 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14343 168 : return pointer_interconvertible_base_of_p (type1, type2);
14344 :
14345 11664 : case CPTK_IS_POD:
14346 11664 : return pod_type_p (type1);
14347 :
14348 153702 : case CPTK_IS_POINTER:
14349 153702 : return TYPE_PTR_P (type1);
14350 :
14351 313 : case CPTK_IS_POLYMORPHIC:
14352 313 : return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1);
14353 :
14354 731675 : case CPTK_IS_REFERENCE:
14355 731675 : return type_code1 == REFERENCE_TYPE;
14356 :
14357 2709190 : case CPTK_IS_SAME:
14358 2709190 : return same_type_p (type1, type2);
14359 :
14360 373 : case CPTK_IS_SCOPED_ENUM:
14361 373 : return SCOPED_ENUM_P (type1);
14362 :
14363 64696 : case CPTK_IS_STD_LAYOUT:
14364 64696 : return std_layout_type_p (type1);
14365 :
14366 59845 : case CPTK_IS_TRIVIAL:
14367 59845 : return trivial_type_p (type1);
14368 :
14369 12955 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14370 12955 : return is_trivially_xible (MODIFY_EXPR, type1, type2);
14371 :
14372 76905 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14373 76905 : return is_trivially_xible (INIT_EXPR, type1, type2);
14374 :
14375 120905 : case CPTK_IS_TRIVIALLY_COPYABLE:
14376 120905 : return trivially_copyable_p (type1);
14377 :
14378 27623 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14379 27623 : return is_trivially_xible (BIT_NOT_EXPR, type1, NULL_TREE);
14380 :
14381 100190 : case CPTK_IS_UNBOUNDED_ARRAY:
14382 100190 : return array_of_unknown_bound_p (type1);
14383 :
14384 277718 : case CPTK_IS_UNION:
14385 277718 : return type_code1 == UNION_TYPE;
14386 :
14387 883 : case CPTK_IS_VIRTUAL_BASE_OF:
14388 803 : return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14389 1664 : && lookup_base (type2, type1, ba_require_virtual,
14390 : NULL, tf_none) != NULL_TREE);
14391 :
14392 626082 : case CPTK_IS_VOLATILE:
14393 626082 : return CP_TYPE_VOLATILE_P (type1);
14394 :
14395 223819 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14396 223819 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/true);
14397 :
14398 54660 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14399 54660 : return ref_xes_from_temporary (type1, type2, /*direct_init=*/false);
14400 :
14401 85 : case CPTK_IS_DEDUCIBLE:
14402 85 : return type_targs_deducible_from (type1, type2);
14403 :
14404 264 : case CPTK_IS_STRUCTURAL:
14405 264 : return structural_type_p (type1);
14406 :
14407 : /* __array_rank, __builtin_type_order and __builtin_structured_binding_size
14408 : are handled in finish_trait_expr. */
14409 0 : case CPTK_RANK:
14410 0 : case CPTK_TYPE_ORDER:
14411 0 : case CPTK_STRUCTURED_BINDING_SIZE:
14412 0 : gcc_unreachable ();
14413 :
14414 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14415 : case CPTK_##CODE:
14416 : #include "cp-trait.def"
14417 : #undef DEFTRAIT_TYPE
14418 : /* Type-yielding traits are handled in finish_trait_type. */
14419 : break;
14420 : }
14421 :
14422 0 : gcc_unreachable ();
14423 : }
14424 :
14425 : /* Returns true if TYPE meets the requirements for the specified KIND,
14426 : false otherwise.
14427 :
14428 : When KIND == 1, TYPE must be an array of unknown bound,
14429 : or (possibly cv-qualified) void, or a complete type.
14430 :
14431 : When KIND == 2, TYPE must be a complete type, or array of complete type,
14432 : or (possibly cv-qualified) void.
14433 :
14434 : When KIND == 3:
14435 : If TYPE is a non-union class type, it must be complete.
14436 :
14437 : When KIND == 4:
14438 : If TYPE is a class type, it must be complete.
14439 :
14440 : If COMPLAIN is not tf_none, we permerror and return false if that doesn't
14441 : produce a hard error. */
14442 :
14443 : static bool
14444 19301663 : check_trait_type (tree type, int kind, tsubst_flags_t complain)
14445 : {
14446 19301663 : if (type == NULL_TREE)
14447 : return true;
14448 :
14449 19301663 : if (TREE_CODE (type) == TREE_VEC)
14450 : {
14451 6300573 : for (tree arg : tree_vec_range (type))
14452 2760365 : if (!check_trait_type (arg, kind, complain))
14453 123 : return false;
14454 3540208 : return true;
14455 : }
14456 :
14457 15761332 : if (kind == 1 && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
14458 : return true; // Array of unknown bound. Don't care about completeness.
14459 :
14460 15760453 : if (kind == 3 && !NON_UNION_CLASS_TYPE_P (type))
14461 : return true; // Not a non-union class type. Don't care about completeness.
14462 :
14463 15644372 : if (kind == 4 && TREE_CODE (type) == ARRAY_TYPE)
14464 : return true; // Not a class type. Don't care about completeness.
14465 :
14466 15643475 : if (VOID_TYPE_P (type))
14467 : return true;
14468 :
14469 15641807 : type = complete_type (strip_array_types (type));
14470 15641807 : if (!COMPLETE_TYPE_P (type)
14471 : /* If we're not emitting error messages, always return false for
14472 : incomplete types. */
14473 15641807 : && (complain == tf_none
14474 181 : || (cxx_incomplete_type_diagnostic (NULL_TREE, type,
14475 : diagnostics::kind::permerror)
14476 181 : && !flag_permissive)))
14477 886 : return false;
14478 : return true;
14479 : }
14480 :
14481 : /* True iff the conversion (if any) would be a direct reference
14482 : binding, not requiring complete types. This is LWG2939. */
14483 :
14484 : static bool
14485 6772199 : same_type_ref_bind_p (cp_trait_kind kind, tree type1, tree type2)
14486 : {
14487 6772199 : tree from, to;
14488 6772199 : switch (kind)
14489 : {
14490 : /* These put the target type first. */
14491 : case CPTK_IS_CONSTRUCTIBLE:
14492 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14493 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14494 : case CPTK_IS_INVOCABLE:
14495 : case CPTK_IS_NOTHROW_INVOCABLE:
14496 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14497 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14498 : to = type1;
14499 : from = type2;
14500 : break;
14501 :
14502 : /* These put it second. */
14503 3226826 : case CPTK_IS_CONVERTIBLE:
14504 3226826 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14505 3226826 : to = type2;
14506 3226826 : from = type1;
14507 3226826 : break;
14508 :
14509 0 : default:
14510 0 : gcc_unreachable ();
14511 : }
14512 :
14513 6772199 : if (TREE_CODE (to) != REFERENCE_TYPE || !from)
14514 : return false;
14515 923433 : if (TREE_CODE (from) == TREE_VEC && TREE_VEC_LENGTH (from) == 1)
14516 63102 : from = TREE_VEC_ELT (from, 0);
14517 923433 : return (TYPE_P (from)
14518 1836624 : && (same_type_ignoring_top_level_qualifiers_p
14519 913191 : (non_reference (to), non_reference (from))));
14520 : }
14521 :
14522 : /* Helper for finish_trait_expr and tsubst_expr. Handle
14523 : CPTK_STRUCTURED_BINDING_SIZE in possibly SFINAE-friendly
14524 : way. */
14525 :
14526 : tree
14527 273 : finish_structured_binding_size (location_t loc, tree type,
14528 : tsubst_flags_t complain)
14529 : {
14530 273 : if (TYPE_REF_P (type))
14531 : {
14532 105 : if (complain & tf_error)
14533 99 : error_at (loc, "%qs argument %qT is a reference",
14534 : "__builtin_structured_binding_size", type);
14535 105 : return error_mark_node;
14536 : }
14537 168 : HOST_WIDE_INT ret = cp_decomp_size (loc, type, complain);
14538 168 : if (ret == -1)
14539 63 : return error_mark_node;
14540 105 : return maybe_wrap_with_location (build_int_cst (size_type_node, ret), loc);
14541 : }
14542 :
14543 : /* Process a trait expression. */
14544 :
14545 : tree
14546 21911023 : finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2,
14547 : tsubst_flags_t complain/*=tf_warning_or_error*/)
14548 : {
14549 21911023 : if (type1 == error_mark_node
14550 21911020 : || type2 == error_mark_node)
14551 : return error_mark_node;
14552 :
14553 21911020 : if (processing_template_decl)
14554 : {
14555 3532923 : tree trait_expr = make_node (TRAIT_EXPR);
14556 3532923 : if (kind == CPTK_RANK || kind == CPTK_STRUCTURED_BINDING_SIZE)
14557 32329 : TREE_TYPE (trait_expr) = size_type_node;
14558 3500594 : else if (kind == CPTK_TYPE_ORDER)
14559 : {
14560 4570 : tree val = type_order_value (type1, type1);
14561 4570 : if (val != error_mark_node)
14562 4570 : TREE_TYPE (trait_expr) = TREE_TYPE (val);
14563 : }
14564 : else
14565 3496024 : TREE_TYPE (trait_expr) = boolean_type_node;
14566 3532923 : TRAIT_EXPR_TYPE1 (trait_expr) = type1;
14567 3532923 : TRAIT_EXPR_TYPE2 (trait_expr) = type2;
14568 3532923 : TRAIT_EXPR_KIND (trait_expr) = kind;
14569 3532923 : TRAIT_EXPR_LOCATION (trait_expr) = loc;
14570 3532923 : return trait_expr;
14571 : }
14572 :
14573 18378097 : switch (kind)
14574 : {
14575 58219 : case CPTK_HAS_NOTHROW_ASSIGN:
14576 58219 : case CPTK_HAS_TRIVIAL_ASSIGN:
14577 58219 : case CPTK_HAS_NOTHROW_CONSTRUCTOR:
14578 58219 : case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
14579 58219 : case CPTK_HAS_NOTHROW_COPY:
14580 58219 : case CPTK_HAS_TRIVIAL_COPY:
14581 58219 : case CPTK_HAS_TRIVIAL_DESTRUCTOR:
14582 58219 : case CPTK_IS_DESTRUCTIBLE:
14583 58219 : case CPTK_IS_NOTHROW_DESTRUCTIBLE:
14584 58219 : case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
14585 58219 : if (!check_trait_type (type1, /*kind=*/1, complain))
14586 57 : return error_mark_node;
14587 : break;
14588 :
14589 319353 : case CPTK_IS_LITERAL_TYPE:
14590 319353 : case CPTK_IS_POD:
14591 319353 : case CPTK_IS_STD_LAYOUT:
14592 319353 : case CPTK_IS_TRIVIAL:
14593 319353 : case CPTK_IS_TRIVIALLY_COPYABLE:
14594 319353 : case CPTK_IS_STRUCTURAL:
14595 319353 : case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
14596 319353 : if (!check_trait_type (type1, /* kind = */ 2, complain))
14597 133 : return error_mark_node;
14598 : break;
14599 :
14600 281205 : case CPTK_IS_ABSTRACT:
14601 281205 : case CPTK_IS_EMPTY:
14602 281205 : case CPTK_IS_POLYMORPHIC:
14603 281205 : case CPTK_HAS_VIRTUAL_DESTRUCTOR:
14604 281205 : if (!check_trait_type (type1, /* kind = */ 3, complain))
14605 39 : return error_mark_node;
14606 : break;
14607 :
14608 : /* N.B. std::is_aggregate is kind=2 but we don't need a complete element
14609 : type to know whether an array is an aggregate, so use kind=4 here. */
14610 443148 : case CPTK_IS_AGGREGATE:
14611 443148 : case CPTK_IS_FINAL:
14612 443148 : case CPTK_IS_IMPLICIT_LIFETIME:
14613 443148 : if (!check_trait_type (type1, /* kind = */ 4, complain))
14614 55 : return error_mark_node;
14615 : break;
14616 :
14617 6772199 : case CPTK_IS_CONSTRUCTIBLE:
14618 6772199 : case CPTK_IS_CONVERTIBLE:
14619 6772199 : case CPTK_IS_INVOCABLE:
14620 6772199 : case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
14621 6772199 : case CPTK_IS_NOTHROW_CONVERTIBLE:
14622 6772199 : case CPTK_IS_NOTHROW_INVOCABLE:
14623 6772199 : case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
14624 6772199 : /* Don't check completeness for direct reference binding. */;
14625 6772199 : if (same_type_ref_bind_p (kind, type1, type2))
14626 : break;
14627 7719881 : gcc_fallthrough ();
14628 :
14629 7719881 : case CPTK_IS_ASSIGNABLE:
14630 7719881 : case CPTK_IS_NOTHROW_ASSIGNABLE:
14631 7719881 : case CPTK_IS_TRIVIALLY_ASSIGNABLE:
14632 7719881 : case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
14633 7719881 : case CPTK_REF_CONVERTS_FROM_TEMPORARY:
14634 7719881 : if (!check_trait_type (type1, /*kind=*/1, complain)
14635 7719881 : || !check_trait_type (type2, /*kind=*/1, complain))
14636 602 : return error_mark_node;
14637 : break;
14638 :
14639 526196 : case CPTK_IS_BASE_OF:
14640 526196 : case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
14641 526079 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14642 507146 : && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
14643 1004671 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14644 : /* We already issued an error. */
14645 27 : return error_mark_node;
14646 : break;
14647 :
14648 910 : case CPTK_IS_VIRTUAL_BASE_OF:
14649 830 : if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
14650 1718 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14651 : /* We already issued an error. */
14652 27 : return error_mark_node;
14653 : break;
14654 :
14655 : case CPTK_IS_ARRAY:
14656 : case CPTK_IS_BOUNDED_ARRAY:
14657 : case CPTK_IS_CLASS:
14658 : case CPTK_IS_CONST:
14659 : case CPTK_IS_ENUM:
14660 : case CPTK_IS_FUNCTION:
14661 : case CPTK_IS_MEMBER_FUNCTION_POINTER:
14662 : case CPTK_IS_MEMBER_OBJECT_POINTER:
14663 : case CPTK_IS_MEMBER_POINTER:
14664 : case CPTK_IS_OBJECT:
14665 : case CPTK_IS_POINTER:
14666 : case CPTK_IS_REFERENCE:
14667 : case CPTK_IS_SAME:
14668 : case CPTK_IS_SCOPED_ENUM:
14669 : case CPTK_IS_UNBOUNDED_ARRAY:
14670 : case CPTK_IS_UNION:
14671 : case CPTK_IS_VOLATILE:
14672 : break;
14673 :
14674 : case CPTK_RANK:
14675 : {
14676 : size_t rank = 0;
14677 122 : for (; TREE_CODE (type1) == ARRAY_TYPE; type1 = TREE_TYPE (type1))
14678 80 : ++rank;
14679 42 : return maybe_wrap_with_location (build_int_cst (size_type_node, rank),
14680 : loc);
14681 : }
14682 :
14683 460 : case CPTK_TYPE_ORDER:
14684 460 : return maybe_wrap_with_location (type_order_value (type1, type2), loc);
14685 :
14686 144 : case CPTK_STRUCTURED_BINDING_SIZE:
14687 144 : return finish_structured_binding_size (loc, type1, complain);
14688 :
14689 242 : case CPTK_IS_LAYOUT_COMPATIBLE:
14690 242 : if (!array_of_unknown_bound_p (type1)
14691 223 : && TREE_CODE (type1) != VOID_TYPE
14692 456 : && !complete_type_or_maybe_complain (type1, NULL_TREE, complain))
14693 : /* We already issued an error. */
14694 12 : return error_mark_node;
14695 230 : if (!array_of_unknown_bound_p (type2)
14696 203 : && TREE_CODE (type2) != VOID_TYPE
14697 424 : && !complete_type_or_maybe_complain (type2, NULL_TREE, complain))
14698 : /* We already issued an error. */
14699 9 : return error_mark_node;
14700 : break;
14701 :
14702 85 : case CPTK_IS_DEDUCIBLE:
14703 85 : if (!DECL_TYPE_TEMPLATE_P (type1))
14704 : {
14705 0 : error ("%qD is not a class or alias template", type1);
14706 0 : return error_mark_node;
14707 : }
14708 : break;
14709 :
14710 : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
14711 : case CPTK_##CODE:
14712 : #include "cp-trait.def"
14713 : #undef DEFTRAIT_TYPE
14714 : /* Type-yielding traits are handled in finish_trait_type. */
14715 0 : gcc_unreachable ();
14716 : }
14717 :
14718 18376490 : tree val = (trait_expr_value (kind, type1, type2)
14719 18376490 : ? boolean_true_node : boolean_false_node);
14720 18376490 : return maybe_wrap_with_location (val, loc);
14721 : }
14722 :
14723 : /* Process a trait type. */
14724 :
14725 : tree
14726 8111326 : finish_trait_type (cp_trait_kind kind, tree type1, tree type2,
14727 : tsubst_flags_t complain)
14728 : {
14729 8112270 : if (type1 == error_mark_node
14730 8112267 : || type2 == error_mark_node)
14731 : return error_mark_node;
14732 :
14733 8112267 : if (processing_template_decl)
14734 : {
14735 237310 : tree type = cxx_make_type (TRAIT_TYPE);
14736 237310 : TRAIT_TYPE_TYPE1 (type) = type1;
14737 237310 : TRAIT_TYPE_TYPE2 (type) = type2;
14738 237310 : TRAIT_TYPE_KIND_RAW (type) = build_int_cstu (integer_type_node, kind);
14739 : /* These traits are intended to be used in the definition of the ::type
14740 : member of the corresponding standard library type trait and aren't
14741 : mangleable (and thus won't appear directly in template signatures),
14742 : so structural equality should suffice. */
14743 237310 : SET_TYPE_STRUCTURAL_EQUALITY (type);
14744 237310 : return type;
14745 : }
14746 :
14747 7874957 : switch (kind)
14748 : {
14749 1264709 : case CPTK_ADD_LVALUE_REFERENCE:
14750 : /* [meta.trans.ref]. */
14751 1264709 : if (referenceable_type_p (type1))
14752 1264622 : return cp_build_reference_type (type1, /*rval=*/false);
14753 : return type1;
14754 :
14755 656029 : case CPTK_ADD_POINTER:
14756 : /* [meta.trans.ptr]. */
14757 656029 : if (VOID_TYPE_P (type1) || referenceable_type_p (type1))
14758 : {
14759 655997 : if (TYPE_REF_P (type1))
14760 654796 : type1 = TREE_TYPE (type1);
14761 655997 : return build_pointer_type (type1);
14762 : }
14763 : return type1;
14764 :
14765 1705703 : case CPTK_ADD_RVALUE_REFERENCE:
14766 : /* [meta.trans.ref]. */
14767 1705703 : if (referenceable_type_p (type1))
14768 1705645 : return cp_build_reference_type (type1, /*rval=*/true);
14769 : return type1;
14770 :
14771 240619 : case CPTK_DECAY:
14772 240619 : if (TYPE_REF_P (type1))
14773 43641 : type1 = TREE_TYPE (type1);
14774 :
14775 240619 : if (TREE_CODE (type1) == ARRAY_TYPE)
14776 735 : return finish_trait_type (CPTK_ADD_POINTER, TREE_TYPE (type1), type2,
14777 735 : complain);
14778 239884 : else if (TREE_CODE (type1) == FUNCTION_TYPE)
14779 : return finish_trait_type (CPTK_ADD_POINTER, type1, type2, complain);
14780 : else
14781 239675 : return cv_unqualified (type1);
14782 :
14783 223 : case CPTK_REMOVE_ALL_EXTENTS:
14784 223 : return strip_array_types (type1);
14785 :
14786 1013766 : case CPTK_REMOVE_CV:
14787 1013766 : return cv_unqualified (type1);
14788 :
14789 484154 : case CPTK_REMOVE_CVREF:
14790 484154 : if (TYPE_REF_P (type1))
14791 184139 : type1 = TREE_TYPE (type1);
14792 484154 : return cv_unqualified (type1);
14793 :
14794 67017 : case CPTK_REMOVE_EXTENT:
14795 67017 : if (TREE_CODE (type1) == ARRAY_TYPE)
14796 9526 : type1 = TREE_TYPE (type1);
14797 : return type1;
14798 :
14799 45206 : case CPTK_REMOVE_POINTER:
14800 45206 : if (TYPE_PTR_P (type1))
14801 42304 : type1 = TREE_TYPE (type1);
14802 : return type1;
14803 :
14804 2235247 : case CPTK_REMOVE_REFERENCE:
14805 2235247 : if (TYPE_REF_P (type1))
14806 1357422 : type1 = TREE_TYPE (type1);
14807 : return type1;
14808 :
14809 113387 : case CPTK_TYPE_PACK_ELEMENT:
14810 113387 : return finish_type_pack_element (type1, type2, complain);
14811 :
14812 48897 : case CPTK_UNDERLYING_TYPE:
14813 48897 : return finish_underlying_type (type1);
14814 :
14815 : #define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
14816 : case CPTK_##CODE:
14817 : #include "cp-trait.def"
14818 : #undef DEFTRAIT_EXPR
14819 : /* Expression-yielding traits are handled in finish_trait_expr. */
14820 : case CPTK_BASES:
14821 : case CPTK_DIRECT_BASES:
14822 : /* BASES and DIRECT_BASES are handled in finish_bases. */
14823 : break;
14824 : }
14825 :
14826 0 : gcc_unreachable ();
14827 : }
14828 :
14829 : /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
14830 : which is ignored for C++. */
14831 :
14832 : void
14833 0 : set_float_const_decimal64 (void)
14834 : {
14835 0 : }
14836 :
14837 : void
14838 0 : clear_float_const_decimal64 (void)
14839 : {
14840 0 : }
14841 :
14842 : bool
14843 1903469 : float_const_decimal64_p (void)
14844 : {
14845 1903469 : return 0;
14846 : }
14847 :
14848 :
14849 : /* Return true if T designates the implied `this' parameter. */
14850 :
14851 : bool
14852 6717042 : is_this_parameter (tree t)
14853 : {
14854 6717042 : if (!DECL_P (t) || DECL_NAME (t) != this_identifier)
14855 : return false;
14856 3921270 : gcc_assert (TREE_CODE (t) == PARM_DECL
14857 : || (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t))
14858 : || (cp_binding_oracle && VAR_P (t)));
14859 : return true;
14860 : }
14861 :
14862 : /* As above, or a C++23 explicit object parameter. */
14863 :
14864 : bool
14865 456 : is_object_parameter (tree t)
14866 : {
14867 456 : if (is_this_parameter (t))
14868 : return true;
14869 91 : if (TREE_CODE (t) != PARM_DECL)
14870 : return false;
14871 34 : tree ctx = DECL_CONTEXT (t);
14872 34 : return (ctx && DECL_XOBJ_MEMBER_FUNCTION_P (ctx)
14873 62 : && t == DECL_ARGUMENTS (ctx));
14874 : }
14875 :
14876 : /* Insert the deduced return type for an auto function. */
14877 :
14878 : void
14879 1078693 : apply_deduced_return_type (tree fco, tree return_type)
14880 : {
14881 1078693 : tree result;
14882 :
14883 1078693 : if (return_type == error_mark_node)
14884 : return;
14885 :
14886 1078690 : if (DECL_CONV_FN_P (fco))
14887 42 : DECL_NAME (fco) = make_conv_op_name (return_type);
14888 :
14889 1078690 : TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
14890 :
14891 1078690 : maybe_update_postconditions (fco);
14892 :
14893 : /* Apply the type to the result object. */
14894 :
14895 1078690 : result = DECL_RESULT (fco);
14896 1078690 : if (result == NULL_TREE)
14897 : return;
14898 1066152 : if (TREE_TYPE (result) == return_type)
14899 : return;
14900 :
14901 1066149 : if (!processing_template_decl && !VOID_TYPE_P (return_type)
14902 1972876 : && !complete_type_or_else (return_type, NULL_TREE))
14903 : return;
14904 :
14905 : /* We already have a DECL_RESULT from start_preparsed_function.
14906 : Now we need to redo the work it and allocate_struct_function
14907 : did to reflect the new type. */
14908 1066149 : result = build_decl (DECL_SOURCE_LOCATION (result), RESULT_DECL, NULL_TREE,
14909 1066149 : TYPE_MAIN_VARIANT (return_type));
14910 1066149 : DECL_ARTIFICIAL (result) = 1;
14911 1066149 : DECL_IGNORED_P (result) = 1;
14912 1066149 : cp_apply_type_quals_to_decl (cp_type_quals (return_type),
14913 : result);
14914 1066149 : DECL_RESULT (fco) = result;
14915 :
14916 1066149 : if (!uses_template_parms (fco))
14917 1066149 : if (function *fun = DECL_STRUCT_FUNCTION (fco))
14918 : {
14919 1065150 : bool aggr = aggregate_value_p (result, fco);
14920 : #ifdef PCC_STATIC_STRUCT_RETURN
14921 : fun->returns_pcc_struct = aggr;
14922 : #endif
14923 1065150 : fun->returns_struct = aggr;
14924 : }
14925 : }
14926 :
14927 : /* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true,
14928 : this is a right unary fold. Otherwise it is a left unary fold. */
14929 :
14930 : static tree
14931 854180 : finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir)
14932 : {
14933 : /* Build a pack expansion (assuming expr has pack type). */
14934 854180 : if (!uses_parameter_packs (expr))
14935 : {
14936 3 : error_at (location_of (expr), "operand of fold expression has no "
14937 : "unexpanded parameter packs");
14938 3 : return error_mark_node;
14939 : }
14940 854177 : tree pack = make_pack_expansion (expr);
14941 :
14942 : /* Build the fold expression. */
14943 854177 : tree code = build_int_cstu (integer_type_node, abs (op));
14944 854177 : tree fold = build_min_nt_loc (loc, dir, code, pack);
14945 854177 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14946 854177 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14947 854177 : FOLD_EXPR_OP (fold),
14948 854177 : FOLD_EXPR_MODIFY_P (fold));
14949 854177 : return fold;
14950 : }
14951 :
14952 : tree
14953 26156 : finish_left_unary_fold_expr (location_t loc, tree expr, int op)
14954 : {
14955 26156 : return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR);
14956 : }
14957 :
14958 : tree
14959 828024 : finish_right_unary_fold_expr (location_t loc, tree expr, int op)
14960 : {
14961 828024 : return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR);
14962 : }
14963 :
14964 : /* Build a binary fold expression over EXPR1 and EXPR2. The
14965 : associativity of the fold is determined by EXPR1 and EXPR2 (whichever
14966 : has an unexpanded parameter pack). */
14967 :
14968 : static tree
14969 198040 : finish_binary_fold_expr (location_t loc, tree pack, tree init,
14970 : int op, tree_code dir)
14971 : {
14972 198040 : pack = make_pack_expansion (pack);
14973 198040 : tree code = build_int_cstu (integer_type_node, abs (op));
14974 198040 : tree fold = build_min_nt_loc (loc, dir, code, pack, init);
14975 198040 : FOLD_EXPR_MODIFY_P (fold) = (op < 0);
14976 198040 : TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
14977 198040 : FOLD_EXPR_OP (fold),
14978 198040 : FOLD_EXPR_MODIFY_P (fold));
14979 198040 : return fold;
14980 : }
14981 :
14982 : tree
14983 198040 : finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op)
14984 : {
14985 : // Determine which expr has an unexpanded parameter pack and
14986 : // set the pack and initial term.
14987 198040 : bool pack1 = uses_parameter_packs (expr1);
14988 198040 : bool pack2 = uses_parameter_packs (expr2);
14989 198040 : if (pack1 && !pack2)
14990 1091 : return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
14991 196949 : else if (pack2 && !pack1)
14992 196949 : return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
14993 : else
14994 : {
14995 0 : if (pack1)
14996 0 : error ("both arguments in binary fold have unexpanded parameter packs");
14997 : else
14998 0 : error ("no unexpanded parameter packs in binary fold");
14999 : }
15000 0 : return error_mark_node;
15001 : }
15002 :
15003 : /* Finish __builtin_launder (arg). */
15004 :
15005 : tree
15006 14327 : finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain)
15007 : {
15008 14327 : tree orig_arg = arg;
15009 14327 : if (!type_dependent_expression_p (arg))
15010 84 : arg = decay_conversion (arg, complain);
15011 14327 : if (error_operand_p (arg))
15012 0 : return error_mark_node;
15013 14327 : if (!type_dependent_expression_p (arg) && !TYPE_PTROB_P (TREE_TYPE (arg)))
15014 : {
15015 24 : error_at (loc, "type %qT of argument to %<__builtin_launder%> "
15016 24 : "is not a pointer to object type", TREE_TYPE (arg));
15017 24 : return error_mark_node;
15018 : }
15019 14303 : if (processing_template_decl)
15020 14243 : arg = orig_arg;
15021 14303 : return build_call_expr_internal_loc (loc, IFN_LAUNDER,
15022 28606 : TREE_TYPE (arg), 1, arg);
15023 : }
15024 :
15025 : /* Finish __builtin_convertvector (arg, type). */
15026 :
15027 : tree
15028 486 : cp_build_vec_convert (tree arg, location_t loc, tree type,
15029 : tsubst_flags_t complain)
15030 : {
15031 486 : if (error_operand_p (type))
15032 9 : return error_mark_node;
15033 477 : if (error_operand_p (arg))
15034 0 : return error_mark_node;
15035 :
15036 477 : tree ret = NULL_TREE;
15037 477 : if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
15038 439 : ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg),
15039 : decay_conversion (arg, complain),
15040 : loc, type, (complain & tf_error) != 0);
15041 :
15042 477 : if (!processing_template_decl)
15043 : return ret;
15044 :
15045 80 : return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg);
15046 : }
15047 :
15048 : /* Finish __builtin_bit_cast (type, arg). */
15049 :
15050 : tree
15051 296556 : cp_build_bit_cast (location_t loc, tree type, tree arg,
15052 : tsubst_flags_t complain)
15053 : {
15054 296556 : if (error_operand_p (type))
15055 0 : return error_mark_node;
15056 296556 : if (!dependent_type_p (type))
15057 : {
15058 214942 : if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
15059 9 : return error_mark_node;
15060 214933 : if (TREE_CODE (type) == ARRAY_TYPE)
15061 : {
15062 : /* std::bit_cast for destination ARRAY_TYPE is not possible,
15063 : as functions may not return an array, so don't bother trying
15064 : to support this (and then deal with VLAs etc.). */
15065 9 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
15066 : "is an array type", type);
15067 9 : return error_mark_node;
15068 : }
15069 214924 : if (!trivially_copyable_p (type))
15070 : {
15071 18 : error_at (loc, "%<__builtin_bit_cast%> destination type %qT "
15072 : "is not trivially copyable", type);
15073 18 : return error_mark_node;
15074 : }
15075 : }
15076 :
15077 296520 : if (error_operand_p (arg))
15078 0 : return error_mark_node;
15079 :
15080 296520 : if (!type_dependent_expression_p (arg))
15081 : {
15082 115572 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
15083 : {
15084 : /* Don't perform array-to-pointer conversion. */
15085 375 : arg = mark_rvalue_use (arg, loc, true);
15086 375 : if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain))
15087 0 : return error_mark_node;
15088 : }
15089 : else
15090 115197 : arg = decay_conversion (arg, complain);
15091 :
15092 115572 : if (error_operand_p (arg))
15093 12 : return error_mark_node;
15094 :
15095 115560 : if (!trivially_copyable_p (TREE_TYPE (arg)))
15096 : {
15097 9 : error_at (cp_expr_loc_or_loc (arg, loc),
15098 : "%<__builtin_bit_cast%> source type %qT "
15099 9 : "is not trivially copyable", TREE_TYPE (arg));
15100 9 : return error_mark_node;
15101 : }
15102 115551 : if (!dependent_type_p (type)
15103 192650 : && !cp_tree_equal (TYPE_SIZE_UNIT (type),
15104 77099 : TYPE_SIZE_UNIT (TREE_TYPE (arg))))
15105 : {
15106 18 : error_at (loc, "%<__builtin_bit_cast%> source size %qE "
15107 : "not equal to destination type size %qE",
15108 18 : TYPE_SIZE_UNIT (TREE_TYPE (arg)),
15109 18 : TYPE_SIZE_UNIT (type));
15110 18 : return error_mark_node;
15111 : }
15112 : }
15113 :
15114 296481 : tree ret = build_min (BIT_CAST_EXPR, type, arg);
15115 296481 : SET_EXPR_LOCATION (ret, loc);
15116 :
15117 296481 : if (!processing_template_decl && CLASS_TYPE_P (type))
15118 874 : ret = get_target_expr (ret, complain);
15119 :
15120 : return ret;
15121 : }
15122 :
15123 : /* Diagnose invalid #pragma GCC unroll argument and adjust
15124 : it if needed. */
15125 :
15126 : tree
15127 24687 : cp_check_pragma_unroll (location_t loc, tree unroll)
15128 : {
15129 24687 : HOST_WIDE_INT lunroll = 0;
15130 24687 : if (type_dependent_expression_p (unroll))
15131 : ;
15132 49302 : else if (!INTEGRAL_TYPE_P (TREE_TYPE (unroll))
15133 49256 : || (!value_dependent_expression_p (unroll)
15134 24575 : && (!tree_fits_shwi_p (unroll)
15135 24549 : || (lunroll = tree_to_shwi (unroll)) < 0
15136 24534 : || lunroll >= USHRT_MAX)))
15137 : {
15138 90 : error_at (loc, "%<#pragma GCC unroll%> requires an"
15139 : " assignment-expression that evaluates to a non-negative"
15140 : " integral constant less than %u", USHRT_MAX);
15141 90 : unroll = integer_one_node;
15142 : }
15143 24561 : else if (TREE_CODE (unroll) == INTEGER_CST)
15144 : {
15145 24531 : unroll = fold_convert (integer_type_node, unroll);
15146 24531 : if (integer_zerop (unroll))
15147 12 : unroll = integer_one_node;
15148 : }
15149 24687 : return unroll;
15150 : }
15151 :
15152 : #include "gt-cp-semantics.h"
|