]>
Commit | Line | Data |
---|---|---|
ad321293 MM |
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 | |
c8094d83 | 4 | and during the instantiation of template functions. |
ad321293 | 5 | |
99dee823 | 6 | Copyright (C) 1998-2021 Free Software Foundation, Inc. |
ad321293 | 7 | Written by Mark Mitchell (mmitchell@usa.net) based on code found |
c8094d83 | 8 | formerly in parse.y and pt.c. |
ad321293 | 9 | |
f5adbb8d | 10 | This file is part of GCC. |
ad321293 | 11 | |
f5adbb8d | 12 | GCC is free software; you can redistribute it and/or modify it |
ad321293 | 13 | under the terms of the GNU General Public License as published by |
e77f031d | 14 | the Free Software Foundation; either version 3, or (at your option) |
ad321293 | 15 | any later version. |
c8094d83 | 16 | |
f5adbb8d | 17 | GCC is distributed in the hope that it will be useful, but |
ad321293 MM |
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. | |
c8094d83 | 21 | |
e77f031d NC |
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/>. */ | |
ad321293 MM |
25 | |
26 | #include "config.h" | |
8d052bc7 | 27 | #include "system.h" |
4977bab6 | 28 | #include "coretypes.h" |
2adfab87 AM |
29 | #include "target.h" |
30 | #include "bitmap.h" | |
2adfab87 | 31 | #include "cp-tree.h" |
2adfab87 AM |
32 | #include "stringpool.h" |
33 | #include "cgraph.h" | |
d8a2d370 DN |
34 | #include "stmt.h" |
35 | #include "varasm.h" | |
36 | #include "stor-layout.h" | |
61d3ce20 | 37 | #include "c-family/c-objc.h" |
25af8512 | 38 | #include "tree-inline.h" |
9b6ab3c0 | 39 | #include "intl.h" |
325c3691 | 40 | #include "tree-iterator.h" |
629b3d75 | 41 | #include "omp-general.h" |
9a771876 | 42 | #include "convert.h" |
314e6352 ML |
43 | #include "stringpool.h" |
44 | #include "attribs.h" | |
41dbbb37 | 45 | #include "gomp-constants.h" |
7fef86d3 | 46 | #include "predict.h" |
28567c40 | 47 | #include "memmodel.h" |
ad321293 MM |
48 | |
49 | /* There routines provide a modular interface to perform many parsing | |
50 | operations. They may therefore be used during actual parsing, or | |
51 | during template instantiation, which may be regarded as a | |
0b4d5576 | 52 | degenerate form of parsing. */ |
ad321293 | 53 | |
3a978d72 | 54 | static tree maybe_convert_cond (tree); |
6de9cd9a | 55 | static tree finalize_nrv_r (tree *, int *, void *); |
d5f4eddd | 56 | static tree capture_decltype (tree); |
4985cde3 | 57 | |
d9a6bd32 JJ |
58 | /* Used for OpenMP non-static data member privatization. */ |
59 | ||
60 | static hash_map<tree, tree> *omp_private_member_map; | |
61 | static vec<tree> omp_private_member_vec; | |
62 | static bool omp_private_member_ignore_next; | |
63 | ||
558475f0 | 64 | |
8d241e0b KL |
65 | /* Deferred Access Checking Overview |
66 | --------------------------------- | |
67 | ||
68 | Most C++ expressions and declarations require access checking | |
69 | to be performed during parsing. However, in several cases, | |
70 | this has to be treated differently. | |
71 | ||
72 | For member declarations, access checking has to be deferred | |
73 | until more information about the declaration is known. For | |
74 | example: | |
75 | ||
76 | class A { | |
0cbd7506 | 77 | typedef int X; |
8d241e0b | 78 | public: |
0cbd7506 | 79 | X f(); |
8d241e0b KL |
80 | }; |
81 | ||
82 | A::X A::f(); | |
83 | A::X g(); | |
84 | ||
85 | When we are parsing the function return type `A::X', we don't | |
86 | really know if this is allowed until we parse the function name. | |
87 | ||
88 | Furthermore, some contexts require that access checking is | |
89 | never performed at all. These include class heads, and template | |
90 | instantiations. | |
91 | ||
92 | Typical use of access checking functions is described here: | |
c8094d83 | 93 | |
8d241e0b KL |
94 | 1. When we enter a context that requires certain access checking |
95 | mode, the function `push_deferring_access_checks' is called with | |
96 | DEFERRING argument specifying the desired mode. Access checking | |
97 | may be performed immediately (dk_no_deferred), deferred | |
98 | (dk_deferred), or not performed (dk_no_check). | |
99 | ||
100 | 2. When a declaration such as a type, or a variable, is encountered, | |
101 | the function `perform_or_defer_access_check' is called. It | |
9771b263 | 102 | maintains a vector of all deferred checks. |
8d241e0b KL |
103 | |
104 | 3. The global `current_class_type' or `current_function_decl' is then | |
105 | setup by the parser. `enforce_access' relies on these information | |
106 | to check access. | |
107 | ||
108 | 4. Upon exiting the context mentioned in step 1, | |
109 | `perform_deferred_access_checks' is called to check all declaration | |
9771b263 | 110 | stored in the vector. `pop_deferring_access_checks' is then |
8d241e0b KL |
111 | called to restore the previous access checking mode. |
112 | ||
113 | In case of parsing error, we simply call `pop_deferring_access_checks' | |
114 | without `perform_deferred_access_checks'. */ | |
115 | ||
a79683d5 | 116 | struct GTY(()) deferred_access { |
9771b263 | 117 | /* A vector representing name-lookups for which we have deferred |
3e1f1ba5 NS |
118 | checking access controls. We cannot check the accessibility of |
119 | names used in a decl-specifier-seq until we know what is being | |
120 | declared because code like: | |
121 | ||
c8094d83 | 122 | class A { |
0cbd7506 MS |
123 | class B {}; |
124 | B* f(); | |
3e1f1ba5 NS |
125 | } |
126 | ||
127 | A::B* A::f() { return 0; } | |
128 | ||
d6b418fa | 129 | is valid, even though `A::B' is not generally accessible. */ |
7e6a72cb | 130 | vec<deferred_access_check, va_gc> *deferred_access_checks; |
c8094d83 | 131 | |
3e1f1ba5 NS |
132 | /* The current mode of access checks. */ |
133 | enum deferring_kind deferring_access_checks_kind; | |
a79683d5 | 134 | }; |
3e1f1ba5 | 135 | |
cf22909c | 136 | /* Data for deferred access checking. */ |
9771b263 | 137 | static GTY(()) vec<deferred_access, va_gc> *deferred_access_stack; |
3e1f1ba5 | 138 | static GTY(()) unsigned deferred_access_no_check; |
cf22909c KL |
139 | |
140 | /* Save the current deferred access states and start deferred | |
141 | access checking iff DEFER_P is true. */ | |
142 | ||
572c2b17 AP |
143 | void |
144 | push_deferring_access_checks (deferring_kind deferring) | |
cf22909c | 145 | { |
78757caa KL |
146 | /* For context like template instantiation, access checking |
147 | disabling applies to all nested context. */ | |
3e1f1ba5 NS |
148 | if (deferred_access_no_check || deferring == dk_no_check) |
149 | deferred_access_no_check++; | |
cf22909c | 150 | else |
3e1f1ba5 | 151 | { |
f32682ca | 152 | deferred_access e = {NULL, deferring}; |
9771b263 | 153 | vec_safe_push (deferred_access_stack, e); |
3e1f1ba5 | 154 | } |
cf22909c KL |
155 | } |
156 | ||
0ef08a81 JM |
157 | /* Save the current deferred access states and start deferred access |
158 | checking, continuing the set of deferred checks in CHECKS. */ | |
159 | ||
160 | void | |
161 | reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks) | |
162 | { | |
163 | push_deferring_access_checks (dk_deferred); | |
164 | if (!deferred_access_no_check) | |
165 | deferred_access_stack->last().deferred_access_checks = checks; | |
166 | } | |
167 | ||
cf22909c KL |
168 | /* Resume deferring access checks again after we stopped doing |
169 | this previously. */ | |
170 | ||
572c2b17 AP |
171 | void |
172 | resume_deferring_access_checks (void) | |
cf22909c | 173 | { |
3e1f1ba5 | 174 | if (!deferred_access_no_check) |
9771b263 | 175 | deferred_access_stack->last().deferring_access_checks_kind = dk_deferred; |
cf22909c KL |
176 | } |
177 | ||
178 | /* Stop deferring access checks. */ | |
179 | ||
572c2b17 AP |
180 | void |
181 | stop_deferring_access_checks (void) | |
cf22909c | 182 | { |
3e1f1ba5 | 183 | if (!deferred_access_no_check) |
9771b263 | 184 | deferred_access_stack->last().deferring_access_checks_kind = dk_no_deferred; |
cf22909c KL |
185 | } |
186 | ||
187 | /* Discard the current deferred access checks and restore the | |
188 | previous states. */ | |
189 | ||
572c2b17 AP |
190 | void |
191 | pop_deferring_access_checks (void) | |
cf22909c | 192 | { |
3e1f1ba5 NS |
193 | if (deferred_access_no_check) |
194 | deferred_access_no_check--; | |
195 | else | |
9771b263 | 196 | deferred_access_stack->pop (); |
cf22909c KL |
197 | } |
198 | ||
c8094d83 MS |
199 | /* Returns a TREE_LIST representing the deferred checks. |
200 | The TREE_PURPOSE of each node is the type through which the | |
cf22909c KL |
201 | access occurred; the TREE_VALUE is the declaration named. |
202 | */ | |
203 | ||
9771b263 | 204 | vec<deferred_access_check, va_gc> * |
572c2b17 | 205 | get_deferred_access_checks (void) |
cf22909c | 206 | { |
3e1f1ba5 NS |
207 | if (deferred_access_no_check) |
208 | return NULL; | |
209 | else | |
9771b263 | 210 | return (deferred_access_stack->last().deferred_access_checks); |
cf22909c KL |
211 | } |
212 | ||
213 | /* Take current deferred checks and combine with the | |
214 | previous states if we also defer checks previously. | |
215 | Otherwise perform checks now. */ | |
216 | ||
572c2b17 AP |
217 | void |
218 | pop_to_parent_deferring_access_checks (void) | |
cf22909c | 219 | { |
3e1f1ba5 NS |
220 | if (deferred_access_no_check) |
221 | deferred_access_no_check--; | |
222 | else | |
223 | { | |
9771b263 | 224 | vec<deferred_access_check, va_gc> *checks; |
3e1f1ba5 NS |
225 | deferred_access *ptr; |
226 | ||
9771b263 | 227 | checks = (deferred_access_stack->last ().deferred_access_checks); |
3e1f1ba5 | 228 | |
9771b263 DN |
229 | deferred_access_stack->pop (); |
230 | ptr = &deferred_access_stack->last (); | |
3e1f1ba5 NS |
231 | if (ptr->deferring_access_checks_kind == dk_no_deferred) |
232 | { | |
233 | /* Check access. */ | |
0e69fdf0 | 234 | perform_access_checks (checks, tf_warning_or_error); |
3e1f1ba5 NS |
235 | } |
236 | else | |
237 | { | |
238 | /* Merge with parent. */ | |
d6b418fa SM |
239 | int i, j; |
240 | deferred_access_check *chk, *probe; | |
c8094d83 | 241 | |
9771b263 | 242 | FOR_EACH_VEC_SAFE_ELT (checks, i, chk) |
3e1f1ba5 | 243 | { |
9771b263 | 244 | FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, j, probe) |
d6b418fa SM |
245 | { |
246 | if (probe->binfo == chk->binfo && | |
247 | probe->decl == chk->decl && | |
248 | probe->diag_decl == chk->diag_decl) | |
249 | goto found; | |
250 | } | |
3e1f1ba5 | 251 | /* Insert into parent's checks. */ |
9771b263 | 252 | vec_safe_push (ptr->deferred_access_checks, *chk); |
3e1f1ba5 NS |
253 | found:; |
254 | } | |
255 | } | |
256 | } | |
cf22909c KL |
257 | } |
258 | ||
be246ac2 AS |
259 | /* Called from enforce_access. A class has attempted (but failed) to access |
260 | DECL. It is already established that a baseclass of that class, | |
261 | PARENT_BINFO, has private access to DECL. Examine certain special cases | |
262 | to find a decl that accurately describes the source of the problem. If | |
263 | none of the special cases apply, simply return DECL as the source of the | |
264 | problem. */ | |
265 | ||
266 | static tree | |
267 | get_class_access_diagnostic_decl (tree parent_binfo, tree decl) | |
268 | { | |
269 | /* When a class is denied access to a decl in a baseclass, most of the | |
270 | time it is because the decl itself was declared as private at the point | |
271 | of declaration. | |
272 | ||
273 | However, in C++, there are (at least) two situations in which a decl | |
274 | can be private even though it was not originally defined as such. | |
275 | These two situations only apply if a baseclass had private access to | |
276 | DECL (this function is only called if that is the case). */ | |
277 | ||
278 | /* We should first check whether the reason the parent had private access | |
279 | to DECL was simply because DECL was created and declared as private in | |
280 | the parent. If it was, then DECL is definitively the source of the | |
281 | problem. */ | |
282 | if (SAME_BINFO_TYPE_P (context_for_name_lookup (decl), | |
283 | BINFO_TYPE (parent_binfo))) | |
284 | return decl; | |
285 | ||
286 | /* 1. If the "using" keyword is used to inherit DECL within the parent, | |
287 | this may cause DECL to be private, so we should return the using | |
288 | statement as the source of the problem. | |
289 | ||
290 | Scan the fields of PARENT_BINFO and see if there are any using decls. If | |
291 | there are, see if they inherit DECL. If they do, that's where DECL must | |
292 | have been declared private. */ | |
293 | ||
294 | for (tree parent_field = TYPE_FIELDS (BINFO_TYPE (parent_binfo)); | |
295 | parent_field; | |
296 | parent_field = DECL_CHAIN (parent_field)) | |
297 | /* Not necessary, but also check TREE_PRIVATE for the sake of | |
298 | eliminating obviously non-relevant using decls. */ | |
299 | if (TREE_CODE (parent_field) == USING_DECL | |
300 | && TREE_PRIVATE (parent_field)) | |
301 | { | |
302 | tree decl_stripped = strip_using_decl (parent_field); | |
303 | ||
304 | /* The using statement might be overloaded. If so, we need to | |
305 | check all of the overloads. */ | |
306 | for (ovl_iterator iter (decl_stripped); iter; ++iter) | |
307 | /* If equal, the using statement inherits DECL, and so is the | |
308 | source of the access failure, so return it. */ | |
309 | if (*iter == decl) | |
310 | return parent_field; | |
311 | } | |
312 | ||
313 | /* 2. If DECL was privately inherited by the parent class, then DECL will | |
314 | be inaccessible, even though it may originally have been accessible to | |
315 | deriving classes. In that case, the fault lies with the parent, since it | |
316 | used a private inheritance, so we return the parent as the source of the | |
317 | problem. | |
318 | ||
319 | Since this is the last check, we just assume it's true. At worst, it | |
320 | will simply point to the class that failed to give access, which is | |
321 | technically true. */ | |
322 | return TYPE_NAME (BINFO_TYPE (parent_binfo)); | |
323 | } | |
324 | ||
92bed036 PP |
325 | /* If the current scope isn't allowed to access DECL along |
326 | BASETYPE_PATH, give an error, or if we're parsing a function or class | |
327 | template, defer the access check to be performed at instantiation time. | |
328 | The most derived class in BASETYPE_PATH is the one used to qualify DECL. | |
329 | DIAG_DECL is the declaration to use in the error diagnostic. */ | |
330 | ||
331 | static bool | |
332 | enforce_access (tree basetype_path, tree decl, tree diag_decl, | |
333 | tsubst_flags_t complain, access_failure_info *afi = NULL) | |
334 | { | |
335 | gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO); | |
336 | ||
337 | if (flag_new_inheriting_ctors | |
338 | && DECL_INHERITED_CTOR (decl)) | |
339 | { | |
340 | /* 7.3.3/18: The additional constructors are accessible if they would be | |
341 | accessible when used to construct an object of the corresponding base | |
342 | class. */ | |
343 | decl = strip_inheriting_ctors (decl); | |
344 | basetype_path = lookup_base (basetype_path, DECL_CONTEXT (decl), | |
345 | ba_any, NULL, complain); | |
346 | } | |
347 | ||
348 | tree cs = current_scope (); | |
349 | if (processing_template_decl | |
350 | && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)) | |
351 | if (tree template_info = get_template_info (cs)) | |
352 | { | |
353 | /* When parsing a function or class template, we in general need to | |
354 | defer access checks until template instantiation time, since a friend | |
355 | declaration may grant access only to a particular specialization of | |
356 | the template. */ | |
357 | ||
358 | if (accessible_p (basetype_path, decl, /*consider_local_p=*/true)) | |
359 | /* But if the member is deemed accessible at parse time, then we can | |
360 | assume it'll be accessible at instantiation time. */ | |
361 | return true; | |
362 | ||
28462a44 PP |
363 | /* Access of a dependent decl should be rechecked after tsubst'ing |
364 | into the user of the decl, rather than explicitly deferring the | |
365 | check here. */ | |
366 | gcc_assert (!uses_template_parms (decl)); | |
367 | if (TREE_CODE (decl) == FIELD_DECL) | |
368 | gcc_assert (!uses_template_parms (DECL_CONTEXT (decl))); | |
369 | ||
92bed036 | 370 | /* Defer this access check until instantiation time. */ |
668ef28f PP |
371 | deferred_access_check access_check; |
372 | access_check.binfo = basetype_path; | |
373 | access_check.decl = decl; | |
374 | access_check.diag_decl = diag_decl; | |
375 | access_check.loc = input_location; | |
376 | vec_safe_push (TI_DEFERRED_ACCESS_CHECKS (template_info), access_check); | |
92bed036 PP |
377 | return true; |
378 | } | |
379 | ||
380 | if (!accessible_p (basetype_path, decl, /*consider_local_p=*/true)) | |
381 | { | |
382 | if (flag_new_inheriting_ctors) | |
383 | diag_decl = strip_inheriting_ctors (diag_decl); | |
384 | if (complain & tf_error) | |
7e0f147a | 385 | { |
be246ac2 AS |
386 | access_kind access_failure_reason = ak_none; |
387 | ||
388 | /* By default, using the decl as the source of the problem will | |
389 | usually give correct results. */ | |
7e0f147a | 390 | tree diag_location = diag_decl; |
7e0f147a | 391 | |
be246ac2 AS |
392 | /* However, if a parent of BASETYPE_PATH had private access to decl, |
393 | then it actually might be the case that the source of the problem | |
394 | is not DECL. */ | |
7e0f147a AS |
395 | tree parent_binfo = get_parent_with_private_access (decl, |
396 | basetype_path); | |
397 | ||
be246ac2 AS |
398 | /* So if a parent did have private access, then we need to do |
399 | special checks to obtain the best diagnostic location decl. */ | |
400 | if (parent_binfo != NULL_TREE) | |
7e0f147a | 401 | { |
be246ac2 AS |
402 | diag_location = get_class_access_diagnostic_decl (parent_binfo, |
403 | diag_decl); | |
404 | ||
405 | /* We also at this point know that the reason access failed was | |
406 | because decl was private. */ | |
407 | access_failure_reason = ak_private; | |
7e0f147a AS |
408 | } |
409 | ||
410 | /* Finally, generate an error message. */ | |
411 | complain_about_access (decl, diag_decl, diag_location, true, | |
be246ac2 | 412 | access_failure_reason); |
7e0f147a | 413 | } |
92bed036 PP |
414 | if (afi) |
415 | afi->record_access_failure (basetype_path, decl, diag_decl); | |
416 | return false; | |
417 | } | |
418 | ||
419 | return true; | |
420 | } | |
421 | ||
6b648482 MM |
422 | /* Perform the access checks in CHECKS. The TREE_PURPOSE of each node |
423 | is the BINFO indicating the qualifying scope used to access the | |
0e69fdf0 PC |
424 | DECL node stored in the TREE_VALUE of the node. If CHECKS is empty |
425 | or we aren't in SFINAE context or all the checks succeed return TRUE, | |
426 | otherwise FALSE. */ | |
6b648482 | 427 | |
0e69fdf0 | 428 | bool |
9771b263 | 429 | perform_access_checks (vec<deferred_access_check, va_gc> *checks, |
0e69fdf0 | 430 | tsubst_flags_t complain) |
6b648482 | 431 | { |
d6b418fa SM |
432 | int i; |
433 | deferred_access_check *chk; | |
b3ff651a | 434 | location_t loc = input_location; |
0e69fdf0 | 435 | bool ok = true; |
d6b418fa SM |
436 | |
437 | if (!checks) | |
0e69fdf0 | 438 | return true; |
d6b418fa | 439 | |
9771b263 | 440 | FOR_EACH_VEC_SAFE_ELT (checks, i, chk) |
b3ff651a JM |
441 | { |
442 | input_location = chk->loc; | |
0e69fdf0 | 443 | ok &= enforce_access (chk->binfo, chk->decl, chk->diag_decl, complain); |
b3ff651a JM |
444 | } |
445 | ||
446 | input_location = loc; | |
0e69fdf0 | 447 | return (complain & tf_error) ? true : ok; |
6b648482 MM |
448 | } |
449 | ||
25903d03 KL |
450 | /* Perform the deferred access checks. |
451 | ||
452 | After performing the checks, we still have to keep the list | |
453 | `deferred_access_stack->deferred_access_checks' since we may want | |
454 | to check access for them again later in a different context. | |
455 | For example: | |
456 | ||
457 | class A { | |
458 | typedef int X; | |
459 | static X a; | |
460 | }; | |
461 | A::X A::a, x; // No error for `A::a', error for `x' | |
462 | ||
463 | We have to perform deferred access of `A::X', first with `A::a', | |
0e69fdf0 | 464 | next with `x'. Return value like perform_access_checks above. */ |
cf22909c | 465 | |
0e69fdf0 PC |
466 | bool |
467 | perform_deferred_access_checks (tsubst_flags_t complain) | |
cf22909c | 468 | { |
0e69fdf0 | 469 | return perform_access_checks (get_deferred_access_checks (), complain); |
cf22909c KL |
470 | } |
471 | ||
472 | /* Defer checking the accessibility of DECL, when looked up in | |
0e69fdf0 | 473 | BINFO. DIAG_DECL is the declaration to use to print diagnostics. |
10791753 DM |
474 | Return value like perform_access_checks above. |
475 | If non-NULL, report failures to AFI. */ | |
cf22909c | 476 | |
0e69fdf0 PC |
477 | bool |
478 | perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl, | |
10791753 DM |
479 | tsubst_flags_t complain, |
480 | access_failure_info *afi) | |
cf22909c | 481 | { |
d6b418fa | 482 | int i; |
3e1f1ba5 | 483 | deferred_access *ptr; |
d6b418fa | 484 | deferred_access_check *chk; |
d6b418fa | 485 | |
92bed036 | 486 | /* Exit if we are in a context that no access checking is performed. */ |
3e1f1ba5 | 487 | if (deferred_access_no_check) |
0e69fdf0 | 488 | return true; |
c8094d83 | 489 | |
50bc768d | 490 | gcc_assert (TREE_CODE (binfo) == TREE_BINFO); |
0f2a66c9 | 491 | |
9771b263 | 492 | ptr = &deferred_access_stack->last (); |
c8094d83 | 493 | |
cf22909c | 494 | /* If we are not supposed to defer access checks, just check now. */ |
3e1f1ba5 | 495 | if (ptr->deferring_access_checks_kind == dk_no_deferred) |
cf22909c | 496 | { |
10791753 | 497 | bool ok = enforce_access (binfo, decl, diag_decl, complain, afi); |
0e69fdf0 | 498 | return (complain & tf_error) ? true : ok; |
cf22909c | 499 | } |
c8094d83 | 500 | |
cf22909c | 501 | /* See if we are already going to perform this check. */ |
9771b263 | 502 | FOR_EACH_VEC_SAFE_ELT (ptr->deferred_access_checks, i, chk) |
d6b418fa SM |
503 | { |
504 | if (chk->decl == decl && chk->binfo == binfo && | |
505 | chk->diag_decl == diag_decl) | |
506 | { | |
0e69fdf0 | 507 | return true; |
d6b418fa SM |
508 | } |
509 | } | |
cf22909c | 510 | /* If not, record the check. */ |
f32682ca | 511 | deferred_access_check new_access = {binfo, decl, diag_decl, input_location}; |
9771b263 | 512 | vec_safe_push (ptr->deferred_access_checks, new_access); |
f7d042e2 JM |
513 | |
514 | return true; | |
515 | } | |
516 | ||
838dfd8a | 517 | /* Returns nonzero if the current statement is a full expression, |
f2c5f623 BC |
518 | i.e. temporaries created during that statement should be destroyed |
519 | at the end of the statement. */ | |
35b1567d | 520 | |
f2c5f623 | 521 | int |
3a978d72 | 522 | stmts_are_full_exprs_p (void) |
f2c5f623 | 523 | { |
ae499cce MM |
524 | return current_stmt_tree ()->stmts_are_full_exprs_p; |
525 | } | |
526 | ||
ed3d0b14 ILT |
527 | /* T is a statement. Add it to the statement-tree. This is the C++ |
528 | version. The C/ObjC frontends have a slightly different version of | |
529 | this function. */ | |
530 | ||
531 | tree | |
532 | add_stmt (tree t) | |
533 | { | |
534 | enum tree_code code = TREE_CODE (t); | |
535 | ||
536 | if (EXPR_P (t) && code != LABEL_EXPR) | |
537 | { | |
538 | if (!EXPR_HAS_LOCATION (t)) | |
539 | SET_EXPR_LOCATION (t, input_location); | |
540 | ||
541 | /* When we expand a statement-tree, we must know whether or not the | |
542 | statements are full-expressions. We record that fact here. */ | |
1cb1986c JJ |
543 | if (STATEMENT_CODE_P (TREE_CODE (t))) |
544 | STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); | |
ed3d0b14 ILT |
545 | } |
546 | ||
0450fc0b PP |
547 | if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) |
548 | STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; | |
549 | ||
ed3d0b14 ILT |
550 | /* Add T to the statement-tree. Non-side-effect statements need to be |
551 | recorded during statement expressions. */ | |
9771b263 | 552 | gcc_checking_assert (!stmt_list_stack->is_empty ()); |
ed3d0b14 ILT |
553 | append_to_statement_list_force (t, &cur_stmt_list); |
554 | ||
555 | return t; | |
556 | } | |
557 | ||
e8924938 | 558 | /* Returns the stmt_tree to which statements are currently being added. */ |
ae499cce MM |
559 | |
560 | stmt_tree | |
3a978d72 | 561 | current_stmt_tree (void) |
ae499cce | 562 | { |
c8094d83 MS |
563 | return (cfun |
564 | ? &cfun->language->base.x_stmt_tree | |
ae499cce | 565 | : &scope_chain->x_stmt_tree); |
f2c5f623 | 566 | } |
35b1567d | 567 | |
543a0daa RH |
568 | /* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */ |
569 | ||
570 | static tree | |
571 | maybe_cleanup_point_expr (tree expr) | |
572 | { | |
573 | if (!processing_template_decl && stmts_are_full_exprs_p ()) | |
0ad28dde | 574 | expr = fold_build_cleanup_point_expr (TREE_TYPE (expr), expr); |
543a0daa RH |
575 | return expr; |
576 | } | |
577 | ||
0ad28dde | 578 | /* Like maybe_cleanup_point_expr except have the type of the new expression be |
22423a1f KH |
579 | void so we don't need to create a temporary variable to hold the inner |
580 | expression. The reason why we do this is because the original type might be | |
581 | an aggregate and we cannot create a temporary variable for that type. */ | |
0ad28dde | 582 | |
14a3430e | 583 | tree |
0ad28dde AP |
584 | maybe_cleanup_point_expr_void (tree expr) |
585 | { | |
586 | if (!processing_template_decl && stmts_are_full_exprs_p ()) | |
587 | expr = fold_build_cleanup_point_expr (void_type_node, expr); | |
588 | return expr; | |
589 | } | |
590 | ||
591 | ||
592 | ||
543a0daa RH |
593 | /* Create a declaration statement for the declaration given by the DECL. */ |
594 | ||
595 | void | |
350fae66 | 596 | add_decl_expr (tree decl) |
543a0daa | 597 | { |
b1e47084 | 598 | tree r = build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl); |
b187901e AP |
599 | if (DECL_INITIAL (decl) |
600 | || (DECL_SIZE (decl) && TREE_SIDE_EFFECTS (DECL_SIZE (decl)))) | |
0ad28dde | 601 | r = maybe_cleanup_point_expr_void (r); |
543a0daa RH |
602 | add_stmt (r); |
603 | } | |
604 | ||
006783f4 JM |
605 | /* Set EXPR_LOCATION of the cleanups of any CLEANUP_STMT in STMTS to LOC. */ |
606 | ||
607 | static void | |
608 | set_cleanup_locs (tree stmts, location_t loc) | |
609 | { | |
610 | if (TREE_CODE (stmts) == CLEANUP_STMT) | |
611 | { | |
612 | protected_set_expr_location (CLEANUP_EXPR (stmts), loc); | |
613 | set_cleanup_locs (CLEANUP_BODY (stmts), loc); | |
614 | } | |
615 | else if (TREE_CODE (stmts) == STATEMENT_LIST) | |
0f54cc9c JM |
616 | for (tree stmt : tsi_range (stmts)) |
617 | set_cleanup_locs (stmt, loc); | |
006783f4 JM |
618 | } |
619 | ||
f2c5f623 | 620 | /* Finish a scope. */ |
35b1567d | 621 | |
20aff0b3 | 622 | tree |
325c3691 | 623 | do_poplevel (tree stmt_list) |
35b1567d | 624 | { |
325c3691 | 625 | tree block = NULL; |
35b1567d | 626 | |
f2c5f623 | 627 | if (stmts_are_full_exprs_p ()) |
325c3691 | 628 | block = poplevel (kept_level_p (), 1, 0); |
f2c5f623 | 629 | |
325c3691 | 630 | stmt_list = pop_stmt_list (stmt_list); |
c8094d83 | 631 | |
006783f4 JM |
632 | /* input_location is the last token of the scope, usually a }. */ |
633 | set_cleanup_locs (stmt_list, input_location); | |
634 | ||
325c3691 RH |
635 | if (!processing_template_decl) |
636 | { | |
c2255bc4 | 637 | stmt_list = c_build_bind_expr (input_location, block, stmt_list); |
325c3691 | 638 | /* ??? See c_end_compound_stmt re statement expressions. */ |
35b1567d BC |
639 | } |
640 | ||
325c3691 | 641 | return stmt_list; |
35b1567d BC |
642 | } |
643 | ||
c8094d83 | 644 | /* Begin a new scope. */ |
35b1567d | 645 | |
325c3691 | 646 | static tree |
92bc1323 | 647 | do_pushlevel (scope_kind sk) |
35b1567d | 648 | { |
325c3691 | 649 | tree ret = push_stmt_list (); |
f2c5f623 | 650 | if (stmts_are_full_exprs_p ()) |
325c3691 RH |
651 | begin_scope (sk, NULL); |
652 | return ret; | |
653 | } | |
5a508662 RH |
654 | |
655 | /* Queue a cleanup. CLEANUP is an expression/statement to be executed | |
656 | when the current scope is exited. EH_ONLY is true when this is not | |
657 | meant to apply to normal control flow transfer. */ | |
658 | ||
659 | void | |
660 | push_cleanup (tree decl, tree cleanup, bool eh_only) | |
661 | { | |
c2255bc4 | 662 | tree stmt = build_stmt (input_location, CLEANUP_STMT, NULL, cleanup, decl); |
5a508662 RH |
663 | CLEANUP_EH_ONLY (stmt) = eh_only; |
664 | add_stmt (stmt); | |
665 | CLEANUP_BODY (stmt) = push_stmt_list (); | |
666 | } | |
325c3691 | 667 | |
20f18c3c JM |
668 | /* Simple infinite loop tracking for -Wreturn-type. We keep a stack of all |
669 | the current loops, represented by 'NULL_TREE' if we've seen a possible | |
670 | exit, and 'error_mark_node' if not. This is currently used only to | |
671 | suppress the warning about a function with no return statements, and | |
672 | therefore we don't bother noting returns as possible exits. We also | |
673 | don't bother with gotos. */ | |
674 | ||
675 | static void | |
676 | begin_maybe_infinite_loop (tree cond) | |
677 | { | |
678 | /* Only track this while parsing a function, not during instantiation. */ | |
679 | if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl) | |
680 | && !processing_template_decl)) | |
681 | return; | |
682 | bool maybe_infinite = true; | |
683 | if (cond) | |
684 | { | |
234bef96 | 685 | cond = fold_non_dependent_expr (cond); |
20f18c3c JM |
686 | maybe_infinite = integer_nonzerop (cond); |
687 | } | |
688 | vec_safe_push (cp_function_chain->infinite_loops, | |
689 | maybe_infinite ? error_mark_node : NULL_TREE); | |
690 | ||
691 | } | |
692 | ||
693 | /* A break is a possible exit for the current loop. */ | |
694 | ||
695 | void | |
696 | break_maybe_infinite_loop (void) | |
697 | { | |
698 | if (!cfun) | |
699 | return; | |
700 | cp_function_chain->infinite_loops->last() = NULL_TREE; | |
701 | } | |
702 | ||
703 | /* If we reach the end of the loop without seeing a possible exit, we have | |
704 | an infinite loop. */ | |
705 | ||
706 | static void | |
707 | end_maybe_infinite_loop (tree cond) | |
708 | { | |
709 | if (!cfun || (DECL_TEMPLATE_INSTANTIATION (current_function_decl) | |
710 | && !processing_template_decl)) | |
711 | return; | |
712 | tree current = cp_function_chain->infinite_loops->pop(); | |
713 | if (current != NULL_TREE) | |
714 | { | |
715 | cond = fold_non_dependent_expr (cond); | |
20f18c3c JM |
716 | if (integer_nonzerop (cond)) |
717 | current_function_infinite_loop = 1; | |
718 | } | |
719 | } | |
720 | ||
721 | ||
caf2523d RH |
722 | /* Begin a conditional that might contain a declaration. When generating |
723 | normal code, we want the declaration to appear before the statement | |
724 | containing the conditional. When generating template code, we want the | |
350fae66 | 725 | conditional to be rendered as the raw DECL_EXPR. */ |
325c3691 RH |
726 | |
727 | static void | |
caf2523d | 728 | begin_cond (tree *cond_p) |
325c3691 | 729 | { |
caf2523d RH |
730 | if (processing_template_decl) |
731 | *cond_p = push_stmt_list (); | |
732 | } | |
733 | ||
734 | /* Finish such a conditional. */ | |
735 | ||
736 | static void | |
737 | finish_cond (tree *cond_p, tree expr) | |
738 | { | |
739 | if (processing_template_decl) | |
35b1567d | 740 | { |
caf2523d | 741 | tree cond = pop_stmt_list (*cond_p); |
5d80a306 | 742 | |
fdaf2f48 JM |
743 | if (expr == NULL_TREE) |
744 | /* Empty condition in 'for'. */ | |
745 | gcc_assert (empty_expr_stmt_p (cond)); | |
746 | else if (check_for_bare_parameter_packs (expr)) | |
747 | expr = error_mark_node; | |
748 | else if (!empty_expr_stmt_p (cond)) | |
749 | expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), cond, expr); | |
35b1567d | 750 | } |
caf2523d | 751 | *cond_p = expr; |
35b1567d BC |
752 | } |
753 | ||
325c3691 RH |
754 | /* If *COND_P specifies a conditional with a declaration, transform the |
755 | loop such that | |
0cbd7506 MS |
756 | while (A x = 42) { } |
757 | for (; A x = 42;) { } | |
325c3691 | 758 | becomes |
0cbd7506 MS |
759 | while (true) { A x = 42; if (!x) break; } |
760 | for (;;) { A x = 42; if (!x) break; } | |
caf2523d RH |
761 | The statement list for BODY will be empty if the conditional did |
762 | not declare anything. */ | |
c8094d83 | 763 | |
325c3691 | 764 | static void |
caf2523d | 765 | simplify_loop_decl_cond (tree *cond_p, tree body) |
325c3691 | 766 | { |
caf2523d | 767 | tree cond, if_stmt; |
325c3691 | 768 | |
caf2523d RH |
769 | if (!TREE_SIDE_EFFECTS (body)) |
770 | return; | |
325c3691 | 771 | |
caf2523d RH |
772 | cond = *cond_p; |
773 | *cond_p = boolean_true_node; | |
c8094d83 | 774 | |
caf2523d | 775 | if_stmt = begin_if_stmt (); |
e51fbec3 | 776 | cond = cp_build_unary_op (TRUTH_NOT_EXPR, cond, false, tf_warning_or_error); |
caf2523d RH |
777 | finish_if_stmt_cond (cond, if_stmt); |
778 | finish_break_stmt (); | |
779 | finish_then_clause (if_stmt); | |
780 | finish_if_stmt (if_stmt); | |
781 | } | |
325c3691 | 782 | |
35b1567d BC |
783 | /* Finish a goto-statement. */ |
784 | ||
3e4d04a1 | 785 | tree |
3a978d72 | 786 | finish_goto_stmt (tree destination) |
35b1567d | 787 | { |
9dc6f476 | 788 | if (identifier_p (destination)) |
35b1567d BC |
789 | destination = lookup_label (destination); |
790 | ||
791 | /* We warn about unused labels with -Wunused. That means we have to | |
792 | mark the used labels as used. */ | |
793 | if (TREE_CODE (destination) == LABEL_DECL) | |
794 | TREE_USED (destination) = 1; | |
fc2b8477 MM |
795 | else |
796 | { | |
84628aa8 | 797 | destination = mark_rvalue_use (destination); |
fc2b8477 | 798 | if (!processing_template_decl) |
f5651df1 | 799 | { |
4b978f96 PC |
800 | destination = cp_convert (ptr_type_node, destination, |
801 | tf_warning_or_error); | |
f5651df1 JJ |
802 | if (error_operand_p (destination)) |
803 | return NULL_TREE; | |
53406315 JJ |
804 | destination |
805 | = fold_build_cleanup_point_expr (TREE_TYPE (destination), | |
806 | destination); | |
f5651df1 | 807 | } |
fc2b8477 | 808 | } |
c8094d83 | 809 | |
35b1567d BC |
810 | check_goto (destination); |
811 | ||
7fef86d3 | 812 | add_stmt (build_predict_expr (PRED_GOTO, NOT_TAKEN)); |
c2255bc4 | 813 | return add_stmt (build_stmt (input_location, GOTO_EXPR, destination)); |
35b1567d BC |
814 | } |
815 | ||
ed5511d9 | 816 | /* COND is the condition-expression for an if, while, etc., |
d4033c81 MLI |
817 | statement. Convert it to a boolean value, if appropriate. |
818 | In addition, verify sequence points if -Wsequence-point is enabled. */ | |
ed5511d9 | 819 | |
8ce33230 | 820 | static tree |
3a978d72 | 821 | maybe_convert_cond (tree cond) |
ed5511d9 MM |
822 | { |
823 | /* Empty conditions remain empty. */ | |
824 | if (!cond) | |
825 | return NULL_TREE; | |
826 | ||
827 | /* Wait until we instantiate templates before doing conversion. */ | |
4556c5b3 | 828 | if (type_dependent_expression_p (cond)) |
c1051bf7 | 829 | return cond; |
ed5511d9 | 830 | |
4556c5b3 | 831 | if (warn_sequence_point && !processing_template_decl) |
d4033c81 MLI |
832 | verify_sequence_points (cond); |
833 | ||
ed5511d9 MM |
834 | /* Do the conversion. */ |
835 | cond = convert_from_reference (cond); | |
fbc8d2d3 ILT |
836 | |
837 | if (TREE_CODE (cond) == MODIFY_EXPR | |
1db01ff9 | 838 | && warn_parentheses |
65870e75 | 839 | && !warning_suppressed_p (cond, OPT_Wparentheses) |
f9d0ca40 | 840 | && warning_at (cp_expr_loc_or_input_loc (cond), |
1db01ff9 JJ |
841 | OPT_Wparentheses, "suggest parentheses around " |
842 | "assignment used as truth value")) | |
65870e75 | 843 | suppress_warning (cond, OPT_Wparentheses); |
fbc8d2d3 | 844 | |
ed5511d9 MM |
845 | return condition_conversion (cond); |
846 | } | |
847 | ||
9bfadf57 | 848 | /* Finish an expression-statement, whose EXPRESSION is as indicated. */ |
a7e4cfa0 | 849 | |
3e4d04a1 | 850 | tree |
3a978d72 | 851 | finish_expr_stmt (tree expr) |
ad321293 | 852 | { |
3e4d04a1 | 853 | tree r = NULL_TREE; |
2ebd93e1 | 854 | location_t loc = EXPR_LOCATION (expr); |
3e4d04a1 | 855 | |
ce4a0391 | 856 | if (expr != NULL_TREE) |
ad321293 | 857 | { |
0fd9d492 JM |
858 | /* If we ran into a problem, make sure we complained. */ |
859 | gcc_assert (expr != error_mark_node || seen_error ()); | |
860 | ||
a5bcc582 | 861 | if (!processing_template_decl) |
3a5b9284 RH |
862 | { |
863 | if (warn_sequence_point) | |
864 | verify_sequence_points (expr); | |
ebeb2c24 | 865 | expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error); |
3a5b9284 | 866 | } |
47d4c811 | 867 | else if (!type_dependent_expression_p (expr)) |
43e1e8b5 | 868 | convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, |
5ade1ed2 | 869 | tf_warning_or_error); |
325c3691 | 870 | |
7b3e2d46 | 871 | if (check_for_bare_parameter_packs (expr)) |
4439d02f | 872 | expr = error_mark_node; |
5d80a306 | 873 | |
325c3691 | 874 | /* Simplification of inner statement expressions, compound exprs, |
ca5b80f3 | 875 | etc can result in us already having an EXPR_STMT. */ |
543a0daa RH |
876 | if (TREE_CODE (expr) != CLEANUP_POINT_EXPR) |
877 | { | |
878 | if (TREE_CODE (expr) != EXPR_STMT) | |
2ebd93e1 | 879 | expr = build_stmt (loc, EXPR_STMT, expr); |
0ad28dde | 880 | expr = maybe_cleanup_point_expr_void (expr); |
543a0daa RH |
881 | } |
882 | ||
325c3691 | 883 | r = add_stmt (expr); |
35b1567d | 884 | } |
364460b6 | 885 | |
3e4d04a1 | 886 | return r; |
35b1567d BC |
887 | } |
888 | ||
35b1567d | 889 | |
ad321293 MM |
890 | /* Begin an if-statement. Returns a newly created IF_STMT if |
891 | appropriate. */ | |
892 | ||
893 | tree | |
3a978d72 | 894 | begin_if_stmt (void) |
ad321293 | 895 | { |
325c3691 | 896 | tree r, scope; |
1eb2a14d | 897 | scope = do_pushlevel (sk_cond); |
545f261b NF |
898 | r = build_stmt (input_location, IF_STMT, NULL_TREE, |
899 | NULL_TREE, NULL_TREE, scope); | |
99f9d4b1 | 900 | current_binding_level->this_entity = r; |
caf2523d | 901 | begin_cond (&IF_COND (r)); |
ad321293 MM |
902 | return r; |
903 | } | |
904 | ||
14da3939 MP |
905 | /* Returns true if FN, a CALL_EXPR, is a call to |
906 | std::is_constant_evaluated or __builtin_is_constant_evaluated. */ | |
907 | ||
908 | static bool | |
909 | is_std_constant_evaluated_p (tree fn) | |
910 | { | |
911 | /* std::is_constant_evaluated takes no arguments. */ | |
912 | if (call_expr_nargs (fn) != 0) | |
913 | return false; | |
914 | ||
915 | tree fndecl = cp_get_callee_fndecl_nofold (fn); | |
15ed55ea MP |
916 | if (fndecl == NULL_TREE) |
917 | return false; | |
918 | ||
14da3939 MP |
919 | if (fndecl_built_in_p (fndecl, CP_BUILT_IN_IS_CONSTANT_EVALUATED, |
920 | BUILT_IN_FRONTEND)) | |
921 | return true; | |
922 | ||
923 | if (!decl_in_std_namespace_p (fndecl)) | |
924 | return false; | |
925 | ||
926 | tree name = DECL_NAME (fndecl); | |
927 | return name && id_equal (name, "is_constant_evaluated"); | |
928 | } | |
929 | ||
26dbe85a MP |
930 | /* Callback function for maybe_warn_for_constant_evaluated that looks |
931 | for calls to std::is_constant_evaluated in TP. */ | |
932 | ||
933 | static tree | |
934 | find_std_constant_evaluated_r (tree *tp, int *walk_subtrees, void *) | |
935 | { | |
936 | tree t = *tp; | |
937 | ||
938 | if (TYPE_P (t) || TREE_CONSTANT (t)) | |
939 | { | |
940 | *walk_subtrees = false; | |
941 | return NULL_TREE; | |
942 | } | |
943 | ||
944 | switch (TREE_CODE (t)) | |
945 | { | |
946 | case CALL_EXPR: | |
947 | if (is_std_constant_evaluated_p (t)) | |
948 | return t; | |
949 | break; | |
950 | case EXPR_STMT: | |
951 | /* Don't warn in statement expressions. */ | |
952 | *walk_subtrees = false; | |
953 | return NULL_TREE; | |
954 | default: | |
955 | break; | |
956 | } | |
957 | ||
958 | return NULL_TREE; | |
959 | } | |
960 | ||
961 | /* In certain contexts, std::is_constant_evaluated() is always true (for | |
962 | instance, in a consteval function or in a constexpr if), or always false | |
963 | (e.g., in a non-constexpr non-consteval function) so give the user a clue. */ | |
964 | ||
965 | static void | |
966 | maybe_warn_for_constant_evaluated (tree cond, bool constexpr_if) | |
967 | { | |
968 | if (!warn_tautological_compare) | |
969 | return; | |
970 | ||
971 | /* Suppress warning for std::is_constant_evaluated if the conditional | |
972 | comes from a macro. */ | |
973 | if (from_macro_expansion_at (EXPR_LOCATION (cond))) | |
974 | return; | |
975 | ||
976 | cond = cp_walk_tree_without_duplicates (&cond, find_std_constant_evaluated_r, | |
977 | NULL); | |
978 | if (cond) | |
979 | { | |
980 | if (constexpr_if) | |
981 | warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, | |
982 | "%<std::is_constant_evaluated%> always evaluates to " | |
983 | "true in %<if constexpr%>"); | |
984 | else if (!maybe_constexpr_fn (current_function_decl)) | |
985 | warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, | |
986 | "%<std::is_constant_evaluated%> always evaluates to " | |
987 | "false in a non-%<constexpr%> function"); | |
988 | else if (DECL_IMMEDIATE_FUNCTION_P (current_function_decl)) | |
989 | warning_at (EXPR_LOCATION (cond), OPT_Wtautological_compare, | |
990 | "%<std::is_constant_evaluated%> always evaluates to " | |
991 | "true in a %<consteval%> function"); | |
992 | } | |
993 | } | |
994 | ||
ad321293 MM |
995 | /* Process the COND of an if-statement, which may be given by |
996 | IF_STMT. */ | |
997 | ||
99f9d4b1 | 998 | tree |
3a978d72 | 999 | finish_if_stmt_cond (tree cond, tree if_stmt) |
ad321293 | 1000 | { |
99f9d4b1 JM |
1001 | cond = maybe_convert_cond (cond); |
1002 | if (IF_STMT_CONSTEXPR_P (if_stmt) | |
9dc20710 | 1003 | && !type_dependent_expression_p (cond) |
899ac3b8 | 1004 | && require_constant_expression (cond) |
83afe9b5 | 1005 | && !instantiation_dependent_expression_p (cond) |
08ad2797 MP |
1006 | /* Wait until instantiation time, since only then COND has been |
1007 | converted to bool. */ | |
0e45c664 | 1008 | && TYPE_MAIN_VARIANT (TREE_TYPE (cond)) == boolean_type_node) |
66d052d5 | 1009 | { |
26dbe85a | 1010 | maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/true); |
66d052d5 JM |
1011 | cond = instantiate_non_dependent_expr (cond); |
1012 | cond = cxx_constant_value (cond, NULL_TREE); | |
1013 | } | |
26dbe85a MP |
1014 | else |
1015 | maybe_warn_for_constant_evaluated (cond, /*constexpr_if=*/false); | |
99f9d4b1 | 1016 | finish_cond (&IF_COND (if_stmt), cond); |
caf2523d | 1017 | add_stmt (if_stmt); |
325c3691 | 1018 | THEN_CLAUSE (if_stmt) = push_stmt_list (); |
99f9d4b1 | 1019 | return cond; |
ad321293 MM |
1020 | } |
1021 | ||
1022 | /* Finish the then-clause of an if-statement, which may be given by | |
1023 | IF_STMT. */ | |
1024 | ||
1025 | tree | |
3a978d72 | 1026 | finish_then_clause (tree if_stmt) |
ad321293 | 1027 | { |
325c3691 | 1028 | THEN_CLAUSE (if_stmt) = pop_stmt_list (THEN_CLAUSE (if_stmt)); |
35b1567d | 1029 | return if_stmt; |
ad321293 MM |
1030 | } |
1031 | ||
1032 | /* Begin the else-clause of an if-statement. */ | |
1033 | ||
325c3691 RH |
1034 | void |
1035 | begin_else_clause (tree if_stmt) | |
ad321293 | 1036 | { |
325c3691 | 1037 | ELSE_CLAUSE (if_stmt) = push_stmt_list (); |
ad321293 MM |
1038 | } |
1039 | ||
1040 | /* Finish the else-clause of an if-statement, which may be given by | |
1041 | IF_STMT. */ | |
1042 | ||
1043 | void | |
3a978d72 | 1044 | finish_else_clause (tree if_stmt) |
ad321293 | 1045 | { |
325c3691 | 1046 | ELSE_CLAUSE (if_stmt) = pop_stmt_list (ELSE_CLAUSE (if_stmt)); |
ad321293 MM |
1047 | } |
1048 | ||
86926937 MP |
1049 | /* Callback for cp_walk_tree to mark all {VAR,PARM}_DECLs in a tree as |
1050 | read. */ | |
1051 | ||
1052 | static tree | |
1053 | maybe_mark_exp_read_r (tree *tp, int *, void *) | |
1054 | { | |
1055 | tree t = *tp; | |
1056 | if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) | |
1057 | mark_exp_read (t); | |
1058 | return NULL_TREE; | |
1059 | } | |
1060 | ||
dfbb4f34 | 1061 | /* Finish an if-statement. */ |
ad321293 | 1062 | |
c8094d83 | 1063 | void |
325c3691 | 1064 | finish_if_stmt (tree if_stmt) |
ad321293 | 1065 | { |
545f261b NF |
1066 | tree scope = IF_SCOPE (if_stmt); |
1067 | IF_SCOPE (if_stmt) = NULL; | |
86926937 MP |
1068 | if (IF_STMT_CONSTEXPR_P (if_stmt)) |
1069 | { | |
1070 | /* Prevent various -Wunused warnings. We might not instantiate | |
1071 | either of these branches, so we would not mark the variables | |
1072 | used in that branch as read. */ | |
1073 | cp_walk_tree_without_duplicates (&THEN_CLAUSE (if_stmt), | |
1074 | maybe_mark_exp_read_r, NULL); | |
1075 | cp_walk_tree_without_duplicates (&ELSE_CLAUSE (if_stmt), | |
1076 | maybe_mark_exp_read_r, NULL); | |
1077 | } | |
325c3691 | 1078 | add_stmt (do_poplevel (scope)); |
35b1567d BC |
1079 | } |
1080 | ||
ad321293 MM |
1081 | /* Begin a while-statement. Returns a newly created WHILE_STMT if |
1082 | appropriate. */ | |
1083 | ||
1084 | tree | |
3a978d72 | 1085 | begin_while_stmt (void) |
ad321293 MM |
1086 | { |
1087 | tree r; | |
c2255bc4 | 1088 | r = build_stmt (input_location, WHILE_STMT, NULL_TREE, NULL_TREE); |
ae499cce | 1089 | add_stmt (r); |
325c3691 | 1090 | WHILE_BODY (r) = do_pushlevel (sk_block); |
caf2523d | 1091 | begin_cond (&WHILE_COND (r)); |
ad321293 MM |
1092 | return r; |
1093 | } | |
1094 | ||
27d26ee7 | 1095 | /* Process the COND of a while-statement, which may be given by |
ad321293 MM |
1096 | WHILE_STMT. */ |
1097 | ||
c8094d83 | 1098 | void |
170a8bd6 EB |
1099 | finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep, |
1100 | unsigned short unroll) | |
ad321293 | 1101 | { |
20f18c3c JM |
1102 | cond = maybe_convert_cond (cond); |
1103 | finish_cond (&WHILE_COND (while_stmt), cond); | |
1104 | begin_maybe_infinite_loop (cond); | |
c5028d80 | 1105 | if (ivdep && cond != error_mark_node) |
ac9effed | 1106 | WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR, |
c5028d80 TB |
1107 | TREE_TYPE (WHILE_COND (while_stmt)), |
1108 | WHILE_COND (while_stmt), | |
1109 | build_int_cst (integer_type_node, | |
ac9effed EB |
1110 | annot_expr_ivdep_kind), |
1111 | integer_zero_node); | |
170a8bd6 EB |
1112 | if (unroll && cond != error_mark_node) |
1113 | WHILE_COND (while_stmt) = build3 (ANNOTATE_EXPR, | |
1114 | TREE_TYPE (WHILE_COND (while_stmt)), | |
1115 | WHILE_COND (while_stmt), | |
1116 | build_int_cst (integer_type_node, | |
1117 | annot_expr_unroll_kind), | |
1118 | build_int_cst (integer_type_node, | |
1119 | unroll)); | |
caf2523d | 1120 | simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt)); |
ad321293 MM |
1121 | } |
1122 | ||
1123 | /* Finish a while-statement, which may be given by WHILE_STMT. */ | |
1124 | ||
c8094d83 | 1125 | void |
3a978d72 | 1126 | finish_while_stmt (tree while_stmt) |
ad321293 | 1127 | { |
20f18c3c | 1128 | end_maybe_infinite_loop (boolean_true_node); |
325c3691 | 1129 | WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt)); |
ad321293 MM |
1130 | } |
1131 | ||
1132 | /* Begin a do-statement. Returns a newly created DO_STMT if | |
1133 | appropriate. */ | |
1134 | ||
1135 | tree | |
3a978d72 | 1136 | begin_do_stmt (void) |
ad321293 | 1137 | { |
c2255bc4 | 1138 | tree r = build_stmt (input_location, DO_STMT, NULL_TREE, NULL_TREE); |
20f18c3c | 1139 | begin_maybe_infinite_loop (boolean_true_node); |
ae499cce | 1140 | add_stmt (r); |
325c3691 | 1141 | DO_BODY (r) = push_stmt_list (); |
35b1567d | 1142 | return r; |
ad321293 MM |
1143 | } |
1144 | ||
1145 | /* Finish the body of a do-statement, which may be given by DO_STMT. */ | |
1146 | ||
1147 | void | |
3a978d72 | 1148 | finish_do_body (tree do_stmt) |
ad321293 | 1149 | { |
62e00e94 DM |
1150 | tree body = DO_BODY (do_stmt) = pop_stmt_list (DO_BODY (do_stmt)); |
1151 | ||
1152 | if (TREE_CODE (body) == STATEMENT_LIST && STATEMENT_LIST_TAIL (body)) | |
1153 | body = STATEMENT_LIST_TAIL (body)->stmt; | |
1154 | ||
1155 | if (IS_EMPTY_STMT (body)) | |
1156 | warning (OPT_Wempty_body, | |
1157 | "suggest explicit braces around empty body in %<do%> statement"); | |
ad321293 MM |
1158 | } |
1159 | ||
1160 | /* Finish a do-statement, which may be given by DO_STMT, and whose | |
1161 | COND is as indicated. */ | |
1162 | ||
1163 | void | |
170a8bd6 | 1164 | finish_do_stmt (tree cond, tree do_stmt, bool ivdep, unsigned short unroll) |
ad321293 | 1165 | { |
ed5511d9 | 1166 | cond = maybe_convert_cond (cond); |
20f18c3c | 1167 | end_maybe_infinite_loop (cond); |
f0da1c0c MP |
1168 | /* Unlike other iteration statements, the condition may not contain |
1169 | a declaration, so we don't call finish_cond which checks for | |
1170 | unexpanded parameter packs. */ | |
1171 | if (check_for_bare_parameter_packs (cond)) | |
1172 | cond = error_mark_node; | |
c5028d80 | 1173 | if (ivdep && cond != error_mark_node) |
ac9effed EB |
1174 | cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, |
1175 | build_int_cst (integer_type_node, annot_expr_ivdep_kind), | |
1176 | integer_zero_node); | |
170a8bd6 EB |
1177 | if (unroll && cond != error_mark_node) |
1178 | cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, | |
1179 | build_int_cst (integer_type_node, annot_expr_unroll_kind), | |
1180 | build_int_cst (integer_type_node, unroll)); | |
35b1567d | 1181 | DO_COND (do_stmt) = cond; |
35b1567d | 1182 | } |
ed5511d9 | 1183 | |
ad321293 MM |
1184 | /* Finish a return-statement. The EXPRESSION returned, if any, is as |
1185 | indicated. */ | |
1186 | ||
3e4d04a1 | 1187 | tree |
3a978d72 | 1188 | finish_return_stmt (tree expr) |
ad321293 | 1189 | { |
3e4d04a1 | 1190 | tree r; |
0c9b182b | 1191 | bool no_warning; |
3e4d04a1 | 1192 | |
0c9b182b | 1193 | expr = check_return_expr (expr, &no_warning); |
1799e5d5 | 1194 | |
830ce0a2 MP |
1195 | if (error_operand_p (expr) |
1196 | || (flag_openmp && !check_omp_return ())) | |
3dbb8427 JM |
1197 | { |
1198 | /* Suppress -Wreturn-type for this function. */ | |
1199 | if (warn_return_type) | |
65870e75 | 1200 | suppress_warning (current_function_decl, OPT_Wreturn_type); |
3dbb8427 JM |
1201 | return error_mark_node; |
1202 | } | |
1203 | ||
35b1567d | 1204 | if (!processing_template_decl) |
efee38a9 | 1205 | { |
d4033c81 MLI |
1206 | if (warn_sequence_point) |
1207 | verify_sequence_points (expr); | |
43e1e8b5 | 1208 | |
44d10c10 | 1209 | if (DECL_DESTRUCTOR_P (current_function_decl) |
c8094d83 | 1210 | || (DECL_CONSTRUCTOR_P (current_function_decl) |
44d10c10 | 1211 | && targetm.cxx.cdtor_returns_this ())) |
efee38a9 MM |
1212 | { |
1213 | /* Similarly, all destructors must run destructors for | |
1214 | base-classes before returning. So, all returns in a | |
dfbb4f34 | 1215 | destructor get sent to the DTOR_LABEL; finish_function emits |
efee38a9 | 1216 | code to return a value there. */ |
44d10c10 | 1217 | return finish_goto_stmt (cdtor_label); |
efee38a9 MM |
1218 | } |
1219 | } | |
543a0daa | 1220 | |
c2255bc4 | 1221 | r = build_stmt (input_location, RETURN_EXPR, expr); |
65870e75 MS |
1222 | if (no_warning) |
1223 | suppress_warning (r, OPT_Wreturn_type); | |
0ad28dde | 1224 | r = maybe_cleanup_point_expr_void (r); |
543a0daa | 1225 | r = add_stmt (r); |
3e4d04a1 RH |
1226 | |
1227 | return r; | |
35b1567d | 1228 | } |
efee38a9 | 1229 | |
3f43ac31 RRC |
1230 | /* Begin the scope of a for-statement or a range-for-statement. |
1231 | Both the returned trees are to be used in a call to | |
1232 | begin_for_stmt or begin_range_for_stmt. */ | |
ad321293 MM |
1233 | |
1234 | tree | |
3f43ac31 RRC |
1235 | begin_for_scope (tree *init) |
1236 | { | |
ee336e84 | 1237 | tree scope = do_pushlevel (sk_for); |
3f43ac31 RRC |
1238 | |
1239 | if (processing_template_decl) | |
1240 | *init = push_stmt_list (); | |
1241 | else | |
1242 | *init = NULL_TREE; | |
1243 | ||
1244 | return scope; | |
1245 | } | |
1246 | ||
1247 | /* Begin a for-statement. Returns a new FOR_STMT. | |
1248 | SCOPE and INIT should be the return of begin_for_scope, | |
1249 | or both NULL_TREE */ | |
1250 | ||
1251 | tree | |
1252 | begin_for_stmt (tree scope, tree init) | |
ad321293 MM |
1253 | { |
1254 | tree r; | |
1255 | ||
c2255bc4 | 1256 | r = build_stmt (input_location, FOR_STMT, NULL_TREE, NULL_TREE, |
40e71fc7 | 1257 | NULL_TREE, NULL_TREE, NULL_TREE); |
325c3691 | 1258 | |
3f43ac31 RRC |
1259 | if (scope == NULL_TREE) |
1260 | { | |
ee336e84 NS |
1261 | gcc_assert (!init); |
1262 | scope = begin_for_scope (&init); | |
3f43ac31 | 1263 | } |
ee336e84 | 1264 | |
3f43ac31 | 1265 | FOR_INIT_STMT (r) = init; |
40e71fc7 | 1266 | FOR_SCOPE (r) = scope; |
894ca2c9 | 1267 | |
ad321293 MM |
1268 | return r; |
1269 | } | |
1270 | ||
17a9e380 | 1271 | /* Finish the init-statement of a for-statement, which may be |
ad321293 MM |
1272 | given by FOR_STMT. */ |
1273 | ||
1274 | void | |
17a9e380 | 1275 | finish_init_stmt (tree for_stmt) |
ad321293 | 1276 | { |
894ca2c9 RH |
1277 | if (processing_template_decl) |
1278 | FOR_INIT_STMT (for_stmt) = pop_stmt_list (FOR_INIT_STMT (for_stmt)); | |
325c3691 RH |
1279 | add_stmt (for_stmt); |
1280 | FOR_BODY (for_stmt) = do_pushlevel (sk_block); | |
caf2523d | 1281 | begin_cond (&FOR_COND (for_stmt)); |
ad321293 MM |
1282 | } |
1283 | ||
1284 | /* Finish the COND of a for-statement, which may be given by | |
1285 | FOR_STMT. */ | |
1286 | ||
1287 | void | |
170a8bd6 | 1288 | finish_for_cond (tree cond, tree for_stmt, bool ivdep, unsigned short unroll) |
ad321293 | 1289 | { |
20f18c3c JM |
1290 | cond = maybe_convert_cond (cond); |
1291 | finish_cond (&FOR_COND (for_stmt), cond); | |
1292 | begin_maybe_infinite_loop (cond); | |
c5028d80 | 1293 | if (ivdep && cond != error_mark_node) |
ac9effed | 1294 | FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR, |
c5028d80 TB |
1295 | TREE_TYPE (FOR_COND (for_stmt)), |
1296 | FOR_COND (for_stmt), | |
1297 | build_int_cst (integer_type_node, | |
ac9effed EB |
1298 | annot_expr_ivdep_kind), |
1299 | integer_zero_node); | |
170a8bd6 EB |
1300 | if (unroll && cond != error_mark_node) |
1301 | FOR_COND (for_stmt) = build3 (ANNOTATE_EXPR, | |
1302 | TREE_TYPE (FOR_COND (for_stmt)), | |
1303 | FOR_COND (for_stmt), | |
1304 | build_int_cst (integer_type_node, | |
1305 | annot_expr_unroll_kind), | |
1306 | build_int_cst (integer_type_node, | |
1307 | unroll)); | |
caf2523d | 1308 | simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt)); |
ad321293 MM |
1309 | } |
1310 | ||
1311 | /* Finish the increment-EXPRESSION in a for-statement, which may be | |
1312 | given by FOR_STMT. */ | |
1313 | ||
1314 | void | |
3a978d72 | 1315 | finish_for_expr (tree expr, tree for_stmt) |
ad321293 | 1316 | { |
543a0daa RH |
1317 | if (!expr) |
1318 | return; | |
6f69173e MM |
1319 | /* If EXPR is an overloaded function, issue an error; there is no |
1320 | context available to use to perform overload resolution. */ | |
543a0daa | 1321 | if (type_unknown_p (expr)) |
6f69173e MM |
1322 | { |
1323 | cxx_incomplete_type_error (expr, TREE_TYPE (expr)); | |
1324 | expr = error_mark_node; | |
1325 | } | |
bcd46a7c AP |
1326 | if (!processing_template_decl) |
1327 | { | |
1328 | if (warn_sequence_point) | |
0cbd7506 | 1329 | verify_sequence_points (expr); |
ebeb2c24 | 1330 | expr = convert_to_void (expr, ICV_THIRD_IN_FOR, |
5ade1ed2 | 1331 | tf_warning_or_error); |
bcd46a7c AP |
1332 | } |
1333 | else if (!type_dependent_expression_p (expr)) | |
ebeb2c24 | 1334 | convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR, |
5ade1ed2 | 1335 | tf_warning_or_error); |
0ad28dde | 1336 | expr = maybe_cleanup_point_expr_void (expr); |
7b3e2d46 | 1337 | if (check_for_bare_parameter_packs (expr)) |
4439d02f | 1338 | expr = error_mark_node; |
35b1567d | 1339 | FOR_EXPR (for_stmt) = expr; |
ad321293 MM |
1340 | } |
1341 | ||
1342 | /* Finish the body of a for-statement, which may be given by | |
1343 | FOR_STMT. The increment-EXPR for the loop must be | |
f9132eb7 RRC |
1344 | provided. |
1345 | It can also finish RANGE_FOR_STMT. */ | |
ad321293 MM |
1346 | |
1347 | void | |
3a978d72 | 1348 | finish_for_stmt (tree for_stmt) |
ad321293 | 1349 | { |
20f18c3c JM |
1350 | end_maybe_infinite_loop (boolean_true_node); |
1351 | ||
f9132eb7 | 1352 | if (TREE_CODE (for_stmt) == RANGE_FOR_STMT) |
a8733ebf | 1353 | RANGE_FOR_BODY (for_stmt) = do_poplevel (RANGE_FOR_BODY (for_stmt)); |
f9132eb7 | 1354 | else |
a8733ebf | 1355 | FOR_BODY (for_stmt) = do_poplevel (FOR_BODY (for_stmt)); |
325c3691 | 1356 | |
ad321293 | 1357 | /* Pop the scope for the body of the loop. */ |
ee336e84 NS |
1358 | tree *scope_ptr = (TREE_CODE (for_stmt) == RANGE_FOR_STMT |
1359 | ? &RANGE_FOR_SCOPE (for_stmt) | |
1360 | : &FOR_SCOPE (for_stmt)); | |
1361 | tree scope = *scope_ptr; | |
1362 | *scope_ptr = NULL; | |
213f5e8a JJ |
1363 | |
1364 | /* During parsing of the body, range for uses "__for_{range,begin,end} " | |
1365 | decl names to make those unaccessible by code in the body. | |
1366 | Change it to ones with underscore instead of space, so that it can | |
1367 | be inspected in the debugger. */ | |
1368 | tree range_for_decl[3] = { NULL_TREE, NULL_TREE, NULL_TREE }; | |
1369 | gcc_assert (CPTI_FOR_BEGIN__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 1 | |
1370 | && CPTI_FOR_END__IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 2 | |
1371 | && CPTI_FOR_RANGE_IDENTIFIER == CPTI_FOR_RANGE__IDENTIFIER + 3 | |
1372 | && CPTI_FOR_BEGIN_IDENTIFIER == CPTI_FOR_BEGIN__IDENTIFIER + 3 | |
1373 | && CPTI_FOR_END_IDENTIFIER == CPTI_FOR_END__IDENTIFIER + 3); | |
1374 | for (int i = 0; i < 3; i++) | |
1375 | { | |
1376 | tree id = cp_global_trees[CPTI_FOR_RANGE__IDENTIFIER + i]; | |
1377 | if (IDENTIFIER_BINDING (id) | |
1378 | && IDENTIFIER_BINDING (id)->scope == current_binding_level) | |
1379 | { | |
1380 | range_for_decl[i] = IDENTIFIER_BINDING (id)->value; | |
1381 | gcc_assert (VAR_P (range_for_decl[i]) | |
1382 | && DECL_ARTIFICIAL (range_for_decl[i])); | |
1383 | } | |
1384 | } | |
1385 | ||
ee336e84 | 1386 | add_stmt (do_poplevel (scope)); |
213f5e8a JJ |
1387 | |
1388 | for (int i = 0; i < 3; i++) | |
1389 | if (range_for_decl[i]) | |
1390 | DECL_NAME (range_for_decl[i]) | |
1391 | = cp_global_trees[CPTI_FOR_RANGE_IDENTIFIER + i]; | |
ad321293 MM |
1392 | } |
1393 | ||
f9132eb7 | 1394 | /* Begin a range-for-statement. Returns a new RANGE_FOR_STMT. |
3f43ac31 RRC |
1395 | SCOPE and INIT should be the return of begin_for_scope, |
1396 | or both NULL_TREE . | |
f9132eb7 RRC |
1397 | To finish it call finish_for_stmt(). */ |
1398 | ||
1399 | tree | |
3f43ac31 | 1400 | begin_range_for_stmt (tree scope, tree init) |
f9132eb7 | 1401 | { |
20f18c3c JM |
1402 | begin_maybe_infinite_loop (boolean_false_node); |
1403 | ||
8112667c MP |
1404 | tree r = build_stmt (input_location, RANGE_FOR_STMT, NULL_TREE, NULL_TREE, |
1405 | NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE); | |
a8733ebf | 1406 | |
3f43ac31 RRC |
1407 | if (scope == NULL_TREE) |
1408 | { | |
ee336e84 NS |
1409 | gcc_assert (!init); |
1410 | scope = begin_for_scope (&init); | |
3f43ac31 RRC |
1411 | } |
1412 | ||
8112667c MP |
1413 | /* Since C++20, RANGE_FOR_STMTs can use the init tree, so save it. */ |
1414 | RANGE_FOR_INIT_STMT (r) = init; | |
40e71fc7 | 1415 | RANGE_FOR_SCOPE (r) = scope; |
f9132eb7 RRC |
1416 | |
1417 | return r; | |
1418 | } | |
1419 | ||
1420 | /* Finish the head of a range-based for statement, which may | |
8112667c | 1421 | be given by RANGE_FOR_STMT. DECL must be the declaration |
f9132eb7 RRC |
1422 | and EXPR must be the loop expression. */ |
1423 | ||
1424 | void | |
1425 | finish_range_for_decl (tree range_for_stmt, tree decl, tree expr) | |
1426 | { | |
8112667c MP |
1427 | if (processing_template_decl) |
1428 | RANGE_FOR_INIT_STMT (range_for_stmt) | |
1429 | = pop_stmt_list (RANGE_FOR_INIT_STMT (range_for_stmt)); | |
f9132eb7 RRC |
1430 | RANGE_FOR_DECL (range_for_stmt) = decl; |
1431 | RANGE_FOR_EXPR (range_for_stmt) = expr; | |
1432 | add_stmt (range_for_stmt); | |
1433 | RANGE_FOR_BODY (range_for_stmt) = do_pushlevel (sk_block); | |
1434 | } | |
1435 | ||
ad321293 MM |
1436 | /* Finish a break-statement. */ |
1437 | ||
3e4d04a1 | 1438 | tree |
3a978d72 | 1439 | finish_break_stmt (void) |
ad321293 | 1440 | { |
04771457 JM |
1441 | /* In switch statements break is sometimes stylistically used after |
1442 | a return statement. This can lead to spurious warnings about | |
1443 | control reaching the end of a non-void function when it is | |
1444 | inlined. Note that we are calling block_may_fallthru with | |
1445 | language specific tree nodes; this works because | |
1446 | block_may_fallthru returns true when given something it does not | |
1447 | understand. */ | |
1448 | if (!block_may_fallthru (cur_stmt_list)) | |
632f2871 | 1449 | return void_node; |
1a2e9708 | 1450 | note_break_stmt (); |
c2255bc4 | 1451 | return add_stmt (build_stmt (input_location, BREAK_STMT)); |
35b1567d BC |
1452 | } |
1453 | ||
ad321293 MM |
1454 | /* Finish a continue-statement. */ |
1455 | ||
3e4d04a1 | 1456 | tree |
3a978d72 | 1457 | finish_continue_stmt (void) |
ad321293 | 1458 | { |
c2255bc4 | 1459 | return add_stmt (build_stmt (input_location, CONTINUE_STMT)); |
ad321293 MM |
1460 | } |
1461 | ||
35b1567d BC |
1462 | /* Begin a switch-statement. Returns a new SWITCH_STMT if |
1463 | appropriate. */ | |
1464 | ||
1465 | tree | |
3a978d72 | 1466 | begin_switch_stmt (void) |
35b1567d | 1467 | { |
325c3691 RH |
1468 | tree r, scope; |
1469 | ||
1eb2a14d | 1470 | scope = do_pushlevel (sk_cond); |
1f18dbc6 NF |
1471 | r = build_stmt (input_location, SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE, scope); |
1472 | ||
ebaae582 | 1473 | begin_cond (&SWITCH_STMT_COND (r)); |
325c3691 | 1474 | |
527f0080 | 1475 | return r; |
ad321293 MM |
1476 | } |
1477 | ||
527f0080 | 1478 | /* Finish the cond of a switch-statement. */ |
ad321293 | 1479 | |
527f0080 | 1480 | void |
3a978d72 | 1481 | finish_switch_cond (tree cond, tree switch_stmt) |
ad321293 | 1482 | { |
6f9fdf4d | 1483 | tree orig_type = NULL; |
14f68c39 | 1484 | |
35b1567d | 1485 | if (!processing_template_decl) |
373eb3b3 | 1486 | { |
35b1567d | 1487 | /* Convert the condition to an integer or enumeration type. */ |
c6ca0e3e | 1488 | tree orig_cond = cond; |
b746c5dc | 1489 | cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true); |
35b1567d | 1490 | if (cond == NULL_TREE) |
373eb3b3 | 1491 | { |
c6ca0e3e PC |
1492 | error_at (cp_expr_loc_or_input_loc (orig_cond), |
1493 | "switch quantity not an integer"); | |
35b1567d BC |
1494 | cond = error_mark_node; |
1495 | } | |
083e891e MP |
1496 | /* We want unlowered type here to handle enum bit-fields. */ |
1497 | orig_type = unlowered_expr_type (cond); | |
5964a3a6 MP |
1498 | if (TREE_CODE (orig_type) != ENUMERAL_TYPE) |
1499 | orig_type = TREE_TYPE (cond); | |
35b1567d BC |
1500 | if (cond != error_mark_node) |
1501 | { | |
0a72704b MM |
1502 | /* [stmt.switch] |
1503 | ||
1504 | Integral promotions are performed. */ | |
1505 | cond = perform_integral_promotions (cond); | |
543a0daa | 1506 | cond = maybe_cleanup_point_expr (cond); |
373eb3b3 | 1507 | } |
ad321293 | 1508 | } |
7b3e2d46 | 1509 | if (check_for_bare_parameter_packs (cond)) |
4439d02f | 1510 | cond = error_mark_node; |
d4033c81 MLI |
1511 | else if (!processing_template_decl && warn_sequence_point) |
1512 | verify_sequence_points (cond); | |
1513 | ||
ebaae582 SB |
1514 | finish_cond (&SWITCH_STMT_COND (switch_stmt), cond); |
1515 | SWITCH_STMT_TYPE (switch_stmt) = orig_type; | |
caf2523d | 1516 | add_stmt (switch_stmt); |
56cb9733 | 1517 | push_switch (switch_stmt); |
ebaae582 | 1518 | SWITCH_STMT_BODY (switch_stmt) = push_stmt_list (); |
ad321293 MM |
1519 | } |
1520 | ||
1521 | /* Finish the body of a switch-statement, which may be given by | |
1522 | SWITCH_STMT. The COND to switch on is indicated. */ | |
1523 | ||
1524 | void | |
3a978d72 | 1525 | finish_switch_stmt (tree switch_stmt) |
ad321293 | 1526 | { |
325c3691 RH |
1527 | tree scope; |
1528 | ||
ebaae582 SB |
1529 | SWITCH_STMT_BODY (switch_stmt) = |
1530 | pop_stmt_list (SWITCH_STMT_BODY (switch_stmt)); | |
c8094d83 | 1531 | pop_switch (); |
325c3691 | 1532 | |
1f18dbc6 NF |
1533 | scope = SWITCH_STMT_SCOPE (switch_stmt); |
1534 | SWITCH_STMT_SCOPE (switch_stmt) = NULL; | |
325c3691 | 1535 | add_stmt (do_poplevel (scope)); |
ad321293 MM |
1536 | } |
1537 | ||
ad321293 MM |
1538 | /* Begin a try-block. Returns a newly-created TRY_BLOCK if |
1539 | appropriate. */ | |
1540 | ||
1541 | tree | |
3a978d72 | 1542 | begin_try_block (void) |
ad321293 | 1543 | { |
c2255bc4 | 1544 | tree r = build_stmt (input_location, TRY_BLOCK, NULL_TREE, NULL_TREE); |
ae499cce | 1545 | add_stmt (r); |
325c3691 | 1546 | TRY_STMTS (r) = push_stmt_list (); |
35b1567d | 1547 | return r; |
ad321293 MM |
1548 | } |
1549 | ||
eaf6fb90 MM |
1550 | /* Likewise, for a function-try-block. The block returned in |
1551 | *COMPOUND_STMT is an artificial outer scope, containing the | |
1552 | function-try-block. */ | |
0dde4175 JM |
1553 | |
1554 | tree | |
eaf6fb90 | 1555 | begin_function_try_block (tree *compound_stmt) |
0dde4175 | 1556 | { |
eaf6fb90 MM |
1557 | tree r; |
1558 | /* This outer scope does not exist in the C++ standard, but we need | |
1559 | a place to put __FUNCTION__ and similar variables. */ | |
1560 | *compound_stmt = begin_compound_stmt (0); | |
1561 | r = begin_try_block (); | |
35b1567d | 1562 | FN_TRY_BLOCK_P (r) = 1; |
35b1567d | 1563 | return r; |
0dde4175 JM |
1564 | } |
1565 | ||
ad321293 MM |
1566 | /* Finish a try-block, which may be given by TRY_BLOCK. */ |
1567 | ||
1568 | void | |
3a978d72 | 1569 | finish_try_block (tree try_block) |
ad321293 | 1570 | { |
325c3691 RH |
1571 | TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block)); |
1572 | TRY_HANDLERS (try_block) = push_stmt_list (); | |
ad321293 MM |
1573 | } |
1574 | ||
efa8eda3 MM |
1575 | /* Finish the body of a cleanup try-block, which may be given by |
1576 | TRY_BLOCK. */ | |
1577 | ||
62409b39 | 1578 | void |
3a978d72 | 1579 | finish_cleanup_try_block (tree try_block) |
62409b39 | 1580 | { |
325c3691 | 1581 | TRY_STMTS (try_block) = pop_stmt_list (TRY_STMTS (try_block)); |
62409b39 MM |
1582 | } |
1583 | ||
f1dedc31 MM |
1584 | /* Finish an implicitly generated try-block, with a cleanup is given |
1585 | by CLEANUP. */ | |
1586 | ||
1587 | void | |
3a978d72 | 1588 | finish_cleanup (tree cleanup, tree try_block) |
f1dedc31 | 1589 | { |
35b1567d BC |
1590 | TRY_HANDLERS (try_block) = cleanup; |
1591 | CLEANUP_P (try_block) = 1; | |
f1dedc31 MM |
1592 | } |
1593 | ||
0dde4175 JM |
1594 | /* Likewise, for a function-try-block. */ |
1595 | ||
1596 | void | |
3a978d72 | 1597 | finish_function_try_block (tree try_block) |
0dde4175 | 1598 | { |
325c3691 RH |
1599 | finish_try_block (try_block); |
1600 | /* FIXME : something queer about CTOR_INITIALIZER somehow following | |
1601 | the try block, but moving it inside. */ | |
b35d4555 | 1602 | in_function_try_handler = 1; |
0dde4175 JM |
1603 | } |
1604 | ||
ad321293 MM |
1605 | /* Finish a handler-sequence for a try-block, which may be given by |
1606 | TRY_BLOCK. */ | |
1607 | ||
1608 | void | |
3a978d72 | 1609 | finish_handler_sequence (tree try_block) |
ad321293 | 1610 | { |
325c3691 | 1611 | TRY_HANDLERS (try_block) = pop_stmt_list (TRY_HANDLERS (try_block)); |
35b1567d | 1612 | check_handlers (TRY_HANDLERS (try_block)); |
ad321293 MM |
1613 | } |
1614 | ||
eaf6fb90 MM |
1615 | /* Finish the handler-seq for a function-try-block, given by |
1616 | TRY_BLOCK. COMPOUND_STMT is the outer block created by | |
1617 | begin_function_try_block. */ | |
0dde4175 JM |
1618 | |
1619 | void | |
eaf6fb90 | 1620 | finish_function_handler_sequence (tree try_block, tree compound_stmt) |
0dde4175 | 1621 | { |
b35d4555 | 1622 | in_function_try_handler = 0; |
325c3691 | 1623 | finish_handler_sequence (try_block); |
eaf6fb90 | 1624 | finish_compound_stmt (compound_stmt); |
35b1567d BC |
1625 | } |
1626 | ||
ad321293 MM |
1627 | /* Begin a handler. Returns a HANDLER if appropriate. */ |
1628 | ||
1629 | tree | |
3a978d72 | 1630 | begin_handler (void) |
ad321293 MM |
1631 | { |
1632 | tree r; | |
325c3691 | 1633 | |
c2255bc4 | 1634 | r = build_stmt (input_location, HANDLER, NULL_TREE, NULL_TREE); |
ae499cce | 1635 | add_stmt (r); |
325c3691 | 1636 | |
1a6025b4 JM |
1637 | /* Create a binding level for the eh_info and the exception object |
1638 | cleanup. */ | |
325c3691 RH |
1639 | HANDLER_BODY (r) = do_pushlevel (sk_catch); |
1640 | ||
ad321293 MM |
1641 | return r; |
1642 | } | |
1643 | ||
1644 | /* Finish the handler-parameters for a handler, which may be given by | |
b35d4555 MM |
1645 | HANDLER. DECL is the declaration for the catch parameter, or NULL |
1646 | if this is a `catch (...)' clause. */ | |
ad321293 | 1647 | |
1a6025b4 | 1648 | void |
3a978d72 | 1649 | finish_handler_parms (tree decl, tree handler) |
b35d4555 | 1650 | { |
1a6025b4 | 1651 | tree type = NULL_TREE; |
b35d4555 MM |
1652 | if (processing_template_decl) |
1653 | { | |
1654 | if (decl) | |
1655 | { | |
1656 | decl = pushdecl (decl); | |
1657 | decl = push_template_decl (decl); | |
325c3691 | 1658 | HANDLER_PARMS (handler) = decl; |
1a6025b4 | 1659 | type = TREE_TYPE (decl); |
b35d4555 MM |
1660 | } |
1661 | } | |
35b1567d | 1662 | else |
63dbcd13 VR |
1663 | { |
1664 | type = expand_start_catch_block (decl); | |
1665 | if (warn_catch_value | |
1666 | && type != NULL_TREE | |
1667 | && type != error_mark_node | |
9f613f06 | 1668 | && !TYPE_REF_P (TREE_TYPE (decl))) |
63dbcd13 VR |
1669 | { |
1670 | tree orig_type = TREE_TYPE (decl); | |
1671 | if (CLASS_TYPE_P (orig_type)) | |
1672 | { | |
1673 | if (TYPE_POLYMORPHIC_P (orig_type)) | |
d3769410 PC |
1674 | warning_at (DECL_SOURCE_LOCATION (decl), |
1675 | OPT_Wcatch_value_, | |
1676 | "catching polymorphic type %q#T by value", | |
1677 | orig_type); | |
63dbcd13 | 1678 | else if (warn_catch_value > 1) |
d3769410 PC |
1679 | warning_at (DECL_SOURCE_LOCATION (decl), |
1680 | OPT_Wcatch_value_, | |
1681 | "catching type %q#T by value", orig_type); | |
63dbcd13 VR |
1682 | } |
1683 | else if (warn_catch_value > 2) | |
d3769410 PC |
1684 | warning_at (DECL_SOURCE_LOCATION (decl), |
1685 | OPT_Wcatch_value_, | |
1686 | "catching non-reference type %q#T", orig_type); | |
63dbcd13 VR |
1687 | } |
1688 | } | |
1a6025b4 | 1689 | HANDLER_TYPE (handler) = type; |
35b1567d BC |
1690 | } |
1691 | ||
1692 | /* Finish a handler, which may be given by HANDLER. The BLOCKs are | |
1693 | the return value from the matching call to finish_handler_parms. */ | |
1694 | ||
1695 | void | |
3a978d72 | 1696 | finish_handler (tree handler) |
35b1567d BC |
1697 | { |
1698 | if (!processing_template_decl) | |
1a6025b4 | 1699 | expand_end_catch_block (); |
325c3691 | 1700 | HANDLER_BODY (handler) = do_poplevel (HANDLER_BODY (handler)); |
35b1567d BC |
1701 | } |
1702 | ||
5882f0f3 | 1703 | /* Begin a compound statement. FLAGS contains some bits that control the |
5995ebfb | 1704 | behavior and context. If BCS_NO_SCOPE is set, the compound statement |
5882f0f3 | 1705 | does not define a scope. If BCS_FN_BODY is set, this is the outermost |
c8094d83 | 1706 | block of a function. If BCS_TRY_BLOCK is set, this is the block |
5882f0f3 RH |
1707 | created on behalf of a TRY statement. Returns a token to be passed to |
1708 | finish_compound_stmt. */ | |
ad321293 MM |
1709 | |
1710 | tree | |
325c3691 | 1711 | begin_compound_stmt (unsigned int flags) |
ad321293 | 1712 | { |
325c3691 | 1713 | tree r; |
558475f0 | 1714 | |
325c3691 RH |
1715 | if (flags & BCS_NO_SCOPE) |
1716 | { | |
1717 | r = push_stmt_list (); | |
1718 | STATEMENT_LIST_NO_SCOPE (r) = 1; | |
1719 | ||
1720 | /* Normally, we try hard to keep the BLOCK for a statement-expression. | |
1721 | But, if it's a statement-expression with a scopeless block, there's | |
1722 | nothing to keep, and we don't want to accidentally keep a block | |
c8094d83 | 1723 | *inside* the scopeless block. */ |
325c3691 RH |
1724 | keep_next_level (false); |
1725 | } | |
f1dedc31 | 1726 | else |
b8fd7909 JM |
1727 | { |
1728 | scope_kind sk = sk_block; | |
1729 | if (flags & BCS_TRY_BLOCK) | |
1730 | sk = sk_try; | |
1731 | else if (flags & BCS_TRANSACTION) | |
1732 | sk = sk_transaction; | |
1733 | r = do_pushlevel (sk); | |
1734 | } | |
325c3691 | 1735 | |
5882f0f3 RH |
1736 | /* When processing a template, we need to remember where the braces were, |
1737 | so that we can set up identical scopes when instantiating the template | |
1738 | later. BIND_EXPR is a handy candidate for this. | |
1739 | Note that do_poplevel won't create a BIND_EXPR itself here (and thus | |
1740 | result in nested BIND_EXPRs), since we don't build BLOCK nodes when | |
1741 | processing templates. */ | |
1742 | if (processing_template_decl) | |
325c3691 | 1743 | { |
f293ce4b | 1744 | r = build3 (BIND_EXPR, NULL, NULL, r, NULL); |
5882f0f3 RH |
1745 | BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0; |
1746 | BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0; | |
325c3691 RH |
1747 | TREE_SIDE_EFFECTS (r) = 1; |
1748 | } | |
ad321293 MM |
1749 | |
1750 | return r; | |
1751 | } | |
1752 | ||
5882f0f3 | 1753 | /* Finish a compound-statement, which is given by STMT. */ |
ad321293 | 1754 | |
325c3691 RH |
1755 | void |
1756 | finish_compound_stmt (tree stmt) | |
ad321293 | 1757 | { |
5882f0f3 | 1758 | if (TREE_CODE (stmt) == BIND_EXPR) |
e02927a1 JM |
1759 | { |
1760 | tree body = do_poplevel (BIND_EXPR_BODY (stmt)); | |
1761 | /* If the STATEMENT_LIST is empty and this BIND_EXPR isn't special, | |
1762 | discard the BIND_EXPR so it can be merged with the containing | |
1763 | STATEMENT_LIST. */ | |
1764 | if (TREE_CODE (body) == STATEMENT_LIST | |
1765 | && STATEMENT_LIST_HEAD (body) == NULL | |
1766 | && !BIND_EXPR_BODY_BLOCK (stmt) | |
1767 | && !BIND_EXPR_TRY_BLOCK (stmt)) | |
1768 | stmt = body; | |
1769 | else | |
1770 | BIND_EXPR_BODY (stmt) = body; | |
1771 | } | |
325c3691 RH |
1772 | else if (STATEMENT_LIST_NO_SCOPE (stmt)) |
1773 | stmt = pop_stmt_list (stmt); | |
7a3397c7 | 1774 | else |
5f070bc7 ZL |
1775 | { |
1776 | /* Destroy any ObjC "super" receivers that may have been | |
1777 | created. */ | |
1778 | objc_clear_super_receiver (); | |
1779 | ||
1780 | stmt = do_poplevel (stmt); | |
1781 | } | |
ad321293 | 1782 | |
325c3691 RH |
1783 | /* ??? See c_end_compound_stmt wrt statement expressions. */ |
1784 | add_stmt (stmt); | |
ad321293 MM |
1785 | } |
1786 | ||
6de9cd9a | 1787 | /* Finish an asm-statement, whose components are a STRING, some |
1c384bf1 RH |
1788 | OUTPUT_OPERANDS, some INPUT_OPERANDS, some CLOBBERS and some |
1789 | LABELS. Also note whether the asm-statement should be | |
5b76e75f | 1790 | considered volatile, and whether it is asm inline. */ |
7dc5bd62 | 1791 | |
3e4d04a1 | 1792 | tree |
529bc410 MP |
1793 | finish_asm_stmt (location_t loc, int volatile_p, tree string, |
1794 | tree output_operands, tree input_operands, tree clobbers, | |
1795 | tree labels, bool inline_p) | |
35b1567d BC |
1796 | { |
1797 | tree r; | |
abfc8a36 | 1798 | tree t; |
5544530a PB |
1799 | int ninputs = list_length (input_operands); |
1800 | int noutputs = list_length (output_operands); | |
abfc8a36 | 1801 | |
abfc8a36 | 1802 | if (!processing_template_decl) |
40b18c0a | 1803 | { |
74f0c611 RH |
1804 | const char *constraint; |
1805 | const char **oconstraints; | |
1806 | bool allows_mem, allows_reg, is_inout; | |
1807 | tree operand; | |
40b18c0a | 1808 | int i; |
40b18c0a | 1809 | |
86b8fed1 | 1810 | oconstraints = XALLOCAVEC (const char *, noutputs); |
74f0c611 RH |
1811 | |
1812 | string = resolve_asm_operand_names (string, output_operands, | |
1c384bf1 | 1813 | input_operands, labels); |
74f0c611 RH |
1814 | |
1815 | for (i = 0, t = output_operands; t; t = TREE_CHAIN (t), ++i) | |
40b18c0a | 1816 | { |
74f0c611 RH |
1817 | operand = TREE_VALUE (t); |
1818 | ||
1819 | /* ??? Really, this should not be here. Users should be using a | |
1820 | proper lvalue, dammit. But there's a long history of using | |
1821 | casts in the output operands. In cases like longlong.h, this | |
1822 | becomes a primitive form of typechecking -- if the cast can be | |
1823 | removed, then the output operand had a type of the proper width; | |
1824 | otherwise we'll get an error. Gross, but ... */ | |
1825 | STRIP_NOPS (operand); | |
1826 | ||
03a904b5 JJ |
1827 | operand = mark_lvalue_use (operand); |
1828 | ||
5ade1ed2 | 1829 | if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error)) |
74f0c611 RH |
1830 | operand = error_mark_node; |
1831 | ||
3db45ab5 | 1832 | if (operand != error_mark_node |
5544530a PB |
1833 | && (TREE_READONLY (operand) |
1834 | || CP_TYPE_CONST_P (TREE_TYPE (operand)) | |
3db45ab5 MS |
1835 | /* Functions are not modifiable, even though they are |
1836 | lvalues. */ | |
7bdc7e06 | 1837 | || FUNC_OR_METHOD_TYPE_P (TREE_TYPE (operand)) |
3db45ab5 MS |
1838 | /* If it's an aggregate and any field is const, then it is |
1839 | effectively const. */ | |
1840 | || (CLASS_TYPE_P (TREE_TYPE (operand)) | |
1841 | && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand))))) | |
529bc410 | 1842 | cxx_readonly_error (loc, operand, lv_asm); |
5544530a | 1843 | |
57e20f74 JJ |
1844 | tree *op = &operand; |
1845 | while (TREE_CODE (*op) == COMPOUND_EXPR) | |
1846 | op = &TREE_OPERAND (*op, 1); | |
1847 | switch (TREE_CODE (*op)) | |
1848 | { | |
1849 | case PREINCREMENT_EXPR: | |
1850 | case PREDECREMENT_EXPR: | |
1851 | case MODIFY_EXPR: | |
1852 | *op = genericize_compound_lvalue (*op); | |
1853 | op = &TREE_OPERAND (*op, 1); | |
1854 | break; | |
1855 | default: | |
1856 | break; | |
1857 | } | |
1858 | ||
74f0c611 RH |
1859 | constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); |
1860 | oconstraints[i] = constraint; | |
1861 | ||
1862 | if (parse_output_constraint (&constraint, i, ninputs, noutputs, | |
1863 | &allows_mem, &allows_reg, &is_inout)) | |
1864 | { | |
1865 | /* If the operand is going to end up in memory, | |
1866 | mark it addressable. */ | |
57e20f74 | 1867 | if (!allows_reg && !cxx_mark_addressable (*op)) |
74f0c611 RH |
1868 | operand = error_mark_node; |
1869 | } | |
1870 | else | |
1871 | operand = error_mark_node; | |
1872 | ||
1873 | TREE_VALUE (t) = operand; | |
1874 | } | |
1875 | ||
1876 | for (i = 0, t = input_operands; t; ++i, t = TREE_CHAIN (t)) | |
1877 | { | |
1878 | constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t))); | |
0ab19cbc | 1879 | bool constraint_parsed |
43e1e8b5 | 1880 | = parse_input_constraint (&constraint, i, ninputs, noutputs, 0, |
0ab19cbc JJ |
1881 | oconstraints, &allows_mem, &allows_reg); |
1882 | /* If the operand is going to end up in memory, don't call | |
1883 | decay_conversion. */ | |
1884 | if (constraint_parsed && !allows_reg && allows_mem) | |
1885 | operand = mark_lvalue_use (TREE_VALUE (t)); | |
1886 | else | |
1887 | operand = decay_conversion (TREE_VALUE (t), tf_warning_or_error); | |
74f0c611 | 1888 | |
40b18c0a MM |
1889 | /* If the type of the operand hasn't been determined (e.g., |
1890 | because it involves an overloaded function), then issue | |
1891 | an error message. There's no context available to | |
1892 | resolve the overloading. */ | |
74f0c611 | 1893 | if (TREE_TYPE (operand) == unknown_type_node) |
40b18c0a | 1894 | { |
529bc410 MP |
1895 | error_at (loc, |
1896 | "type of %<asm%> operand %qE could not be determined", | |
1897 | TREE_VALUE (t)); | |
74f0c611 | 1898 | operand = error_mark_node; |
40b18c0a | 1899 | } |
40b18c0a | 1900 | |
0ab19cbc | 1901 | if (constraint_parsed) |
40b18c0a | 1902 | { |
74f0c611 RH |
1903 | /* If the operand is going to end up in memory, |
1904 | mark it addressable. */ | |
b4c33883 AP |
1905 | if (!allows_reg && allows_mem) |
1906 | { | |
1907 | /* Strip the nops as we allow this case. FIXME, this really | |
1908 | should be rejected or made deprecated. */ | |
1909 | STRIP_NOPS (operand); | |
57e20f74 JJ |
1910 | |
1911 | tree *op = &operand; | |
1912 | while (TREE_CODE (*op) == COMPOUND_EXPR) | |
1913 | op = &TREE_OPERAND (*op, 1); | |
1914 | switch (TREE_CODE (*op)) | |
1915 | { | |
1916 | case PREINCREMENT_EXPR: | |
1917 | case PREDECREMENT_EXPR: | |
1918 | case MODIFY_EXPR: | |
1919 | *op = genericize_compound_lvalue (*op); | |
1920 | op = &TREE_OPERAND (*op, 1); | |
1921 | break; | |
1922 | default: | |
1923 | break; | |
1924 | } | |
1925 | ||
1926 | if (!cxx_mark_addressable (*op)) | |
b4c33883 AP |
1927 | operand = error_mark_node; |
1928 | } | |
6760071f JJ |
1929 | else if (!allows_reg && !allows_mem) |
1930 | { | |
1931 | /* If constraint allows neither register nor memory, | |
1932 | try harder to get a constant. */ | |
1933 | tree constop = maybe_constant_value (operand); | |
1934 | if (TREE_CONSTANT (constop)) | |
1935 | operand = constop; | |
1936 | } | |
40b18c0a | 1937 | } |
74f0c611 RH |
1938 | else |
1939 | operand = error_mark_node; | |
40b18c0a | 1940 | |
74f0c611 | 1941 | TREE_VALUE (t) = operand; |
40b18c0a MM |
1942 | } |
1943 | } | |
abfc8a36 | 1944 | |
529bc410 | 1945 | r = build_stmt (loc, ASM_EXPR, string, |
0dfdeca6 | 1946 | output_operands, input_operands, |
1c384bf1 | 1947 | clobbers, labels); |
5544530a | 1948 | ASM_VOLATILE_P (r) = volatile_p || noutputs == 0; |
5b76e75f | 1949 | ASM_INLINE_P (r) = inline_p; |
0ad28dde | 1950 | r = maybe_cleanup_point_expr_void (r); |
3e4d04a1 | 1951 | return add_stmt (r); |
ad321293 | 1952 | } |
b4c4a9ec | 1953 | |
5bca4e80 | 1954 | /* Finish a label with the indicated NAME. Returns the new label. */ |
f01b0acb | 1955 | |
a723baf1 | 1956 | tree |
3a978d72 | 1957 | finish_label_stmt (tree name) |
f01b0acb | 1958 | { |
5b030314 | 1959 | tree decl = define_label (input_location, name); |
417fa55b | 1960 | |
5bca4e80 | 1961 | if (decl == error_mark_node) |
417fa55b LM |
1962 | return error_mark_node; |
1963 | ||
c2255bc4 | 1964 | add_stmt (build_stmt (input_location, LABEL_EXPR, decl)); |
5bca4e80 ILT |
1965 | |
1966 | return decl; | |
f01b0acb MM |
1967 | } |
1968 | ||
acef433b MM |
1969 | /* Finish a series of declarations for local labels. G++ allows users |
1970 | to declare "local" labels, i.e., labels with scope. This extension | |
1971 | is useful when writing code involving statement-expressions. */ | |
1972 | ||
1973 | void | |
3a978d72 | 1974 | finish_label_decl (tree name) |
acef433b | 1975 | { |
a6d76a95 PC |
1976 | if (!at_function_scope_p ()) |
1977 | { | |
a9c697b8 | 1978 | error ("%<__label__%> declarations are only allowed in function scopes"); |
a6d76a95 PC |
1979 | return; |
1980 | } | |
1981 | ||
1982 | add_decl_expr (declare_local_label (name)); | |
acef433b MM |
1983 | } |
1984 | ||
659e5a7a | 1985 | /* When DECL goes out of scope, make sure that CLEANUP is executed. */ |
f1dedc31 | 1986 | |
c8094d83 | 1987 | void |
3a978d72 | 1988 | finish_decl_cleanup (tree decl, tree cleanup) |
f1dedc31 | 1989 | { |
325c3691 | 1990 | push_cleanup (decl, cleanup, false); |
35b1567d BC |
1991 | } |
1992 | ||
659e5a7a | 1993 | /* If the current scope exits with an exception, run CLEANUP. */ |
24bef158 | 1994 | |
659e5a7a | 1995 | void |
3a978d72 | 1996 | finish_eh_cleanup (tree cleanup) |
24bef158 | 1997 | { |
325c3691 | 1998 | push_cleanup (NULL, cleanup, true); |
35b1567d BC |
1999 | } |
2000 | ||
2282d28d MM |
2001 | /* The MEM_INITS is a list of mem-initializers, in reverse of the |
2002 | order they were written by the user. Each node is as for | |
2003 | emit_mem_initializers. */ | |
bf3428d0 MM |
2004 | |
2005 | void | |
2282d28d | 2006 | finish_mem_initializers (tree mem_inits) |
bf3428d0 | 2007 | { |
2282d28d MM |
2008 | /* Reorder the MEM_INITS so that they are in the order they appeared |
2009 | in the source program. */ | |
2010 | mem_inits = nreverse (mem_inits); | |
bf3428d0 | 2011 | |
a0de9d20 | 2012 | if (processing_template_decl) |
5d80a306 DG |
2013 | { |
2014 | tree mem; | |
2015 | ||
2016 | for (mem = mem_inits; mem; mem = TREE_CHAIN (mem)) | |
2017 | { | |
2018 | /* If the TREE_PURPOSE is a TYPE_PACK_EXPANSION, skip the | |
2019 | check for bare parameter packs in the TREE_VALUE, because | |
2020 | any parameter packs in the TREE_VALUE have already been | |
2021 | bound as part of the TREE_PURPOSE. See | |
2022 | make_pack_expansion for more information. */ | |
4439d02f | 2023 | if (TREE_CODE (TREE_PURPOSE (mem)) != TYPE_PACK_EXPANSION |
7b3e2d46 | 2024 | && check_for_bare_parameter_packs (TREE_VALUE (mem))) |
4439d02f | 2025 | TREE_VALUE (mem) = error_mark_node; |
5d80a306 DG |
2026 | } |
2027 | ||
f330f599 PC |
2028 | add_stmt (build_min_nt_loc (UNKNOWN_LOCATION, |
2029 | CTOR_INITIALIZER, mem_inits)); | |
5d80a306 | 2030 | } |
cdd2559c | 2031 | else |
2282d28d | 2032 | emit_mem_initializers (mem_inits); |
558475f0 MM |
2033 | } |
2034 | ||
10c6dc8e JM |
2035 | /* Obfuscate EXPR if it looks like an id-expression or member access so |
2036 | that the call to finish_decltype in do_auto_deduction will give the | |
cb57504a | 2037 | right result. If EVEN_UNEVAL, do this even in unevaluated context. */ |
10c6dc8e JM |
2038 | |
2039 | tree | |
cb57504a | 2040 | force_paren_expr (tree expr, bool even_uneval) |
10c6dc8e JM |
2041 | { |
2042 | /* This is only needed for decltype(auto) in C++14. */ | |
e4276ba5 | 2043 | if (cxx_dialect < cxx14) |
10c6dc8e JM |
2044 | return expr; |
2045 | ||
0e4cf887 JM |
2046 | /* If we're in unevaluated context, we can't be deducing a |
2047 | return/initializer type, so we don't need to mess with this. */ | |
cb57504a | 2048 | if (cp_unevaluated_operand && !even_uneval) |
0e4cf887 JM |
2049 | return expr; |
2050 | ||
dfd7fdca DM |
2051 | if (!DECL_P (tree_strip_any_location_wrapper (expr)) |
2052 | && TREE_CODE (expr) != COMPONENT_REF | |
10c6dc8e JM |
2053 | && TREE_CODE (expr) != SCOPE_REF) |
2054 | return expr; | |
2055 | ||
ea55c915 JM |
2056 | location_t loc = cp_expr_location (expr); |
2057 | ||
cac177cf PP |
2058 | if (TREE_CODE (expr) == COMPONENT_REF |
2059 | || TREE_CODE (expr) == SCOPE_REF) | |
0e4cf887 | 2060 | REF_PARENTHESIZED_P (expr) = true; |
c945ee25 | 2061 | else if (processing_template_decl) |
ea55c915 | 2062 | expr = build1_loc (loc, PAREN_EXPR, TREE_TYPE (expr), expr); |
10c6dc8e JM |
2063 | else |
2064 | { | |
ea55c915 | 2065 | expr = build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr); |
e4511ca2 | 2066 | REF_PARENTHESIZED_P (expr) = true; |
10c6dc8e JM |
2067 | } |
2068 | ||
2069 | return expr; | |
2070 | } | |
2071 | ||
1137001c PP |
2072 | /* If T is an id-expression obfuscated by force_paren_expr, undo the |
2073 | obfuscation and return the underlying id-expression. Otherwise | |
2074 | return T. */ | |
2075 | ||
2076 | tree | |
2077 | maybe_undo_parenthesized_ref (tree t) | |
2078 | { | |
1d4f0f3f MP |
2079 | if (cxx_dialect < cxx14) |
2080 | return t; | |
2081 | ||
2082 | if (INDIRECT_REF_P (t) && REF_PARENTHESIZED_P (t)) | |
1137001c PP |
2083 | { |
2084 | t = TREE_OPERAND (t, 0); | |
2085 | while (TREE_CODE (t) == NON_LVALUE_EXPR | |
2086 | || TREE_CODE (t) == NOP_EXPR) | |
2087 | t = TREE_OPERAND (t, 0); | |
2088 | ||
2089 | gcc_assert (TREE_CODE (t) == ADDR_EXPR | |
2090 | || TREE_CODE (t) == STATIC_CAST_EXPR); | |
2091 | t = TREE_OPERAND (t, 0); | |
2092 | } | |
1d4f0f3f MP |
2093 | else if (TREE_CODE (t) == PAREN_EXPR) |
2094 | t = TREE_OPERAND (t, 0); | |
e4511ca2 JM |
2095 | else if (TREE_CODE (t) == VIEW_CONVERT_EXPR |
2096 | && REF_PARENTHESIZED_P (t)) | |
2097 | t = TREE_OPERAND (t, 0); | |
1137001c PP |
2098 | |
2099 | return t; | |
2100 | } | |
2101 | ||
b4c4a9ec MM |
2102 | /* Finish a parenthesized expression EXPR. */ |
2103 | ||
e87eed2a DM |
2104 | cp_expr |
2105 | finish_parenthesized_expr (cp_expr expr) | |
b4c4a9ec | 2106 | { |
6615c446 | 2107 | if (EXPR_P (expr)) |
78ef5b89 | 2108 | /* This inhibits warnings in c_common_truthvalue_conversion. */ |
65870e75 | 2109 | suppress_warning (expr, OPT_Wparentheses); |
b4c4a9ec | 2110 | |
d816a3ba JM |
2111 | if (TREE_CODE (expr) == OFFSET_REF |
2112 | || TREE_CODE (expr) == SCOPE_REF) | |
19420d00 NS |
2113 | /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be |
2114 | enclosed in parentheses. */ | |
2115 | PTRMEM_OK_P (expr) = 0; | |
c8094d83 | 2116 | |
dfd7fdca DM |
2117 | tree stripped_expr = tree_strip_any_location_wrapper (expr); |
2118 | if (TREE_CODE (stripped_expr) == STRING_CST) | |
2119 | PAREN_STRING_LITERAL_P (stripped_expr) = 1; | |
c8094d83 | 2120 | |
e87eed2a | 2121 | expr = cp_expr (force_paren_expr (expr), expr.get_location ()); |
10c6dc8e | 2122 | |
b4c4a9ec MM |
2123 | return expr; |
2124 | } | |
2125 | ||
a723baf1 MM |
2126 | /* Finish a reference to a non-static data member (DECL) that is not |
2127 | preceded by `.' or `->'. */ | |
2128 | ||
2129 | tree | |
a3f10e50 | 2130 | finish_non_static_data_member (tree decl, tree object, tree qualifying_scope) |
a723baf1 | 2131 | { |
50bc768d | 2132 | gcc_assert (TREE_CODE (decl) == FIELD_DECL); |
d9a6bd32 JJ |
2133 | bool try_omp_private = !object && omp_private_member_map; |
2134 | tree ret; | |
a723baf1 | 2135 | |
2defb926 | 2136 | if (!object) |
51fc2d02 | 2137 | { |
51fc2d02 JM |
2138 | tree scope = qualifying_scope; |
2139 | if (scope == NULL_TREE) | |
e6da0bf1 PC |
2140 | { |
2141 | scope = context_for_name_lookup (decl); | |
2142 | if (!TYPE_P (scope)) | |
2143 | { | |
2144 | /* Can happen during error recovery (c++/85014). */ | |
2145 | gcc_assert (seen_error ()); | |
2146 | return error_mark_node; | |
2147 | } | |
2148 | } | |
51fc2d02 JM |
2149 | object = maybe_dummy_object (scope, NULL); |
2150 | } | |
2151 | ||
0b360a07 | 2152 | object = maybe_resolve_dummy (object, true); |
1496e7d6 PC |
2153 | if (object == error_mark_node) |
2154 | return error_mark_node; | |
2155 | ||
e2254932 | 2156 | /* DR 613/850: Can use non-static data members without an associated |
2defb926 JM |
2157 | object in sizeof/decltype/alignof. */ |
2158 | if (is_dummy_object (object) && cp_unevaluated_operand == 0 | |
2159 | && (!processing_template_decl || !current_class_ref)) | |
a723baf1 | 2160 | { |
c8094d83 | 2161 | if (current_function_decl |
a723baf1 | 2162 | && DECL_STATIC_FUNCTION_P (current_function_decl)) |
6863c41a | 2163 | error ("invalid use of member %qD in static member function", decl); |
a723baf1 | 2164 | else |
6863c41a JM |
2165 | error ("invalid use of non-static data member %qD", decl); |
2166 | inform (DECL_SOURCE_LOCATION (decl), "declared here"); | |
a723baf1 MM |
2167 | |
2168 | return error_mark_node; | |
2169 | } | |
d5f4eddd | 2170 | |
51fc2d02 JM |
2171 | if (current_class_ptr) |
2172 | TREE_USED (current_class_ptr) = 1; | |
dd03c093 | 2173 | if (processing_template_decl) |
a723baf1 | 2174 | { |
a3f10e50 | 2175 | tree type = TREE_TYPE (decl); |
a723baf1 | 2176 | |
9f613f06 | 2177 | if (TYPE_REF_P (type)) |
2516ccfe | 2178 | /* Quals on the object don't matter. */; |
2993d08a JM |
2179 | else if (PACK_EXPANSION_P (type)) |
2180 | /* Don't bother trying to represent this. */ | |
2181 | type = NULL_TREE; | |
a3f10e50 NS |
2182 | else |
2183 | { | |
f4f206f4 | 2184 | /* Set the cv qualifiers. */ |
bab5167f | 2185 | int quals = cp_type_quals (TREE_TYPE (object)); |
c8094d83 | 2186 | |
a3f10e50 NS |
2187 | if (DECL_MUTABLE_P (decl)) |
2188 | quals &= ~TYPE_QUAL_CONST; | |
9e95d15f | 2189 | |
a3f10e50 NS |
2190 | quals |= cp_type_quals (TREE_TYPE (decl)); |
2191 | type = cp_build_qualified_type (type, quals); | |
2192 | } | |
c8094d83 | 2193 | |
dd03c093 JM |
2194 | if (qualifying_scope) |
2195 | /* Wrap this in a SCOPE_REF for now. */ | |
2196 | ret = build_qualified_name (type, qualifying_scope, decl, | |
2197 | /*template_p=*/false); | |
2198 | else | |
2199 | ret = (convert_from_reference | |
2200 | (build_min (COMPONENT_REF, type, object, decl, NULL_TREE))); | |
a3f10e50 | 2201 | } |
ab11c13f | 2202 | /* If PROCESSING_TEMPLATE_DECL is nonzero here, then |
dd03c093 | 2203 | QUALIFYING_SCOPE is also non-null. */ |
a3f10e50 NS |
2204 | else |
2205 | { | |
2206 | tree access_type = TREE_TYPE (object); | |
9f01ded6 | 2207 | |
02022f3a | 2208 | perform_or_defer_access_check (TYPE_BINFO (access_type), decl, |
0e69fdf0 | 2209 | decl, tf_warning_or_error); |
a723baf1 MM |
2210 | |
2211 | /* If the data member was named `C::M', convert `*this' to `C' | |
2212 | first. */ | |
2213 | if (qualifying_scope) | |
2214 | { | |
2215 | tree binfo = NULL_TREE; | |
2216 | object = build_scoped_ref (object, qualifying_scope, | |
2217 | &binfo); | |
2218 | } | |
2219 | ||
d9a6bd32 JJ |
2220 | ret = build_class_member_access_expr (object, decl, |
2221 | /*access_path=*/NULL_TREE, | |
2222 | /*preserve_reference=*/false, | |
2223 | tf_warning_or_error); | |
2224 | } | |
2225 | if (try_omp_private) | |
2226 | { | |
2227 | tree *v = omp_private_member_map->get (decl); | |
2228 | if (v) | |
2229 | ret = convert_from_reference (*v); | |
a723baf1 | 2230 | } |
d9a6bd32 | 2231 | return ret; |
a723baf1 MM |
2232 | } |
2233 | ||
ee76b931 MM |
2234 | /* DECL was the declaration to which a qualified-id resolved. Issue |
2235 | an error message if it is not accessible. If OBJECT_TYPE is | |
2236 | non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the | |
2237 | type of `*x', or `x', respectively. If the DECL was named as | |
4f6c1ca2 PP |
2238 | `A::B' then NESTED_NAME_SPECIFIER is `A'. Return value is like |
2239 | perform_access_checks above. */ | |
ee76b931 | 2240 | |
4f6c1ca2 | 2241 | bool |
c8094d83 MS |
2242 | check_accessibility_of_qualified_id (tree decl, |
2243 | tree object_type, | |
4f6c1ca2 PP |
2244 | tree nested_name_specifier, |
2245 | tsubst_flags_t complain) | |
ee76b931 | 2246 | { |
77880ae4 | 2247 | /* If we're not checking, return immediately. */ |
95b4aca6 | 2248 | if (deferred_access_no_check) |
4f6c1ca2 | 2249 | return true; |
c8094d83 | 2250 | |
ee76b931 | 2251 | /* Determine the SCOPE of DECL. */ |
92bed036 | 2252 | tree scope = context_for_name_lookup (decl); |
ee76b931 | 2253 | /* If the SCOPE is not a type, then DECL is not a member. */ |
92bed036 PP |
2254 | if (!TYPE_P (scope) |
2255 | /* If SCOPE is dependent then we can't perform this access check now, | |
2256 | and since we'll perform this access check again after substitution | |
2257 | there's no need to explicitly defer it. */ | |
2258 | || dependent_type_p (scope)) | |
4f6c1ca2 | 2259 | return true; |
92bed036 PP |
2260 | |
2261 | tree qualifying_type = NULL_TREE; | |
ee76b931 | 2262 | /* Compute the scope through which DECL is being accessed. */ |
c8094d83 | 2263 | if (object_type |
ee76b931 MM |
2264 | /* OBJECT_TYPE might not be a class type; consider: |
2265 | ||
2266 | class A { typedef int I; }; | |
2267 | I *p; | |
2268 | p->A::I::~I(); | |
2269 | ||
0cbd7506 | 2270 | In this case, we will have "A::I" as the DECL, but "I" as the |
ee76b931 MM |
2271 | OBJECT_TYPE. */ |
2272 | && CLASS_TYPE_P (object_type) | |
2273 | && DERIVED_FROM_P (scope, object_type)) | |
2274 | /* If we are processing a `->' or `.' expression, use the type of the | |
2275 | left-hand side. */ | |
2276 | qualifying_type = object_type; | |
2277 | else if (nested_name_specifier) | |
2278 | { | |
2279 | /* If the reference is to a non-static member of the | |
2280 | current class, treat it as if it were referenced through | |
2281 | `this'. */ | |
2282 | if (DECL_NONSTATIC_MEMBER_P (decl) | |
98a1fb70 PP |
2283 | && current_class_ptr) |
2284 | if (tree current = current_nonlambda_class_type ()) | |
2285 | { | |
2286 | if (dependent_type_p (current)) | |
2287 | /* In general we can't know whether this access goes through | |
2288 | `this' until instantiation time. Punt now, or else we might | |
2289 | create a deferred access check that's not relative to `this' | |
2290 | when it ought to be. We'll check this access again after | |
2291 | substitution, e.g. from tsubst_qualified_id. */ | |
2292 | return true; | |
2293 | ||
2294 | if (DERIVED_FROM_P (scope, current)) | |
2295 | qualifying_type = current; | |
2296 | } | |
ee76b931 MM |
2297 | /* Otherwise, use the type indicated by the |
2298 | nested-name-specifier. */ | |
98a1fb70 | 2299 | if (!qualifying_type) |
ee76b931 MM |
2300 | qualifying_type = nested_name_specifier; |
2301 | } | |
2302 | else | |
2303 | /* Otherwise, the name must be from the current class or one of | |
2304 | its bases. */ | |
2305 | qualifying_type = currently_open_derived_class (scope); | |
2306 | ||
43e1e8b5 | 2307 | if (qualifying_type |
fc429748 MM |
2308 | /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM |
2309 | or similar in a default argument value. */ | |
92bed036 | 2310 | && CLASS_TYPE_P (qualifying_type)) |
4f6c1ca2 PP |
2311 | return perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl, |
2312 | decl, complain); | |
2313 | ||
2314 | return true; | |
ee76b931 MM |
2315 | } |
2316 | ||
2317 | /* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the | |
2318 | class named to the left of the "::" operator. DONE is true if this | |
2319 | expression is a complete postfix-expression; it is false if this | |
2320 | expression is followed by '->', '[', '(', etc. ADDRESS_P is true | |
02ed62dd MM |
2321 | iff this expression is the operand of '&'. TEMPLATE_P is true iff |
2322 | the qualified-id was of the form "A::template B". TEMPLATE_ARG_P | |
2323 | is true iff this qualified name appears as a template argument. */ | |
ee76b931 MM |
2324 | |
2325 | tree | |
3db45ab5 MS |
2326 | finish_qualified_id_expr (tree qualifying_class, |
2327 | tree expr, | |
02ed62dd | 2328 | bool done, |
3db45ab5 | 2329 | bool address_p, |
02ed62dd | 2330 | bool template_p, |
a378996b PC |
2331 | bool template_arg_p, |
2332 | tsubst_flags_t complain) | |
ee76b931 | 2333 | { |
d4f0f205 MM |
2334 | gcc_assert (TYPE_P (qualifying_class)); |
2335 | ||
5e08432e MM |
2336 | if (error_operand_p (expr)) |
2337 | return error_mark_node; | |
2338 | ||
2e649151 PC |
2339 | if ((DECL_P (expr) || BASELINK_P (expr)) |
2340 | && !mark_used (expr, complain)) | |
2341 | return error_mark_node; | |
d4f0f205 | 2342 | |
02ed62dd | 2343 | if (template_p) |
5ea106d8 JM |
2344 | { |
2345 | if (TREE_CODE (expr) == UNBOUND_CLASS_TEMPLATE) | |
be197ade PC |
2346 | { |
2347 | /* cp_parser_lookup_name thought we were looking for a type, | |
2348 | but we're actually looking for a declaration. */ | |
2349 | qualifying_class = TYPE_CONTEXT (expr); | |
2350 | expr = TYPE_IDENTIFIER (expr); | |
2351 | } | |
5ea106d8 JM |
2352 | else |
2353 | check_template_keyword (expr); | |
2354 | } | |
02ed62dd | 2355 | |
ee76b931 MM |
2356 | /* If EXPR occurs as the operand of '&', use special handling that |
2357 | permits a pointer-to-member. */ | |
2358 | if (address_p && done) | |
2359 | { | |
2360 | if (TREE_CODE (expr) == SCOPE_REF) | |
2361 | expr = TREE_OPERAND (expr, 1); | |
c8094d83 | 2362 | expr = build_offset_ref (qualifying_class, expr, |
a378996b | 2363 | /*address_p=*/true, complain); |
ee76b931 MM |
2364 | return expr; |
2365 | } | |
2366 | ||
d348f172 | 2367 | /* No need to check access within an enum. */ |
1a142d6e JM |
2368 | if (TREE_CODE (qualifying_class) == ENUMERAL_TYPE |
2369 | && TREE_CODE (expr) != IDENTIFIER_NODE) | |
d348f172 JM |
2370 | return expr; |
2371 | ||
02ed62dd MM |
2372 | /* Within the scope of a class, turn references to non-static |
2373 | members into expression of the form "this->...". */ | |
2374 | if (template_arg_p) | |
2375 | /* But, within a template argument, we do not want make the | |
2376 | transformation, as there is no "this" pointer. */ | |
2377 | ; | |
2378 | else if (TREE_CODE (expr) == FIELD_DECL) | |
43854f72 SB |
2379 | { |
2380 | push_deferring_access_checks (dk_no_check); | |
2defb926 | 2381 | expr = finish_non_static_data_member (expr, NULL_TREE, |
43854f72 SB |
2382 | qualifying_class); |
2383 | pop_deferring_access_checks (); | |
2384 | } | |
88b811bd | 2385 | else if (BASELINK_P (expr)) |
ee76b931 | 2386 | { |
ee76b931 | 2387 | /* See if any of the functions are non-static members. */ |
7e361ae6 | 2388 | /* If so, the expression may be relative to 'this'. */ |
a8cef3cb | 2389 | if (!shared_member_p (expr) |
0ef811d7 JM |
2390 | && current_class_ptr |
2391 | && DERIVED_FROM_P (qualifying_class, | |
2392 | current_nonlambda_class_type ())) | |
c8094d83 | 2393 | expr = (build_class_member_access_expr |
0ef811d7 | 2394 | (maybe_dummy_object (qualifying_class, NULL), |
ee76b931 MM |
2395 | expr, |
2396 | BASELINK_ACCESS_BINFO (expr), | |
5ade1ed2 | 2397 | /*preserve_reference=*/false, |
a378996b | 2398 | complain)); |
ee76b931 | 2399 | else if (done) |
a5ac359a MM |
2400 | /* The expression is a qualified name whose address is not |
2401 | being taken. */ | |
a378996b PC |
2402 | expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false, |
2403 | complain); | |
ee76b931 | 2404 | } |
b2725ea5 JJ |
2405 | else if (!template_p |
2406 | && TREE_CODE (expr) == TEMPLATE_DECL | |
2407 | && !DECL_FUNCTION_TEMPLATE_P (expr)) | |
2408 | { | |
2409 | if (complain & tf_error) | |
2410 | error ("%qE missing template arguments", expr); | |
2411 | return error_mark_node; | |
2412 | } | |
e467c9d2 JM |
2413 | else |
2414 | { | |
e467c9d2 JM |
2415 | /* In a template, return a SCOPE_REF for most qualified-ids |
2416 | so that we can check access at instantiation time. But if | |
2417 | we're looking at a member of the current instantiation, we | |
2418 | know we have access and building up the SCOPE_REF confuses | |
2419 | non-type template argument handling. */ | |
2420 | if (processing_template_decl | |
88b811bd | 2421 | && (!currently_open_class (qualifying_class) |
066c4268 JM |
2422 | || TREE_CODE (expr) == IDENTIFIER_NODE |
2423 | || TREE_CODE (expr) == TEMPLATE_ID_EXPR | |
88b811bd | 2424 | || TREE_CODE (expr) == BIT_NOT_EXPR)) |
e467c9d2 JM |
2425 | expr = build_qualified_name (TREE_TYPE (expr), |
2426 | qualifying_class, expr, | |
2427 | template_p); | |
5c3703c5 JJ |
2428 | else if (tree wrap = maybe_get_tls_wrapper_call (expr)) |
2429 | expr = wrap; | |
1e8671f7 JM |
2430 | |
2431 | expr = convert_from_reference (expr); | |
e467c9d2 | 2432 | } |
ee76b931 MM |
2433 | |
2434 | return expr; | |
2435 | } | |
2436 | ||
b69b1501 MM |
2437 | /* Begin a statement-expression. The value returned must be passed to |
2438 | finish_stmt_expr. */ | |
b4c4a9ec | 2439 | |
c8094d83 | 2440 | tree |
3a978d72 | 2441 | begin_stmt_expr (void) |
b4c4a9ec | 2442 | { |
325c3691 | 2443 | return push_stmt_list (); |
35b1567d BC |
2444 | } |
2445 | ||
a5bcc582 | 2446 | /* Process the final expression of a statement expression. EXPR can be |
85a56c9d MM |
2447 | NULL, if the final expression is empty. Return a STATEMENT_LIST |
2448 | containing all the statements in the statement-expression, or | |
2449 | ERROR_MARK_NODE if there was an error. */ | |
a5bcc582 NS |
2450 | |
2451 | tree | |
325c3691 | 2452 | finish_stmt_expr_expr (tree expr, tree stmt_expr) |
a5bcc582 | 2453 | { |
72e4661a | 2454 | if (error_operand_p (expr)) |
76b9a2a1 AP |
2455 | { |
2456 | /* The type of the statement-expression is the type of the last | |
2457 | expression. */ | |
2458 | TREE_TYPE (stmt_expr) = error_mark_node; | |
2459 | return error_mark_node; | |
2460 | } | |
c8094d83 | 2461 | |
85a56c9d | 2462 | /* If the last statement does not have "void" type, then the value |
3db45ab5 | 2463 | of the last statement is the value of the entire expression. */ |
a5bcc582 NS |
2464 | if (expr) |
2465 | { | |
c6c7698d JM |
2466 | tree type = TREE_TYPE (expr); |
2467 | ||
1ea71a82 AO |
2468 | if (type && type_unknown_p (type)) |
2469 | { | |
2470 | error ("a statement expression is an insufficient context" | |
2471 | " for overload resolution"); | |
2472 | TREE_TYPE (stmt_expr) = error_mark_node; | |
2473 | return error_mark_node; | |
2474 | } | |
2475 | else if (processing_template_decl) | |
c6c7698d | 2476 | { |
c2255bc4 | 2477 | expr = build_stmt (input_location, EXPR_STMT, expr); |
c6c7698d JM |
2478 | expr = add_stmt (expr); |
2479 | /* Mark the last statement so that we can recognize it as such at | |
2480 | template-instantiation time. */ | |
2481 | EXPR_STMT_STMT_EXPR_RESULT (expr) = 1; | |
2482 | } | |
2483 | else if (VOID_TYPE_P (type)) | |
a5bcc582 | 2484 | { |
c6c7698d JM |
2485 | /* Just treat this like an ordinary statement. */ |
2486 | expr = finish_expr_stmt (expr); | |
2487 | } | |
2488 | else | |
2489 | { | |
2490 | /* It actually has a value we need to deal with. First, force it | |
2491 | to be an rvalue so that we won't need to build up a copy | |
2492 | constructor call later when we try to assign it to something. */ | |
574cfaa4 | 2493 | expr = force_rvalue (expr, tf_warning_or_error); |
85a56c9d MM |
2494 | if (error_operand_p (expr)) |
2495 | return error_mark_node; | |
c6c7698d JM |
2496 | |
2497 | /* Update for array-to-pointer decay. */ | |
2692eb7d | 2498 | type = TREE_TYPE (expr); |
c6c7698d JM |
2499 | |
2500 | /* Wrap it in a CLEANUP_POINT_EXPR and add it to the list like a | |
2501 | normal statement, but don't convert to void or actually add | |
2502 | the EXPR_STMT. */ | |
2503 | if (TREE_CODE (expr) != CLEANUP_POINT_EXPR) | |
2504 | expr = maybe_cleanup_point_expr (expr); | |
2505 | add_stmt (expr); | |
85a56c9d | 2506 | } |
c6c7698d | 2507 | |
85a56c9d MM |
2508 | /* The type of the statement-expression is the type of the last |
2509 | expression. */ | |
2510 | TREE_TYPE (stmt_expr) = type; | |
a5bcc582 | 2511 | } |
c8094d83 | 2512 | |
85a56c9d | 2513 | return stmt_expr; |
a5bcc582 NS |
2514 | } |
2515 | ||
303b7406 NS |
2516 | /* Finish a statement-expression. EXPR should be the value returned |
2517 | by the previous begin_stmt_expr. Returns an expression | |
2518 | representing the statement-expression. */ | |
b4c4a9ec | 2519 | |
c8094d83 | 2520 | tree |
325c3691 | 2521 | finish_stmt_expr (tree stmt_expr, bool has_no_scope) |
b4c4a9ec | 2522 | { |
85a56c9d MM |
2523 | tree type; |
2524 | tree result; | |
325c3691 | 2525 | |
85a56c9d | 2526 | if (error_operand_p (stmt_expr)) |
d7b5fa31 JJ |
2527 | { |
2528 | pop_stmt_list (stmt_expr); | |
2529 | return error_mark_node; | |
2530 | } | |
325c3691 | 2531 | |
85a56c9d | 2532 | gcc_assert (TREE_CODE (stmt_expr) == STATEMENT_LIST); |
325c3691 | 2533 | |
85a56c9d MM |
2534 | type = TREE_TYPE (stmt_expr); |
2535 | result = pop_stmt_list (stmt_expr); | |
c6c7698d | 2536 | TREE_TYPE (result) = type; |
6f80451c | 2537 | |
a5bcc582 | 2538 | if (processing_template_decl) |
325c3691 RH |
2539 | { |
2540 | result = build_min (STMT_EXPR, type, result); | |
2541 | TREE_SIDE_EFFECTS (result) = 1; | |
2542 | STMT_EXPR_NO_SCOPE (result) = has_no_scope; | |
2543 | } | |
c6c7698d | 2544 | else if (CLASS_TYPE_P (type)) |
a5bcc582 | 2545 | { |
c6c7698d JM |
2546 | /* Wrap the statement-expression in a TARGET_EXPR so that the |
2547 | temporary object created by the final expression is destroyed at | |
2548 | the end of the full-expression containing the | |
2549 | statement-expression. */ | |
574cfaa4 | 2550 | result = force_target_expr (type, result, tf_warning_or_error); |
a5bcc582 | 2551 | } |
325c3691 | 2552 | |
b4c4a9ec MM |
2553 | return result; |
2554 | } | |
2555 | ||
c2acde1e JM |
2556 | /* Returns the expression which provides the value of STMT_EXPR. */ |
2557 | ||
2558 | tree | |
2559 | stmt_expr_value_expr (tree stmt_expr) | |
2560 | { | |
2561 | tree t = STMT_EXPR_STMT (stmt_expr); | |
2562 | ||
2563 | if (TREE_CODE (t) == BIND_EXPR) | |
2564 | t = BIND_EXPR_BODY (t); | |
2565 | ||
9de0e916 | 2566 | if (TREE_CODE (t) == STATEMENT_LIST && STATEMENT_LIST_TAIL (t)) |
c2acde1e JM |
2567 | t = STATEMENT_LIST_TAIL (t)->stmt; |
2568 | ||
2569 | if (TREE_CODE (t) == EXPR_STMT) | |
2570 | t = EXPR_STMT_EXPR (t); | |
2571 | ||
2572 | return t; | |
2573 | } | |
2574 | ||
9af66ed1 DS |
2575 | /* Return TRUE iff EXPR_STMT is an empty list of |
2576 | expression statements. */ | |
2577 | ||
2578 | bool | |
2579 | empty_expr_stmt_p (tree expr_stmt) | |
2580 | { | |
2581 | tree body = NULL_TREE; | |
2582 | ||
632f2871 | 2583 | if (expr_stmt == void_node) |
489df541 DS |
2584 | return true; |
2585 | ||
9af66ed1 DS |
2586 | if (expr_stmt) |
2587 | { | |
2588 | if (TREE_CODE (expr_stmt) == EXPR_STMT) | |
2589 | body = EXPR_STMT_EXPR (expr_stmt); | |
2590 | else if (TREE_CODE (expr_stmt) == STATEMENT_LIST) | |
2591 | body = expr_stmt; | |
2592 | } | |
2593 | ||
489df541 DS |
2594 | if (body) |
2595 | { | |
2596 | if (TREE_CODE (body) == STATEMENT_LIST) | |
2597 | return tsi_end_p (tsi_start (body)); | |
2598 | else | |
2599 | return empty_expr_stmt_p (body); | |
2600 | } | |
9af66ed1 DS |
2601 | return false; |
2602 | } | |
2603 | ||
dfd7fdca | 2604 | /* Perform Koenig lookup. FN_EXPR is the postfix-expression representing |
fa531100 | 2605 | the function (or functions) to call; ARGS are the arguments to the |
cdc23b1b | 2606 | call. Returns the functions to be considered by overload resolution. */ |
b3445994 | 2607 | |
e87eed2a | 2608 | cp_expr |
dfd7fdca | 2609 | perform_koenig_lookup (cp_expr fn_expr, vec<tree, va_gc> *args, |
94df301f | 2610 | tsubst_flags_t complain) |
b3445994 MM |
2611 | { |
2612 | tree identifier = NULL_TREE; | |
2613 | tree functions = NULL_TREE; | |
d095e03c | 2614 | tree tmpl_args = NULL_TREE; |
4e6a9725 | 2615 | bool template_id = false; |
dfd7fdca DM |
2616 | location_t loc = fn_expr.get_location (); |
2617 | tree fn = fn_expr.get_value (); | |
2618 | ||
2619 | STRIP_ANY_LOCATION_WRAPPER (fn); | |
d095e03c JM |
2620 | |
2621 | if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) | |
2622 | { | |
4e6a9725 JM |
2623 | /* Use a separate flag to handle null args. */ |
2624 | template_id = true; | |
d095e03c JM |
2625 | tmpl_args = TREE_OPERAND (fn, 1); |
2626 | fn = TREE_OPERAND (fn, 0); | |
2627 | } | |
b3445994 MM |
2628 | |
2629 | /* Find the name of the overloaded function. */ | |
9dc6f476 | 2630 | if (identifier_p (fn)) |
b3445994 | 2631 | identifier = fn; |
848bf88d | 2632 | else |
b3445994 MM |
2633 | { |
2634 | functions = fn; | |
848bf88d | 2635 | identifier = OVL_NAME (functions); |
b3445994 MM |
2636 | } |
2637 | ||
2638 | /* A call to a namespace-scope function using an unqualified name. | |
2639 | ||
2640 | Do Koenig lookup -- unless any of the arguments are | |
2641 | type-dependent. */ | |
d095e03c JM |
2642 | if (!any_type_dependent_arguments_p (args) |
2643 | && !any_dependent_template_arguments_p (tmpl_args)) | |
b3445994 | 2644 | { |
cdc23b1b | 2645 | fn = lookup_arg_dependent (identifier, functions, args); |
b3445994 | 2646 | if (!fn) |
94df301f JM |
2647 | { |
2648 | /* The unqualified name could not be resolved. */ | |
37a80bf9 | 2649 | if (complain & tf_error) |
b2f6675b | 2650 | fn = unqualified_fn_lookup_error (cp_expr (identifier, loc)); |
94df301f JM |
2651 | else |
2652 | fn = identifier; | |
2653 | } | |
b3445994 | 2654 | } |
b3445994 | 2655 | |
e7555e42 | 2656 | if (fn && template_id && fn != error_mark_node) |
4e6a9725 | 2657 | fn = build2 (TEMPLATE_ID_EXPR, unknown_type_node, fn, tmpl_args); |
d095e03c | 2658 | |
dfd7fdca | 2659 | return cp_expr (fn, loc); |
b3445994 MM |
2660 | } |
2661 | ||
c166b898 ILT |
2662 | /* Generate an expression for `FN (ARGS)'. This may change the |
2663 | contents of ARGS. | |
4ba126e4 MM |
2664 | |
2665 | If DISALLOW_VIRTUAL is true, the call to FN will be not generated | |
2666 | as a virtual call, even if FN is virtual. (This flag is set when | |
2667 | encountering an expression where the function name is explicitly | |
2668 | qualified. For example a call to `X::f' never generates a virtual | |
2669 | call.) | |
2670 | ||
2671 | Returns code for the call. */ | |
b4c4a9ec | 2672 | |
c8094d83 | 2673 | tree |
9771b263 | 2674 | finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual, |
c166b898 | 2675 | bool koenig_p, tsubst_flags_t complain) |
b4c4a9ec | 2676 | { |
d17811fd MM |
2677 | tree result; |
2678 | tree orig_fn; | |
4dbdb49b | 2679 | vec<tree, va_gc> *orig_args = *args; |
d17811fd | 2680 | |
c166b898 | 2681 | if (fn == error_mark_node) |
4ba126e4 MM |
2682 | return error_mark_node; |
2683 | ||
4860b874 | 2684 | gcc_assert (!TYPE_P (fn)); |
a759e627 | 2685 | |
1137001c PP |
2686 | /* If FN may be a FUNCTION_DECL obfuscated by force_paren_expr, undo |
2687 | it so that we can tell this is a call to a known function. */ | |
2688 | fn = maybe_undo_parenthesized_ref (fn); | |
2689 | ||
dfd7fdca DM |
2690 | STRIP_ANY_LOCATION_WRAPPER (fn); |
2691 | ||
d17811fd | 2692 | orig_fn = fn; |
d17811fd MM |
2693 | |
2694 | if (processing_template_decl) | |
2695 | { | |
3c1f5a3a JM |
2696 | /* If FN is a local extern declaration or set thereof, look them up |
2697 | again at instantiation time. */ | |
2698 | if (is_overloaded_fn (fn)) | |
2699 | { | |
2700 | tree ifn = get_first_fn (fn); | |
2701 | if (TREE_CODE (ifn) == FUNCTION_DECL | |
f4086696 | 2702 | && DECL_LOCAL_DECL_P (ifn)) |
3c1f5a3a JM |
2703 | orig_fn = DECL_NAME (ifn); |
2704 | } | |
2705 | ||
1770aeed DS |
2706 | /* If the call expression is dependent, build a CALL_EXPR node |
2707 | with no type; type_dependent_expression_p recognizes | |
2708 | expressions with no type as being dependent. */ | |
d17811fd | 2709 | if (type_dependent_expression_p (fn) |
23cb7266 | 2710 | || any_type_dependent_arguments_p (*args)) |
6d80c4b9 | 2711 | { |
3c1f5a3a | 2712 | result = build_min_nt_call_vec (orig_fn, *args); |
f9d0ca40 | 2713 | SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn)); |
5094a795 | 2714 | KOENIG_LOOKUP_P (result) = koenig_p; |
1bf07cc3 | 2715 | if (is_overloaded_fn (fn)) |
335a120f | 2716 | fn = get_fns (fn); |
1bf07cc3 | 2717 | |
be461b8f JJ |
2718 | if (cfun) |
2719 | { | |
1bf07cc3 NS |
2720 | bool abnormal = true; |
2721 | for (lkp_iterator iter (fn); abnormal && iter; ++iter) | |
be461b8f | 2722 | { |
4ff685a8 | 2723 | tree fndecl = STRIP_TEMPLATE (*iter); |
be461b8f JJ |
2724 | if (TREE_CODE (fndecl) != FUNCTION_DECL |
2725 | || !TREE_THIS_VOLATILE (fndecl)) | |
1bf07cc3 | 2726 | abnormal = false; |
be461b8f | 2727 | } |
1bf07cc3 NS |
2728 | /* FIXME: Stop warning about falling off end of non-void |
2729 | function. But this is wrong. Even if we only see | |
2730 | no-return fns at this point, we could select a | |
2731 | future-defined return fn during instantiation. Or | |
2732 | vice-versa. */ | |
2733 | if (abnormal) | |
be461b8f JJ |
2734 | current_function_returns_abnormally = 1; |
2735 | } | |
6d80c4b9 MM |
2736 | return result; |
2737 | } | |
c166b898 | 2738 | orig_args = make_tree_vector_copy (*args); |
d17811fd MM |
2739 | if (!BASELINK_P (fn) |
2740 | && TREE_CODE (fn) != PSEUDO_DTOR_EXPR | |
2741 | && TREE_TYPE (fn) != unknown_type_node) | |
2742 | fn = build_non_dependent_expr (fn); | |
c166b898 | 2743 | make_args_non_dependent (*args); |
d17811fd MM |
2744 | } |
2745 | ||
deb9642d JM |
2746 | if (TREE_CODE (fn) == COMPONENT_REF) |
2747 | { | |
2748 | tree member = TREE_OPERAND (fn, 1); | |
2749 | if (BASELINK_P (member)) | |
2750 | { | |
2751 | tree object = TREE_OPERAND (fn, 0); | |
2752 | return build_new_method_call (object, member, | |
2753 | args, NULL_TREE, | |
2754 | (disallow_virtual | |
2755 | ? LOOKUP_NORMAL | LOOKUP_NONVIRTUAL | |
2756 | : LOOKUP_NORMAL), | |
2757 | /*fn_p=*/NULL, | |
2758 | complain); | |
2759 | } | |
2760 | } | |
2761 | ||
53677b17 PC |
2762 | /* Per 13.3.1.1, '(&f)(...)' is the same as '(f)(...)'. */ |
2763 | if (TREE_CODE (fn) == ADDR_EXPR | |
2764 | && TREE_CODE (TREE_OPERAND (fn, 0)) == OVERLOAD) | |
2765 | fn = TREE_OPERAND (fn, 0); | |
2766 | ||
eff3a276 MM |
2767 | if (is_overloaded_fn (fn)) |
2768 | fn = baselink_for_fns (fn); | |
a723baf1 | 2769 | |
d17811fd | 2770 | result = NULL_TREE; |
4ba126e4 | 2771 | if (BASELINK_P (fn)) |
03d82991 | 2772 | { |
4ba126e4 MM |
2773 | tree object; |
2774 | ||
2775 | /* A call to a member function. From [over.call.func]: | |
2776 | ||
2777 | If the keyword this is in scope and refers to the class of | |
2778 | that member function, or a derived class thereof, then the | |
2779 | function call is transformed into a qualified function call | |
2780 | using (*this) as the postfix-expression to the left of the | |
2781 | . operator.... [Otherwise] a contrived object of type T | |
c8094d83 | 2782 | becomes the implied object argument. |
4ba126e4 | 2783 | |
38f1276b | 2784 | In this situation: |
4ba126e4 MM |
2785 | |
2786 | struct A { void f(); }; | |
2787 | struct B : public A {}; | |
2788 | struct C : public A { void g() { B::f(); }}; | |
2789 | ||
38f1276b JM |
2790 | "the class of that member function" refers to `A'. But 11.2 |
2791 | [class.access.base] says that we need to convert 'this' to B* as | |
2792 | part of the access, so we pass 'B' to maybe_dummy_object. */ | |
b4c4a9ec | 2793 | |
200e869c PP |
2794 | if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn))) |
2795 | { | |
2796 | /* A constructor call always uses a dummy object. (This constructor | |
2797 | call which has the form A::A () is actually invalid and we are | |
2798 | going to reject it later in build_new_method_call.) */ | |
2799 | object = build_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn))); | |
2800 | } | |
2801 | else | |
2802 | object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), | |
2803 | NULL); | |
b4c4a9ec | 2804 | |
d17811fd | 2805 | result = build_new_method_call (object, fn, args, NULL_TREE, |
c8094d83 | 2806 | (disallow_virtual |
c2aa8dc9 JM |
2807 | ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL |
2808 | : LOOKUP_NORMAL), | |
5ade1ed2 DG |
2809 | /*fn_p=*/NULL, |
2810 | complain); | |
4ba126e4 | 2811 | } |
cb57504a JM |
2812 | else if (concept_check_p (fn)) |
2813 | { | |
2814 | /* FN is actually a template-id referring to a concept definition. */ | |
2815 | tree id = unpack_concept_check (fn); | |
2816 | tree tmpl = TREE_OPERAND (id, 0); | |
2817 | tree args = TREE_OPERAND (id, 1); | |
2818 | ||
2819 | if (!function_concept_p (tmpl)) | |
2820 | { | |
2821 | error_at (EXPR_LOC_OR_LOC (fn, input_location), | |
2822 | "cannot call a concept as a function"); | |
2823 | return error_mark_node; | |
2824 | } | |
2825 | ||
2826 | /* Ensure the result is wrapped as a call expression. */ | |
2827 | result = build_concept_check (tmpl, args, tf_warning_or_error); | |
cb57504a | 2828 | } |
4ba126e4 | 2829 | else if (is_overloaded_fn (fn)) |
16c35a1f RH |
2830 | { |
2831 | /* If the function is an overloaded builtin, resolve it. */ | |
2832 | if (TREE_CODE (fn) == FUNCTION_DECL | |
58646b77 PB |
2833 | && (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL |
2834 | || DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD)) | |
c2255bc4 | 2835 | result = resolve_overloaded_builtin (input_location, fn, *args); |
16c35a1f RH |
2836 | |
2837 | if (!result) | |
0d23cf7a JJ |
2838 | { |
2839 | if (warn_sizeof_pointer_memaccess | |
32ad49af | 2840 | && (complain & tf_warning) |
9771b263 | 2841 | && !vec_safe_is_empty (*args) |
0d23cf7a JJ |
2842 | && !processing_template_decl) |
2843 | { | |
3a785c97 JJ |
2844 | location_t sizeof_arg_loc[3]; |
2845 | tree sizeof_arg[3]; | |
2846 | unsigned int i; | |
2847 | for (i = 0; i < 3; i++) | |
2848 | { | |
2849 | tree t; | |
2850 | ||
2851 | sizeof_arg_loc[i] = UNKNOWN_LOCATION; | |
2852 | sizeof_arg[i] = NULL_TREE; | |
9771b263 | 2853 | if (i >= (*args)->length ()) |
3a785c97 | 2854 | continue; |
9771b263 | 2855 | t = (**args)[i]; |
3a785c97 JJ |
2856 | if (TREE_CODE (t) != SIZEOF_EXPR) |
2857 | continue; | |
2858 | if (SIZEOF_EXPR_TYPE_P (t)) | |
2859 | sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0)); | |
2860 | else | |
2861 | sizeof_arg[i] = TREE_OPERAND (t, 0); | |
2862 | sizeof_arg_loc[i] = EXPR_LOCATION (t); | |
2863 | } | |
0d23cf7a | 2864 | sizeof_pointer_memaccess_warning |
3a785c97 | 2865 | (sizeof_arg_loc, fn, *args, |
0d23cf7a JJ |
2866 | sizeof_arg, same_type_ignoring_top_level_qualifiers_p); |
2867 | } | |
2868 | ||
4dbdb49b JM |
2869 | if ((complain & tf_warning) |
2870 | && TREE_CODE (fn) == FUNCTION_DECL | |
3d78e008 | 2871 | && fndecl_built_in_p (fn, BUILT_IN_MEMSET) |
4dbdb49b JM |
2872 | && vec_safe_length (*args) == 3 |
2873 | && !any_type_dependent_arguments_p (*args)) | |
2874 | { | |
2875 | tree arg0 = (*orig_args)[0]; | |
2876 | tree arg1 = (*orig_args)[1]; | |
2877 | tree arg2 = (*orig_args)[2]; | |
2878 | int literal_mask = ((literal_integer_zerop (arg1) << 1) | |
2879 | | (literal_integer_zerop (arg2) << 2)); | |
4dbdb49b JM |
2880 | warn_for_memset (input_location, arg0, arg2, literal_mask); |
2881 | } | |
2882 | ||
0d23cf7a | 2883 | /* A call to a namespace-scope function. */ |
268de039 | 2884 | result = build_new_function_call (fn, args, complain); |
0d23cf7a | 2885 | } |
16c35a1f | 2886 | } |
a723baf1 MM |
2887 | else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) |
2888 | { | |
9771b263 | 2889 | if (!vec_safe_is_empty (*args)) |
a723baf1 | 2890 | error ("arguments to destructor are not allowed"); |
e443d821 JM |
2891 | /* C++20/DR: If the postfix-expression names a pseudo-destructor (in |
2892 | which case the postfix-expression is a possibly-parenthesized class | |
2893 | member access), the function call destroys the object of scalar type | |
2894 | denoted by the object expression of the class member access. */ | |
2895 | tree ob = TREE_OPERAND (fn, 0); | |
2896 | if (obvalue_p (ob)) | |
61680cfa | 2897 | result = build_trivial_dtor_call (ob, true); |
e443d821 JM |
2898 | else |
2899 | /* No location to clobber. */ | |
2900 | result = convert_to_void (ob, ICV_STATEMENT, complain); | |
a723baf1 | 2901 | } |
4ba126e4 | 2902 | else if (CLASS_TYPE_P (TREE_TYPE (fn))) |
d17811fd MM |
2903 | /* If the "function" is really an object of class type, it might |
2904 | have an overloaded `operator ()'. */ | |
c166b898 | 2905 | result = build_op_call (fn, args, complain); |
16c35a1f | 2906 | |
d17811fd MM |
2907 | if (!result) |
2908 | /* A call where the function is unknown. */ | |
c166b898 | 2909 | result = cp_build_function_call_vec (fn, args, complain); |
4ba126e4 | 2910 | |
bb4586d3 | 2911 | if (processing_template_decl && result != error_mark_node) |
6d80c4b9 | 2912 | { |
591cb3cf | 2913 | if (INDIRECT_REF_P (result)) |
bb4586d3 | 2914 | result = TREE_OPERAND (result, 0); |
c166b898 | 2915 | result = build_call_vec (TREE_TYPE (result), orig_fn, orig_args); |
6e04dcd5 | 2916 | SET_EXPR_LOCATION (result, input_location); |
5094a795 | 2917 | KOENIG_LOOKUP_P (result) = koenig_p; |
c166b898 | 2918 | release_tree_vector (orig_args); |
bb4586d3 | 2919 | result = convert_from_reference (result); |
6d80c4b9 | 2920 | } |
c166b898 | 2921 | |
d17811fd | 2922 | return result; |
b4c4a9ec MM |
2923 | } |
2924 | ||
2925 | /* Finish a call to a postfix increment or decrement or EXPR. (Which | |
2926 | is indicated by CODE, which should be POSTINCREMENT_EXPR or | |
2927 | POSTDECREMENT_EXPR.) */ | |
2928 | ||
e87eed2a DM |
2929 | cp_expr |
2930 | finish_increment_expr (cp_expr expr, enum tree_code code) | |
2931 | { | |
2932 | /* input_location holds the location of the trailing operator token. | |
2933 | Build a location of the form: | |
2934 | expr++ | |
2935 | ~~~~^~ | |
2936 | with the caret at the operator token, ranging from the start | |
2937 | of EXPR to the end of the operator token. */ | |
2938 | location_t combined_loc = make_location (input_location, | |
2939 | expr.get_start (), | |
2940 | get_finish (input_location)); | |
2941 | cp_expr result = build_x_unary_op (combined_loc, code, expr, | |
2942 | tf_warning_or_error); | |
2943 | /* TODO: build_x_unary_op doesn't honor the location, so set it here. */ | |
2944 | result.set_location (combined_loc); | |
2945 | return result; | |
b4c4a9ec MM |
2946 | } |
2947 | ||
2948 | /* Finish a use of `this'. Returns an expression for `this'. */ | |
2949 | ||
c8094d83 | 2950 | tree |
3a978d72 | 2951 | finish_this_expr (void) |
b4c4a9ec | 2952 | { |
2bf492a1 | 2953 | tree result = NULL_TREE; |
b4c4a9ec | 2954 | |
c6be04ad JM |
2955 | if (current_class_ptr) |
2956 | { | |
2957 | tree type = TREE_TYPE (current_class_ref); | |
2958 | ||
2959 | /* In a lambda expression, 'this' refers to the captured 'this'. */ | |
2960 | if (LAMBDA_TYPE_P (type)) | |
0b360a07 | 2961 | result = lambda_expr_this_capture (CLASSTYPE_LAMBDA_EXPR (type), true); |
c6be04ad JM |
2962 | else |
2963 | result = current_class_ptr; | |
c6be04ad | 2964 | } |
b4c4a9ec | 2965 | |
2bf492a1 JM |
2966 | if (result) |
2967 | /* The keyword 'this' is a prvalue expression. */ | |
2968 | return rvalue (result); | |
374b2837 | 2969 | |
2bf492a1 JM |
2970 | tree fn = current_nonlambda_function (); |
2971 | if (fn && DECL_STATIC_FUNCTION_P (fn)) | |
2972 | error ("%<this%> is unavailable for static member functions"); | |
2973 | else if (fn) | |
2974 | error ("invalid use of %<this%> in non-member function"); | |
2975 | else | |
2976 | error ("invalid use of %<this%> at top level"); | |
2977 | return error_mark_node; | |
b4c4a9ec MM |
2978 | } |
2979 | ||
a723baf1 MM |
2980 | /* Finish a pseudo-destructor expression. If SCOPE is NULL, the |
2981 | expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is | |
2982 | the TYPE for the type given. If SCOPE is non-NULL, the expression | |
2983 | was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */ | |
b4c4a9ec | 2984 | |
c8094d83 | 2985 | tree |
2dc6ed87 PC |
2986 | finish_pseudo_destructor_expr (tree object, tree scope, tree destructor, |
2987 | location_t loc) | |
b4c4a9ec | 2988 | { |
09b1ccd6 | 2989 | if (object == error_mark_node || destructor == error_mark_node) |
a723baf1 | 2990 | return error_mark_node; |
40242ccf | 2991 | |
50bc768d | 2992 | gcc_assert (TYPE_P (destructor)); |
b4c4a9ec | 2993 | |
a723baf1 MM |
2994 | if (!processing_template_decl) |
2995 | { | |
2996 | if (scope == error_mark_node) | |
2997 | { | |
2dc6ed87 | 2998 | error_at (loc, "invalid qualifying scope in pseudo-destructor name"); |
a723baf1 MM |
2999 | return error_mark_node; |
3000 | } | |
3df70c62 JM |
3001 | if (is_auto (destructor)) |
3002 | destructor = TREE_TYPE (object); | |
5cf10afb AP |
3003 | if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor)) |
3004 | { | |
2dc6ed87 PC |
3005 | error_at (loc, |
3006 | "qualified type %qT does not match destructor name ~%qT", | |
3007 | scope, destructor); | |
5cf10afb AP |
3008 | return error_mark_node; |
3009 | } | |
3010 | ||
c8094d83 | 3011 | |
26bcf8fc MM |
3012 | /* [expr.pseudo] says both: |
3013 | ||
0cbd7506 | 3014 | The type designated by the pseudo-destructor-name shall be |
26bcf8fc MM |
3015 | the same as the object type. |
3016 | ||
0cbd7506 | 3017 | and: |
26bcf8fc | 3018 | |
0cbd7506 | 3019 | The cv-unqualified versions of the object type and of the |
26bcf8fc MM |
3020 | type designated by the pseudo-destructor-name shall be the |
3021 | same type. | |
3022 | ||
0cbd7506 MS |
3023 | We implement the more generous second sentence, since that is |
3024 | what most other compilers do. */ | |
c8094d83 | 3025 | if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object), |
26bcf8fc | 3026 | destructor)) |
a723baf1 | 3027 | { |
2dc6ed87 | 3028 | error_at (loc, "%qE is not of type %qT", object, destructor); |
a723baf1 MM |
3029 | return error_mark_node; |
3030 | } | |
3031 | } | |
b4c4a9ec | 3032 | |
e443d821 JM |
3033 | tree type = (type_dependent_expression_p (object) |
3034 | ? NULL_TREE : void_type_node); | |
3035 | ||
3036 | return build3_loc (loc, PSEUDO_DTOR_EXPR, type, object, | |
2dc6ed87 | 3037 | scope, destructor); |
b4c4a9ec MM |
3038 | } |
3039 | ||
ce4a0391 MM |
3040 | /* Finish an expression of the form CODE EXPR. */ |
3041 | ||
e87eed2a DM |
3042 | cp_expr |
3043 | finish_unary_op_expr (location_t op_loc, enum tree_code code, cp_expr expr, | |
e59baf05 | 3044 | tsubst_flags_t complain) |
ce4a0391 | 3045 | { |
e87eed2a DM |
3046 | /* Build a location of the form: |
3047 | ++expr | |
3048 | ^~~~~~ | |
3049 | with the caret at the operator token, ranging from the start | |
3050 | of the operator token to the end of EXPR. */ | |
3051 | location_t combined_loc = make_location (op_loc, | |
3052 | op_loc, expr.get_finish ()); | |
3053 | cp_expr result = build_x_unary_op (combined_loc, code, expr, complain); | |
3054 | /* TODO: build_x_unary_op doesn't always honor the location. */ | |
3055 | result.set_location (combined_loc); | |
3056 | ||
0798984a PC |
3057 | if (result == error_mark_node) |
3058 | return result; | |
cda0a029 JM |
3059 | |
3060 | if (!(complain & tf_warning)) | |
3061 | return result; | |
3062 | ||
0798984a PC |
3063 | tree result_ovl = result; |
3064 | tree expr_ovl = expr; | |
cda0a029 JM |
3065 | |
3066 | if (!processing_template_decl) | |
3067 | expr_ovl = cp_fully_fold (expr_ovl); | |
3068 | ||
3069 | if (!CONSTANT_CLASS_P (expr_ovl) | |
3070 | || TREE_OVERFLOW_P (expr_ovl)) | |
3071 | return result; | |
3072 | ||
3073 | if (!processing_template_decl) | |
3074 | result_ovl = cp_fully_fold (result_ovl); | |
3075 | ||
3076 | if (CONSTANT_CLASS_P (result_ovl) && TREE_OVERFLOW_P (result_ovl)) | |
e87eed2a | 3077 | overflow_warning (combined_loc, result_ovl); |
59c0753d | 3078 | |
ce4a0391 MM |
3079 | return result; |
3080 | } | |
3081 | ||
60648580 JM |
3082 | /* Finish a compound-literal expression or C++11 functional cast with aggregate |
3083 | initializer. TYPE is the type to which the CONSTRUCTOR in COMPOUND_LITERAL | |
3084 | is being cast. */ | |
a723baf1 MM |
3085 | |
3086 | tree | |
834aa426 | 3087 | finish_compound_literal (tree type, tree compound_literal, |
60648580 JM |
3088 | tsubst_flags_t complain, |
3089 | fcl_t fcl_context) | |
a723baf1 | 3090 | { |
326a4d4e JJ |
3091 | if (type == error_mark_node) |
3092 | return error_mark_node; | |
3093 | ||
9f613f06 | 3094 | if (TYPE_REF_P (type)) |
76186d20 JM |
3095 | { |
3096 | compound_literal | |
3097 | = finish_compound_literal (TREE_TYPE (type), compound_literal, | |
60648580 | 3098 | complain, fcl_context); |
a347241b JM |
3099 | /* The prvalue is then used to direct-initialize the reference. */ |
3100 | tree r = (perform_implicit_conversion_flags | |
3101 | (type, compound_literal, complain, LOOKUP_NORMAL)); | |
3102 | return convert_from_reference (r); | |
76186d20 JM |
3103 | } |
3104 | ||
2b643eda MM |
3105 | if (!TYPE_OBJ_P (type)) |
3106 | { | |
834aa426 JM |
3107 | if (complain & tf_error) |
3108 | error ("compound literal of non-object type %qT", type); | |
2b643eda MM |
3109 | return error_mark_node; |
3110 | } | |
3111 | ||
cf25e27f PP |
3112 | if (template_placeholder_p (type)) |
3113 | { | |
3114 | type = do_auto_deduction (type, compound_literal, type, complain, | |
3115 | adc_variable_type); | |
3116 | if (type == error_mark_node) | |
3117 | return error_mark_node; | |
3118 | } | |
8b7033e0 | 3119 | |
1f6857ba MP |
3120 | /* Used to hold a copy of the compound literal in a template. */ |
3121 | tree orig_cl = NULL_TREE; | |
3122 | ||
3123 | if (processing_template_decl) | |
a723baf1 | 3124 | { |
1f6857ba MP |
3125 | const bool dependent_p |
3126 | = (instantiation_dependent_expression_p (compound_literal) | |
3127 | || dependent_type_p (type)); | |
3128 | if (dependent_p) | |
3129 | /* We're about to return, no need to copy. */ | |
3130 | orig_cl = compound_literal; | |
3131 | else | |
3132 | /* We're going to need a copy. */ | |
3133 | orig_cl = unshare_constructor (compound_literal); | |
3134 | TREE_TYPE (orig_cl) = type; | |
e92fb501 | 3135 | /* Mark the expression as a compound literal. */ |
1f6857ba | 3136 | TREE_HAS_CONSTRUCTOR (orig_cl) = 1; |
f8ec35c3 | 3137 | /* And as instantiation-dependent. */ |
1f6857ba | 3138 | CONSTRUCTOR_IS_DEPENDENT (orig_cl) = dependent_p; |
60648580 | 3139 | if (fcl_context == fcl_c99) |
1f6857ba MP |
3140 | CONSTRUCTOR_C99_COMPOUND_LITERAL (orig_cl) = 1; |
3141 | /* If the compound literal is dependent, we're done for now. */ | |
3142 | if (dependent_p) | |
3143 | return orig_cl; | |
3144 | /* Otherwise, do go on to e.g. check narrowing. */ | |
a723baf1 MM |
3145 | } |
3146 | ||
df794884 | 3147 | type = complete_type (type); |
09357846 JM |
3148 | |
3149 | if (TYPE_NON_AGGREGATE_CLASS (type)) | |
3150 | { | |
3151 | /* Trying to deal with a CONSTRUCTOR instead of a TREE_LIST | |
3152 | everywhere that deals with function arguments would be a pain, so | |
3153 | just wrap it in a TREE_LIST. The parser set a flag so we know | |
3154 | that it came from T{} rather than T({}). */ | |
3155 | CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1; | |
3156 | compound_literal = build_tree_list (NULL_TREE, compound_literal); | |
ad774d0d PC |
3157 | return build_functional_cast (input_location, type, |
3158 | compound_literal, complain); | |
09357846 JM |
3159 | } |
3160 | ||
23bee8f4 JJ |
3161 | if (TREE_CODE (type) == ARRAY_TYPE |
3162 | && check_array_initializer (NULL_TREE, type, compound_literal)) | |
3163 | return error_mark_node; | |
754af126 | 3164 | compound_literal = reshape_init (type, compound_literal, complain); |
25339f10 | 3165 | if (SCALAR_TYPE_P (type) |
f83fad40 MP |
3166 | && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)) |
3167 | { | |
3168 | tree t = instantiate_non_dependent_expr_sfinae (compound_literal, | |
3169 | complain); | |
3170 | if (!check_narrowing (type, t, complain)) | |
3171 | return error_mark_node; | |
3172 | } | |
80c6dcf5 JM |
3173 | if (TREE_CODE (type) == ARRAY_TYPE |
3174 | && TYPE_DOMAIN (type) == NULL_TREE) | |
3175 | { | |
3176 | cp_complete_array_type_or_error (&type, compound_literal, | |
3177 | false, complain); | |
3178 | if (type == error_mark_node) | |
3179 | return error_mark_node; | |
3180 | } | |
1f6857ba MP |
3181 | compound_literal = digest_init_flags (type, compound_literal, |
3182 | LOOKUP_NORMAL | LOOKUP_NO_NARROWING, | |
0bdc4c1c | 3183 | complain); |
d724d2af MP |
3184 | if (compound_literal == error_mark_node) |
3185 | return error_mark_node; | |
3186 | ||
1f6857ba MP |
3187 | /* If we're in a template, return the original compound literal. */ |
3188 | if (orig_cl) | |
de6f64f9 | 3189 | return orig_cl; |
1f6857ba | 3190 | |
8c53f5e2 | 3191 | if (TREE_CODE (compound_literal) == CONSTRUCTOR) |
60648580 JM |
3192 | { |
3193 | TREE_HAS_CONSTRUCTOR (compound_literal) = true; | |
3194 | if (fcl_context == fcl_c99) | |
3195 | CONSTRUCTOR_C99_COMPOUND_LITERAL (compound_literal) = 1; | |
3196 | } | |
323af7cf NS |
3197 | |
3198 | /* Put static/constant array temporaries in static variables. */ | |
60648580 JM |
3199 | /* FIXME all C99 compound literals should be variables rather than C++ |
3200 | temporaries, unless they are used as an aggregate initializer. */ | |
a63940ba | 3201 | if ((!at_function_scope_p () || CP_TYPE_CONST_P (type)) |
60648580 | 3202 | && fcl_context == fcl_c99 |
a63940ba | 3203 | && TREE_CODE (type) == ARRAY_TYPE |
fa9ef321 | 3204 | && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type) |
a63940ba JM |
3205 | && initializer_constant_valid_p (compound_literal, type)) |
3206 | { | |
3207 | tree decl = create_temporary_var (type); | |
80a9c584 | 3208 | DECL_CONTEXT (decl) = NULL_TREE; |
a63940ba JM |
3209 | DECL_INITIAL (decl) = compound_literal; |
3210 | TREE_STATIC (decl) = 1; | |
3211 | if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type)) | |
3212 | { | |
3213 | /* 5.19 says that a constant expression can include an | |
3214 | lvalue-rvalue conversion applied to "a glvalue of literal type | |
3215 | that refers to a non-volatile temporary object initialized | |
3216 | with a constant expression". Rather than try to communicate | |
3217 | that this VAR_DECL is a temporary, just mark it constexpr. */ | |
3218 | DECL_DECLARED_CONSTEXPR_P (decl) = true; | |
3219 | DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true; | |
3220 | TREE_CONSTANT (decl) = true; | |
3221 | } | |
3222 | cp_apply_type_quals_to_decl (cp_type_quals (type), decl); | |
3223 | decl = pushdecl_top_level (decl); | |
3224 | DECL_NAME (decl) = make_anon_name (); | |
3225 | SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl)); | |
eca7fc57 JM |
3226 | /* Make sure the destructor is callable. */ |
3227 | tree clean = cxx_maybe_build_cleanup (decl, complain); | |
3228 | if (clean == error_mark_node) | |
3229 | return error_mark_node; | |
a63940ba JM |
3230 | return decl; |
3231 | } | |
323af7cf NS |
3232 | |
3233 | /* Represent other compound literals with TARGET_EXPR so we produce | |
3f0de4dd | 3234 | a prvalue, and can elide copies. */ |
323af7cf | 3235 | if (!VECTOR_TYPE_P (type)) |
3f0de4dd JM |
3236 | { |
3237 | /* The CONSTRUCTOR is now an initializer, not a compound literal. */ | |
3238 | TREE_HAS_CONSTRUCTOR (compound_literal) = false; | |
3239 | compound_literal = get_target_expr_sfinae (compound_literal, complain); | |
3240 | } | |
323af7cf NS |
3241 | |
3242 | return compound_literal; | |
a723baf1 MM |
3243 | } |
3244 | ||
5f261ba9 MM |
3245 | /* Return the declaration for the function-name variable indicated by |
3246 | ID. */ | |
3247 | ||
3248 | tree | |
3249 | finish_fname (tree id) | |
3250 | { | |
3251 | tree decl; | |
c8094d83 | 3252 | |
3ba09659 | 3253 | decl = fname_decl (input_location, C_RID_CODE (id), id); |
f2381074 KT |
3254 | if (processing_template_decl && current_function_decl |
3255 | && decl != error_mark_node) | |
10b1d5e7 | 3256 | decl = DECL_NAME (decl); |
5f261ba9 MM |
3257 | return decl; |
3258 | } | |
3259 | ||
8014a339 | 3260 | /* Finish a translation unit. */ |
ce4a0391 | 3261 | |
c8094d83 | 3262 | void |
3a978d72 | 3263 | finish_translation_unit (void) |
ce4a0391 MM |
3264 | { |
3265 | /* In case there were missing closebraces, | |
3266 | get us back to the global binding level. */ | |
273a708f | 3267 | pop_everything (); |
ce4a0391 MM |
3268 | while (current_namespace != global_namespace) |
3269 | pop_namespace (); | |
0ba8a114 | 3270 | |
c6002625 | 3271 | /* Do file scope __FUNCTION__ et al. */ |
0ba8a114 | 3272 | finish_fname_decls (); |
7cec9588 | 3273 | |
01f8a8b4 | 3274 | if (vec_safe_length (scope_chain->omp_declare_target_attribute)) |
7cec9588 JJ |
3275 | { |
3276 | if (!errorcount) | |
3277 | error ("%<#pragma omp declare target%> without corresponding " | |
3278 | "%<#pragma omp end declare target%>"); | |
01f8a8b4 | 3279 | vec_safe_truncate (scope_chain->omp_declare_target_attribute, 0); |
7cec9588 | 3280 | } |
ce4a0391 MM |
3281 | } |
3282 | ||
b4c4a9ec MM |
3283 | /* Finish a template type parameter, specified as AGGR IDENTIFIER. |
3284 | Returns the parameter. */ | |
3285 | ||
c8094d83 | 3286 | tree |
3a978d72 | 3287 | finish_template_type_parm (tree aggr, tree identifier) |
b4c4a9ec | 3288 | { |
6eabb241 | 3289 | if (aggr != class_type_node) |
b4c4a9ec | 3290 | { |
cbe5f3b3 | 3291 | permerror (input_location, "template type parameters must use the keyword %<class%> or %<typename%>"); |
b4c4a9ec MM |
3292 | aggr = class_type_node; |
3293 | } | |
3294 | ||
3295 | return build_tree_list (aggr, identifier); | |
3296 | } | |
3297 | ||
3298 | /* Finish a template template parameter, specified as AGGR IDENTIFIER. | |
3299 | Returns the parameter. */ | |
3300 | ||
c8094d83 | 3301 | tree |
3a978d72 | 3302 | finish_template_template_parm (tree aggr, tree identifier) |
b4c4a9ec | 3303 | { |
c2255bc4 AH |
3304 | tree decl = build_decl (input_location, |
3305 | TYPE_DECL, identifier, NULL_TREE); | |
971e17ff | 3306 | |
b4c4a9ec MM |
3307 | tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE); |
3308 | DECL_TEMPLATE_PARMS (tmpl) = current_template_parms; | |
3309 | DECL_TEMPLATE_RESULT (tmpl) = decl; | |
c727aa5e | 3310 | DECL_ARTIFICIAL (decl) = 1; |
971e17ff | 3311 | |
204a3763 JM |
3312 | /* Associate the constraints with the underlying declaration, |
3313 | not the template. */ | |
971e17ff AS |
3314 | tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); |
3315 | tree constr = build_constraints (reqs, NULL_TREE); | |
3316 | set_constraints (decl, constr); | |
3317 | ||
b4c4a9ec MM |
3318 | end_template_decl (); |
3319 | ||
50bc768d | 3320 | gcc_assert (DECL_TEMPLATE_PARMS (tmpl)); |
b37bf5bd | 3321 | |
43e1e8b5 | 3322 | check_default_tmpl_args (decl, DECL_TEMPLATE_PARMS (tmpl), |
85d85234 DG |
3323 | /*is_primary=*/true, /*is_partial=*/false, |
3324 | /*is_friend=*/0); | |
3325 | ||
b4c4a9ec MM |
3326 | return finish_template_type_parm (aggr, tmpl); |
3327 | } | |
ce4a0391 | 3328 | |
8ba658ee MM |
3329 | /* ARGUMENT is the default-argument value for a template template |
3330 | parameter. If ARGUMENT is invalid, issue error messages and return | |
3331 | the ERROR_MARK_NODE. Otherwise, ARGUMENT itself is returned. */ | |
3332 | ||
3333 | tree | |
3334 | check_template_template_default_arg (tree argument) | |
3335 | { | |
3336 | if (TREE_CODE (argument) != TEMPLATE_DECL | |
3337 | && TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM | |
8ba658ee MM |
3338 | && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE) |
3339 | { | |
a3a503a5 | 3340 | if (TREE_CODE (argument) == TYPE_DECL) |
e488a090 VR |
3341 | error ("invalid use of type %qT as a default value for a template " |
3342 | "template-parameter", TREE_TYPE (argument)); | |
a3a503a5 GB |
3343 | else |
3344 | error ("invalid default argument for a template template parameter"); | |
8ba658ee MM |
3345 | return error_mark_node; |
3346 | } | |
3347 | ||
3348 | return argument; | |
3349 | } | |
3350 | ||
ce4a0391 MM |
3351 | /* Begin a class definition, as indicated by T. */ |
3352 | ||
3353 | tree | |
e3c888eb | 3354 | begin_class_definition (tree t) |
ce4a0391 | 3355 | { |
7d2f0ecd | 3356 | if (error_operand_p (t) || error_operand_p (TYPE_MAIN_DECL (t))) |
7437519c ZW |
3357 | return error_mark_node; |
3358 | ||
03bed153 JM |
3359 | if (processing_template_parmlist && !LAMBDA_TYPE_P (t)) |
3360 | { | |
3361 | error ("definition of %q#T inside template parameter list", t); | |
3362 | return error_mark_node; | |
3363 | } | |
3364 | ||
ebf0bf7f JJ |
3365 | /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733 |
3366 | are passed the same as decimal scalar types. */ | |
cd924144 JM |
3367 | if (TREE_CODE (t) == RECORD_TYPE |
3368 | && !processing_template_decl) | |
ebf0bf7f | 3369 | { |
cd924144 JM |
3370 | tree ns = TYPE_CONTEXT (t); |
3371 | if (ns && TREE_CODE (ns) == NAMESPACE_DECL | |
3372 | && DECL_CONTEXT (ns) == std_node | |
935c0a5d | 3373 | && DECL_NAME (ns) |
a01f151f | 3374 | && id_equal (DECL_NAME (ns), "decimal")) |
cd924144 JM |
3375 | { |
3376 | const char *n = TYPE_NAME_STRING (t); | |
3377 | if ((strcmp (n, "decimal32") == 0) | |
3378 | || (strcmp (n, "decimal64") == 0) | |
3379 | || (strcmp (n, "decimal128") == 0)) | |
3380 | TYPE_TRANSPARENT_AGGR (t) = 1; | |
3381 | } | |
ebf0bf7f JJ |
3382 | } |
3383 | ||
47ee8904 MM |
3384 | /* A non-implicit typename comes from code like: |
3385 | ||
3386 | template <typename T> struct A { | |
0cbd7506 | 3387 | template <typename U> struct A<T>::B ... |
47ee8904 MM |
3388 | |
3389 | This is erroneous. */ | |
3390 | else if (TREE_CODE (t) == TYPENAME_TYPE) | |
3391 | { | |
a82e1a7d | 3392 | error ("invalid definition of qualified type %qT", t); |
47ee8904 MM |
3393 | t = error_mark_node; |
3394 | } | |
3395 | ||
9e1e64ec | 3396 | if (t == error_mark_node || ! MAYBE_CLASS_TYPE_P (t)) |
ce4a0391 | 3397 | { |
9e1e64ec | 3398 | t = make_class_type (RECORD_TYPE); |
d13c0ae8 | 3399 | pushtag (make_anon_name (), t); |
ce4a0391 | 3400 | } |
830fcda8 | 3401 | |
4c571114 | 3402 | if (TYPE_BEING_DEFINED (t)) |
ce4a0391 | 3403 | { |
9e1e64ec | 3404 | t = make_class_type (TREE_CODE (t)); |
d13c0ae8 | 3405 | pushtag (TYPE_IDENTIFIER (t), t); |
ce4a0391 | 3406 | } |
cf97b970 NS |
3407 | |
3408 | if (modules_p ()) | |
3409 | { | |
3410 | if (!module_may_redeclare (TYPE_NAME (t))) | |
3411 | { | |
3412 | error ("cannot declare %qD in a different module", TYPE_NAME (t)); | |
3413 | inform (DECL_SOURCE_LOCATION (TYPE_NAME (t)), "declared here"); | |
3414 | return error_mark_node; | |
3415 | } | |
3416 | set_instantiating_module (TYPE_NAME (t)); | |
3417 | set_defining_module (TYPE_NAME (t)); | |
3418 | } | |
3419 | ||
ff350acd | 3420 | maybe_process_partial_specialization (t); |
29370796 | 3421 | pushclass (t); |
ce4a0391 | 3422 | TYPE_BEING_DEFINED (t) = 1; |
5294e4c3 | 3423 | class_binding_level->defining_class_p = 1; |
b9e75696 | 3424 | |
c0694c4b MM |
3425 | if (flag_pack_struct) |
3426 | { | |
3427 | tree v; | |
3428 | TYPE_PACKED (t) = 1; | |
3429 | /* Even though the type is being defined for the first time | |
3430 | here, there might have been a forward declaration, so there | |
3431 | might be cv-qualified variants of T. */ | |
3432 | for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) | |
3433 | TYPE_PACKED (v) = 1; | |
3434 | } | |
ce4a0391 MM |
3435 | /* Reset the interface data, at the earliest possible |
3436 | moment, as it might have been set via a class foo; | |
3437 | before. */ | |
6a7b9203 | 3438 | if (! TYPE_UNNAMED_P (t)) |
1951a1b6 | 3439 | { |
8400e75e DM |
3440 | struct c_fileinfo *finfo = \ |
3441 | get_fileinfo (LOCATION_FILE (input_location)); | |
5d709b00 | 3442 | CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only; |
1951a1b6 | 3443 | SET_CLASSTYPE_INTERFACE_UNKNOWN_X |
5d709b00 | 3444 | (t, finfo->interface_unknown); |
1951a1b6 | 3445 | } |
7e6a72cb | 3446 | reset_specialization (); |
c8094d83 | 3447 | |
b7975aed MM |
3448 | /* Make a declaration for this class in its own scope. */ |
3449 | build_self_reference (); | |
3450 | ||
830fcda8 | 3451 | return t; |
ce4a0391 MM |
3452 | } |
3453 | ||
61a127b3 MM |
3454 | /* Finish the member declaration given by DECL. */ |
3455 | ||
3456 | void | |
3a978d72 | 3457 | finish_member_declaration (tree decl) |
61a127b3 MM |
3458 | { |
3459 | if (decl == error_mark_node || decl == NULL_TREE) | |
3460 | return; | |
3461 | ||
3462 | if (decl == void_type_node) | |
3463 | /* The COMPONENT was a friend, not a member, and so there's | |
3464 | nothing for us to do. */ | |
3465 | return; | |
3466 | ||
3467 | /* We should see only one DECL at a time. */ | |
910ad8de | 3468 | gcc_assert (DECL_CHAIN (decl) == NULL_TREE); |
61a127b3 | 3469 | |
7f357c61 NS |
3470 | /* Don't add decls after definition. */ |
3471 | gcc_assert (TYPE_BEING_DEFINED (current_class_type) | |
3472 | /* We can add lambda types when late parsing default | |
3473 | arguments. */ | |
3474 | || LAMBDA_TYPE_P (TREE_TYPE (decl))); | |
3475 | ||
61a127b3 | 3476 | /* Set up access control for DECL. */ |
c8094d83 | 3477 | TREE_PRIVATE (decl) |
61a127b3 | 3478 | = (current_access_specifier == access_private_node); |
c8094d83 | 3479 | TREE_PROTECTED (decl) |
61a127b3 MM |
3480 | = (current_access_specifier == access_protected_node); |
3481 | if (TREE_CODE (decl) == TEMPLATE_DECL) | |
3482 | { | |
17aec3eb RK |
3483 | TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl); |
3484 | TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl); | |
61a127b3 MM |
3485 | } |
3486 | ||
8d0d1915 JM |
3487 | /* Mark the DECL as a member of the current class, unless it's |
3488 | a member of an enumeration. */ | |
3489 | if (TREE_CODE (decl) != CONST_DECL) | |
3490 | DECL_CONTEXT (decl) = current_class_type; | |
61a127b3 | 3491 | |
716a5836 RB |
3492 | /* Remember the single FIELD_DECL an anonymous aggregate type is used for. */ |
3493 | if (TREE_CODE (decl) == FIELD_DECL | |
3494 | && ANON_AGGR_TYPE_P (TREE_TYPE (decl))) | |
3495 | { | |
3496 | gcc_assert (!ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl)))); | |
3497 | ANON_AGGR_TYPE_FIELD (TYPE_MAIN_VARIANT (TREE_TYPE (decl))) = decl; | |
3498 | } | |
3499 | ||
3928bd5f NS |
3500 | if (TREE_CODE (decl) == USING_DECL) |
3501 | /* For now, ignore class-scope USING_DECLS, so that debugging | |
3502 | backends do not see them. */ | |
3503 | DECL_IGNORED_P (decl) = 1; | |
3504 | ||
3505 | /* Check for bare parameter packs in the non-static data member | |
3506 | declaration. */ | |
1ad8aeeb | 3507 | if (TREE_CODE (decl) == FIELD_DECL) |
4439d02f | 3508 | { |
7b3e2d46 | 3509 | if (check_for_bare_parameter_packs (TREE_TYPE (decl))) |
4439d02f | 3510 | TREE_TYPE (decl) = error_mark_node; |
7b3e2d46 | 3511 | if (check_for_bare_parameter_packs (DECL_ATTRIBUTES (decl))) |
4439d02f DG |
3512 | DECL_ATTRIBUTES (decl) = NULL_TREE; |
3513 | } | |
b1d7b1c0 | 3514 | |
421844e7 MM |
3515 | /* [dcl.link] |
3516 | ||
3517 | A C language linkage is ignored for the names of class members | |
3518 | and the member function type of class member functions. */ | |
3928bd5f | 3519 | if (DECL_LANG_SPECIFIC (decl)) |
5d2ed28c | 3520 | SET_DECL_LANGUAGE (decl, lang_cplusplus); |
421844e7 | 3521 | |
3928bd5f | 3522 | bool add = false; |
f139561c | 3523 | |
3928bd5f NS |
3524 | /* Functions and non-functions are added differently. */ |
3525 | if (DECL_DECLARES_FUNCTION_P (decl)) | |
3526 | add = add_method (current_class_type, decl, false); | |
fad882c6 JM |
3527 | /* Enter the DECL into the scope of the class, if the class |
3528 | isn't a closure (whose fields are supposed to be unnamed). */ | |
3529 | else if (CLASSTYPE_LAMBDA_EXPR (current_class_type) | |
3530 | || pushdecl_class_level (decl)) | |
3928bd5f | 3531 | add = true; |
557831a9 | 3532 | |
3928bd5f NS |
3533 | if (add) |
3534 | { | |
61a127b3 | 3535 | /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields |
3928bd5f NS |
3536 | go at the beginning. The reason is that |
3537 | legacy_nonfn_member_lookup searches the list in order, and we | |
3538 | want a field name to override a type name so that the "struct | |
3539 | stat hack" will work. In particular: | |
3540 | ||
3541 | struct S { enum E { }; static const int E = 5; int ary[S::E]; } s; | |
3542 | ||
3543 | is valid. */ | |
61a127b3 MM |
3544 | |
3545 | if (TREE_CODE (decl) == TYPE_DECL) | |
c8094d83 | 3546 | TYPE_FIELDS (current_class_type) |
61a127b3 MM |
3547 | = chainon (TYPE_FIELDS (current_class_type), decl); |
3548 | else | |
3549 | { | |
910ad8de | 3550 | DECL_CHAIN (decl) = TYPE_FIELDS (current_class_type); |
61a127b3 MM |
3551 | TYPE_FIELDS (current_class_type) = decl; |
3552 | } | |
8f032717 | 3553 | |
c8094d83 | 3554 | maybe_add_class_template_decl_list (current_class_type, decl, |
f139561c | 3555 | /*friend_p=*/0); |
61a127b3 MM |
3556 | } |
3557 | } | |
3558 | ||
306ef644 | 3559 | /* Finish processing a complete template declaration. The PARMS are |
36a117a5 MM |
3560 | the template parameters. */ |
3561 | ||
3562 | void | |
3a978d72 | 3563 | finish_template_decl (tree parms) |
36a117a5 MM |
3564 | { |
3565 | if (parms) | |
3566 | end_template_decl (); | |
3567 | else | |
3568 | end_specialization (); | |
3569 | } | |
3570 | ||
971e17ff AS |
3571 | // Returns the template type of the class scope being entered. If we're |
3572 | // entering a constrained class scope. TYPE is the class template | |
3573 | // scope being entered and we may need to match the intended type with | |
3574 | // a constrained specialization. For example: | |
3575 | // | |
3576 | // template<Object T> | |
3577 | // struct S { void f(); }; #1 | |
3578 | // | |
3579 | // template<Object T> | |
3580 | // void S<T>::f() { } #2 | |
3581 | // | |
3582 | // We check, in #2, that S<T> refers precisely to the type declared by | |
3583 | // #1 (i.e., that the constraints match). Note that the following should | |
3584 | // be an error since there is no specialization of S<T> that is | |
3585 | // unconstrained, but this is not diagnosed here. | |
3586 | // | |
3587 | // template<typename T> | |
3588 | // void S<T>::f() { } | |
3589 | // | |
3590 | // We cannot diagnose this problem here since this function also matches | |
3591 | // qualified template names that are not part of a definition. For example: | |
3592 | // | |
3593 | // template<Integral T, Floating_point U> | |
3594 | // typename pair<T, U>::first_type void f(T, U); | |
3595 | // | |
3596 | // Here, it is unlikely that there is a partial specialization of | |
3597 | // pair constrained for for Integral and Floating_point arguments. | |
3598 | // | |
3599 | // The general rule is: if a constrained specialization with matching | |
3600 | // constraints is found return that type. Also note that if TYPE is not a | |
3601 | // class-type (e.g. a typename type), then no fixup is needed. | |
3602 | ||
3603 | static tree | |
3604 | fixup_template_type (tree type) | |
3605 | { | |
3606 | // Find the template parameter list at the a depth appropriate to | |
3607 | // the scope we're trying to enter. | |
3608 | tree parms = current_template_parms; | |
3609 | int depth = template_class_depth (type); | |
3610 | for (int n = processing_template_decl; n > depth && parms; --n) | |
3611 | parms = TREE_CHAIN (parms); | |
3612 | if (!parms) | |
3613 | return type; | |
3614 | tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms); | |
3615 | tree cur_constr = build_constraints (cur_reqs, NULL_TREE); | |
3616 | ||
3617 | // Search for a specialization whose type and constraints match. | |
3618 | tree tmpl = CLASSTYPE_TI_TEMPLATE (type); | |
3619 | tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); | |
3620 | while (specs) | |
3621 | { | |
3622 | tree spec_constr = get_constraints (TREE_VALUE (specs)); | |
3623 | ||
3624 | // If the type and constraints match a specialization, then we | |
3625 | // are entering that type. | |
3626 | if (same_type_p (type, TREE_TYPE (specs)) | |
3627 | && equivalent_constraints (cur_constr, spec_constr)) | |
3628 | return TREE_TYPE (specs); | |
3629 | specs = TREE_CHAIN (specs); | |
3630 | } | |
3631 | ||
3632 | // If no specialization matches, then must return the type | |
3633 | // previously found. | |
3634 | return type; | |
3635 | } | |
3636 | ||
509fc277 | 3637 | /* Finish processing a template-id (which names a type) of the form |
36a117a5 | 3638 | NAME < ARGS >. Return the TYPE_DECL for the type named by the |
838dfd8a | 3639 | template-id. If ENTERING_SCOPE is nonzero we are about to enter |
36a117a5 MM |
3640 | the scope of template-id indicated. */ |
3641 | ||
3642 | tree | |
3a978d72 | 3643 | finish_template_type (tree name, tree args, int entering_scope) |
36a117a5 | 3644 | { |
28704289 | 3645 | tree type; |
36a117a5 | 3646 | |
28704289 | 3647 | type = lookup_template_class (name, args, |
42eaed49 | 3648 | NULL_TREE, NULL_TREE, entering_scope, |
23fca1f5 | 3649 | tf_warning_or_error | tf_user); |
971e17ff AS |
3650 | |
3651 | /* If we might be entering the scope of a partial specialization, | |
3652 | find the one with the right constraints. */ | |
3653 | if (flag_concepts | |
3654 | && entering_scope | |
3655 | && CLASS_TYPE_P (type) | |
e4307389 | 3656 | && CLASSTYPE_TEMPLATE_INFO (type) |
971e17ff AS |
3657 | && dependent_type_p (type) |
3658 | && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))) | |
3659 | type = fixup_template_type (type); | |
3660 | ||
28704289 DS |
3661 | if (type == error_mark_node) |
3662 | return type; | |
3663 | else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type)) | |
3664 | return TYPE_STUB_DECL (type); | |
3665 | else | |
3666 | return TYPE_NAME (type); | |
36a117a5 | 3667 | } |
648f19f6 | 3668 | |
ea6021e8 MM |
3669 | /* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER. |
3670 | Return a TREE_LIST containing the ACCESS_SPECIFIER and the | |
3671 | BASE_CLASS, or NULL_TREE if an error occurred. The | |
aba649ba | 3672 | ACCESS_SPECIFIER is one of |
809e3e7f NS |
3673 | access_{default,public,protected_private}_node. For a virtual base |
3674 | we set TREE_TYPE. */ | |
ea6021e8 | 3675 | |
c8094d83 | 3676 | tree |
dbbf88d1 | 3677 | finish_base_specifier (tree base, tree access, bool virtual_p) |
ea6021e8 | 3678 | { |
ea6021e8 MM |
3679 | tree result; |
3680 | ||
dbbf88d1 | 3681 | if (base == error_mark_node) |
acb044ee GDR |
3682 | { |
3683 | error ("invalid base-class specification"); | |
3684 | result = NULL_TREE; | |
3685 | } | |
9e1e64ec PC |
3686 | else if (! MAYBE_CLASS_TYPE_P (base)) |
3687 | { | |
3688 | error ("%qT is not a class type", base); | |
3689 | result = NULL_TREE; | |
3690 | } | |
ea6021e8 | 3691 | else |
bb92901d | 3692 | { |
dbbf88d1 | 3693 | if (cp_type_quals (base) != 0) |
0cbd7506 | 3694 | { |
546a4197 PC |
3695 | /* DR 484: Can a base-specifier name a cv-qualified |
3696 | class type? */ | |
0cbd7506 MS |
3697 | base = TYPE_MAIN_VARIANT (base); |
3698 | } | |
dbbf88d1 | 3699 | result = build_tree_list (access, base); |
809e3e7f NS |
3700 | if (virtual_p) |
3701 | TREE_TYPE (result) = integer_type_node; | |
bb92901d | 3702 | } |
ea6021e8 MM |
3703 | |
3704 | return result; | |
3705 | } | |
61a127b3 | 3706 | |
eff3a276 MM |
3707 | /* If FNS is a member function, a set of member functions, or a |
3708 | template-id referring to one or more member functions, return a | |
3709 | BASELINK for FNS, incorporating the current access context. | |
3710 | Otherwise, return FNS unchanged. */ | |
3711 | ||
3712 | tree | |
3713 | baselink_for_fns (tree fns) | |
3714 | { | |
aef3a6b2 | 3715 | tree scope; |
eff3a276 MM |
3716 | tree cl; |
3717 | ||
43e1e8b5 | 3718 | if (BASELINK_P (fns) |
eff3a276 MM |
3719 | || error_operand_p (fns)) |
3720 | return fns; | |
aef3a6b2 JM |
3721 | |
3722 | scope = ovl_scope (fns); | |
3723 | if (!CLASS_TYPE_P (scope)) | |
eff3a276 MM |
3724 | return fns; |
3725 | ||
aef3a6b2 | 3726 | cl = currently_open_derived_class (scope); |
eff3a276 | 3727 | if (!cl) |
aef3a6b2 | 3728 | cl = scope; |
f07edb5d JM |
3729 | tree access_path = TYPE_BINFO (cl); |
3730 | tree conv_path = (cl == scope ? access_path | |
3731 | : lookup_base (cl, scope, ba_any, NULL, tf_none)); | |
3732 | return build_baselink (conv_path, access_path, fns, /*optype=*/NULL_TREE); | |
eff3a276 MM |
3733 | } |
3734 | ||
9fd30fec | 3735 | /* Returns true iff DECL is a variable from a function outside |
d5f4eddd JM |
3736 | the current one. */ |
3737 | ||
3738 | static bool | |
9fd30fec | 3739 | outer_var_p (tree decl) |
d5f4eddd | 3740 | { |
5a6ccc94 | 3741 | return ((VAR_P (decl) || TREE_CODE (decl) == PARM_DECL) |
d5f4eddd | 3742 | && DECL_FUNCTION_SCOPE_P (decl) |
e1bea341 JM |
3743 | /* Don't get confused by temporaries. */ |
3744 | && DECL_NAME (decl) | |
cdf47df0 JM |
3745 | && (DECL_CONTEXT (decl) != current_function_decl |
3746 | || parsing_nsdmi ())); | |
d5f4eddd JM |
3747 | } |
3748 | ||
9fd30fec JM |
3749 | /* As above, but also checks that DECL is automatic. */ |
3750 | ||
548cb3d7 | 3751 | bool |
9fd30fec JM |
3752 | outer_automatic_var_p (tree decl) |
3753 | { | |
3754 | return (outer_var_p (decl) | |
3755 | && !TREE_STATIC (decl)); | |
3756 | } | |
3757 | ||
548cb3d7 | 3758 | /* DECL satisfies outer_automatic_var_p. Possibly complain about it or |
c1051bf7 JM |
3759 | rewrite it for lambda capture. |
3760 | ||
3761 | If ODR_USE is true, we're being called from mark_use, and we complain about | |
3762 | use of constant variables. If ODR_USE is false, we're being called for the | |
3763 | id-expression, and we do lambda capture. */ | |
548cb3d7 JM |
3764 | |
3765 | tree | |
c1051bf7 | 3766 | process_outer_var_ref (tree decl, tsubst_flags_t complain, bool odr_use) |
548cb3d7 JM |
3767 | { |
3768 | if (cp_unevaluated_operand) | |
00a49cd8 JM |
3769 | { |
3770 | tree type = TREE_TYPE (decl); | |
3771 | if (!dependent_type_p (type) | |
3772 | && variably_modified_type_p (type, NULL_TREE)) | |
3773 | /* VLAs are used even in unevaluated context. */; | |
3774 | else | |
3775 | /* It's not a use (3.2) if we're in an unevaluated context. */ | |
3776 | return decl; | |
3777 | } | |
63d02f05 JM |
3778 | if (decl == error_mark_node) |
3779 | return decl; | |
548cb3d7 JM |
3780 | |
3781 | tree context = DECL_CONTEXT (decl); | |
3782 | tree containing_function = current_function_decl; | |
3783 | tree lambda_stack = NULL_TREE; | |
3784 | tree lambda_expr = NULL_TREE; | |
3785 | tree initializer = convert_from_reference (decl); | |
3786 | ||
3787 | /* Mark it as used now even if the use is ill-formed. */ | |
20700098 | 3788 | if (!mark_used (decl, complain)) |
9f635aba | 3789 | return error_mark_node; |
548cb3d7 | 3790 | |
548cb3d7 JM |
3791 | if (parsing_nsdmi ()) |
3792 | containing_function = NULL_TREE; | |
f44a8dd5 | 3793 | |
5c263e84 JM |
3794 | if (containing_function && LAMBDA_FUNCTION_P (containing_function)) |
3795 | { | |
3796 | /* Check whether we've already built a proxy. */ | |
84dd815f | 3797 | tree var = decl; |
68ad1bf7 | 3798 | while (is_normal_capture_proxy (var)) |
84dd815f JM |
3799 | var = DECL_CAPTURED_VARIABLE (var); |
3800 | tree d = retrieve_local_specialization (var); | |
3801 | ||
3802 | if (d && d != decl && is_capture_proxy (d)) | |
5c263e84 JM |
3803 | { |
3804 | if (DECL_CONTEXT (d) == containing_function) | |
3805 | /* We already have an inner proxy. */ | |
3806 | return d; | |
3807 | else | |
3808 | /* We need to capture an outer proxy. */ | |
c1051bf7 | 3809 | return process_outer_var_ref (d, complain, odr_use); |
5c263e84 | 3810 | } |
f44a8dd5 JM |
3811 | } |
3812 | ||
3813 | /* If we are in a lambda function, we can move out until we hit | |
3814 | 1. the context, | |
3815 | 2. a non-lambda function, or | |
3816 | 3. a non-default capturing lambda function. */ | |
3817 | while (context != containing_function | |
3818 | /* containing_function can be null with invalid generic lambdas. */ | |
3819 | && containing_function | |
3820 | && LAMBDA_FUNCTION_P (containing_function)) | |
3821 | { | |
3822 | tree closure = DECL_CONTEXT (containing_function); | |
3823 | lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure); | |
3824 | ||
3825 | if (TYPE_CLASS_SCOPE_P (closure)) | |
3826 | /* A lambda in an NSDMI (c++/64496). */ | |
3827 | break; | |
3828 | ||
348dd384 | 3829 | if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE) |
f44a8dd5 JM |
3830 | break; |
3831 | ||
348dd384 | 3832 | lambda_stack = tree_cons (NULL_TREE, lambda_expr, lambda_stack); |
f44a8dd5 | 3833 | |
348dd384 | 3834 | containing_function = decl_function_context (containing_function); |
f44a8dd5 JM |
3835 | } |
3836 | ||
e6df04c1 JM |
3837 | /* In a lambda within a template, wait until instantiation time to implicitly |
3838 | capture a parameter pack. We want to wait because we don't know if we're | |
3839 | capturing the whole pack or a single element, and it's OK to wait because | |
3840 | find_parameter_packs_r walks into the lambda body. */ | |
f44a8dd5 | 3841 | if (context == containing_function |
e6df04c1 | 3842 | && DECL_PACK_P (decl)) |
f44a8dd5 | 3843 | return decl; |
548cb3d7 | 3844 | |
348dd384 | 3845 | if (lambda_expr && VAR_P (decl) && DECL_ANON_UNION_VAR_P (decl)) |
548cb3d7 JM |
3846 | { |
3847 | if (complain & tf_error) | |
3848 | error ("cannot capture member %qD of anonymous union", decl); | |
3849 | return error_mark_node; | |
3850 | } | |
c1051bf7 JM |
3851 | /* Do lambda capture when processing the id-expression, not when |
3852 | odr-using a variable. */ | |
3853 | if (!odr_use && context == containing_function) | |
348dd384 NS |
3854 | decl = add_default_capture (lambda_stack, |
3855 | /*id=*/DECL_NAME (decl), initializer); | |
c1051bf7 JM |
3856 | /* Only an odr-use of an outer automatic variable causes an |
3857 | error, and a constant variable can decay to a prvalue | |
3858 | constant without odr-use. So don't complain yet. */ | |
3859 | else if (!odr_use && decl_constant_var_p (decl)) | |
3860 | return decl; | |
548cb3d7 JM |
3861 | else if (lambda_expr) |
3862 | { | |
3863 | if (complain & tf_error) | |
47867b4f JM |
3864 | { |
3865 | error ("%qD is not captured", decl); | |
3866 | tree closure = LAMBDA_EXPR_CLOSURE (lambda_expr); | |
348dd384 | 3867 | if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_NONE) |
47867b4f JM |
3868 | inform (location_of (closure), |
3869 | "the lambda has no capture-default"); | |
3870 | else if (TYPE_CLASS_SCOPE_P (closure)) | |
64a5912c | 3871 | inform (UNKNOWN_LOCATION, "lambda in local class %q+T cannot " |
47867b4f JM |
3872 | "capture variables from the enclosing context", |
3873 | TYPE_CONTEXT (closure)); | |
4b1cbcee | 3874 | inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl); |
47867b4f | 3875 | } |
548cb3d7 JM |
3876 | return error_mark_node; |
3877 | } | |
3878 | else | |
3879 | { | |
3880 | if (complain & tf_error) | |
91d01bf4 JM |
3881 | { |
3882 | error (VAR_P (decl) | |
3883 | ? G_("use of local variable with automatic storage from " | |
3884 | "containing function") | |
3885 | : G_("use of parameter from containing function")); | |
3886 | inform (DECL_SOURCE_LOCATION (decl), "%q#D declared here", decl); | |
3887 | } | |
548cb3d7 JM |
3888 | return error_mark_node; |
3889 | } | |
3890 | return decl; | |
3891 | } | |
3892 | ||
b3445994 MM |
3893 | /* ID_EXPRESSION is a representation of parsed, but unprocessed, |
3894 | id-expression. (See cp_parser_id_expression for details.) SCOPE, | |
3895 | if non-NULL, is the type or namespace used to explicitly qualify | |
3896 | ID_EXPRESSION. DECL is the entity to which that name has been | |
c8094d83 | 3897 | resolved. |
b3445994 MM |
3898 | |
3899 | *CONSTANT_EXPRESSION_P is true if we are presently parsing a | |
3900 | constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will | |
3901 | be set to true if this expression isn't permitted in a | |
3902 | constant-expression, but it is otherwise not set by this function. | |
3903 | *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a | |
3904 | constant-expression, but a non-constant expression is also | |
3905 | permissible. | |
3906 | ||
02ed62dd MM |
3907 | DONE is true if this expression is a complete postfix-expression; |
3908 | it is false if this expression is followed by '->', '[', '(', etc. | |
3909 | ADDRESS_P is true iff this expression is the operand of '&'. | |
3910 | TEMPLATE_P is true iff the qualified-id was of the form | |
3911 | "A::template B". TEMPLATE_ARG_P is true iff this qualified name | |
3912 | appears as a template argument. | |
3913 | ||
b3445994 MM |
3914 | If an error occurs, and it is the kind of error that might cause |
3915 | the parser to abort a tentative parse, *ERROR_MSG is filled in. It | |
3916 | is the caller's responsibility to issue the message. *ERROR_MSG | |
3917 | will be a string with static storage duration, so the caller need | |
3918 | not "free" it. | |
3919 | ||
3920 | Return an expression for the entity, after issuing appropriate | |
3921 | diagnostics. This function is also responsible for transforming a | |
3922 | reference to a non-static member into a COMPONENT_REF that makes | |
c8094d83 | 3923 | the use of "this" explicit. |
b3445994 MM |
3924 | |
3925 | Upon return, *IDK will be filled in appropriately. */ | |
dfd7fdca DM |
3926 | static cp_expr |
3927 | finish_id_expression_1 (tree id_expression, | |
3928 | tree decl, | |
3929 | tree scope, | |
3930 | cp_id_kind *idk, | |
3931 | bool integral_constant_expression_p, | |
3932 | bool allow_non_integral_constant_expression_p, | |
3933 | bool *non_integral_constant_expression_p, | |
3934 | bool template_p, | |
3935 | bool done, | |
3936 | bool address_p, | |
3937 | bool template_arg_p, | |
3938 | const char **error_msg, | |
3939 | location_t location) | |
b3445994 | 3940 | { |
a9727434 FC |
3941 | decl = strip_using_decl (decl); |
3942 | ||
b3445994 MM |
3943 | /* Initialize the output parameters. */ |
3944 | *idk = CP_ID_KIND_NONE; | |
3945 | *error_msg = NULL; | |
3946 | ||
3947 | if (id_expression == error_mark_node) | |
3948 | return error_mark_node; | |
3949 | /* If we have a template-id, then no further lookup is | |
3950 | required. If the template-id was for a template-class, we | |
3951 | will sometimes have a TYPE_DECL at this point. */ | |
3952 | else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR | |
ee935db4 | 3953 | || TREE_CODE (decl) == TYPE_DECL) |
b3445994 MM |
3954 | ; |
3955 | /* Look up the name. */ | |
c8094d83 | 3956 | else |
b3445994 MM |
3957 | { |
3958 | if (decl == error_mark_node) | |
3959 | { | |
3960 | /* Name lookup failed. */ | |
c8094d83 MS |
3961 | if (scope |
3962 | && (!TYPE_P (scope) | |
4546865e | 3963 | || (!dependent_type_p (scope) |
9dc6f476 | 3964 | && !(identifier_p (id_expression) |
84c0088f | 3965 | && IDENTIFIER_CONV_OP_P (id_expression) |
4546865e | 3966 | && dependent_type_p (TREE_TYPE (id_expression)))))) |
b3445994 | 3967 | { |
4546865e MM |
3968 | /* If the qualifying type is non-dependent (and the name |
3969 | does not name a conversion operator to a dependent | |
3970 | type), issue an error. */ | |
2b7a3abf | 3971 | qualified_name_lookup_error (scope, id_expression, decl, location); |
b3445994 MM |
3972 | return error_mark_node; |
3973 | } | |
3974 | else if (!scope) | |
3975 | { | |
3976 | /* It may be resolved via Koenig lookup. */ | |
3977 | *idk = CP_ID_KIND_UNQUALIFIED; | |
3978 | return id_expression; | |
3979 | } | |
4546865e MM |
3980 | else |
3981 | decl = id_expression; | |
b3445994 | 3982 | } |
b3445994 MM |
3983 | |
3984 | /* Remember that the name was used in the definition of | |
3985 | the current class so that we can check later to see if | |
3986 | the meaning would have been different after the class | |
3987 | was entirely defined. */ | |
9dc6f476 | 3988 | if (!scope && decl != error_mark_node && identifier_p (id_expression)) |
b3445994 | 3989 | maybe_note_name_used_in_class (id_expression, decl); |
8ca4bf25 | 3990 | |
76f39440 JM |
3991 | /* A use in unevaluated operand might not be instantiated appropriately |
3992 | if tsubst_copy builds a dummy parm, or if we never instantiate a | |
3993 | generic lambda, so mark it now. */ | |
3994 | if (processing_template_decl && cp_unevaluated_operand) | |
3995 | mark_type_use (decl); | |
3996 | ||
d5f4eddd JM |
3997 | /* Disallow uses of local variables from containing functions, except |
3998 | within lambda-expressions. */ | |
548cb3d7 | 3999 | if (outer_automatic_var_p (decl)) |
cfb71cad JM |
4000 | { |
4001 | decl = process_outer_var_ref (decl, tf_warning_or_error); | |
4002 | if (decl == error_mark_node) | |
4003 | return error_mark_node; | |
4004 | } | |
da9bc840 JM |
4005 | |
4006 | /* Also disallow uses of function parameters outside the function | |
4007 | body, except inside an unevaluated context (i.e. decltype). */ | |
4008 | if (TREE_CODE (decl) == PARM_DECL | |
4009 | && DECL_CONTEXT (decl) == NULL_TREE | |
4010 | && !cp_unevaluated_operand) | |
4011 | { | |
24f12823 | 4012 | *error_msg = G_("use of parameter outside function body"); |
da9bc840 JM |
4013 | return error_mark_node; |
4014 | } | |
b3445994 MM |
4015 | } |
4016 | ||
4017 | /* If we didn't find anything, or what we found was a type, | |
4018 | then this wasn't really an id-expression. */ | |
4019 | if (TREE_CODE (decl) == TEMPLATE_DECL | |
4020 | && !DECL_FUNCTION_TEMPLATE_P (decl)) | |
4021 | { | |
24f12823 | 4022 | *error_msg = G_("missing template arguments"); |
b3445994 MM |
4023 | return error_mark_node; |
4024 | } | |
4025 | else if (TREE_CODE (decl) == TYPE_DECL | |
4026 | || TREE_CODE (decl) == NAMESPACE_DECL) | |
4027 | { | |
24f12823 | 4028 | *error_msg = G_("expected primary-expression"); |
b3445994 MM |
4029 | return error_mark_node; |
4030 | } | |
4031 | ||
4032 | /* If the name resolved to a template parameter, there is no | |
931a9c05 GB |
4033 | need to look it up again later. */ |
4034 | if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl)) | |
4035 | || TREE_CODE (decl) == TEMPLATE_PARM_INDEX) | |
b3445994 | 4036 | { |
db24eb1f | 4037 | tree r; |
c8094d83 | 4038 | |
b3445994 | 4039 | *idk = CP_ID_KIND_NONE; |
931a9c05 GB |
4040 | if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX) |
4041 | decl = TEMPLATE_PARM_DECL (decl); | |
4be5c72c JM |
4042 | r = DECL_INITIAL (decl); |
4043 | if (CLASS_TYPE_P (TREE_TYPE (r)) && !CP_TYPE_CONST_P (TREE_TYPE (r))) | |
4044 | { | |
4045 | /* If the entity is a template parameter object for a template | |
4046 | parameter of type T, the type of the expression is const T. */ | |
4047 | tree ctype = TREE_TYPE (r); | |
4048 | ctype = cp_build_qualified_type (ctype, (cp_type_quals (ctype) | |
4049 | | TYPE_QUAL_CONST)); | |
4050 | r = build1 (VIEW_CONVERT_EXPR, ctype, r); | |
4051 | } | |
4052 | r = convert_from_reference (r); | |
c8094d83 | 4053 | if (integral_constant_expression_p |
68deab91 | 4054 | && !dependent_type_p (TREE_TYPE (decl)) |
db24eb1f | 4055 | && !(INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (r)))) |
931a9c05 | 4056 | { |
67c03833 | 4057 | if (!allow_non_integral_constant_expression_p) |
a82e1a7d | 4058 | error ("template parameter %qD of type %qT is not allowed in " |
931a9c05 GB |
4059 | "an integral constant expression because it is not of " |
4060 | "integral or enumeration type", decl, TREE_TYPE (decl)); | |
67c03833 | 4061 | *non_integral_constant_expression_p = true; |
931a9c05 | 4062 | } |
db24eb1f | 4063 | return r; |
931a9c05 | 4064 | } |
b3445994 MM |
4065 | else |
4066 | { | |
a2b4cfaa | 4067 | bool dependent_p = type_dependent_expression_p (decl); |
b3445994 MM |
4068 | |
4069 | /* If the declaration was explicitly qualified indicate | |
4070 | that. The semantics of `A::f(3)' are different than | |
4071 | `f(3)' if `f' is virtual. */ | |
c8094d83 | 4072 | *idk = (scope |
b3445994 MM |
4073 | ? CP_ID_KIND_QUALIFIED |
4074 | : (TREE_CODE (decl) == TEMPLATE_ID_EXPR | |
4075 | ? CP_ID_KIND_TEMPLATE_ID | |
a2b4cfaa JM |
4076 | : (dependent_p |
4077 | ? CP_ID_KIND_UNQUALIFIED_DEPENDENT | |
4078 | : CP_ID_KIND_UNQUALIFIED))); | |
b3445994 | 4079 | |
bb6a6ee9 | 4080 | if (dependent_p |
88b811bd JM |
4081 | && DECL_P (decl) |
4082 | && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl))) | |
4083 | /* Dependent type attributes on the decl mean that the TREE_TYPE is | |
4084 | wrong, so just return the identifier. */ | |
4085 | return id_expression; | |
b3445994 | 4086 | |
c2aa34b5 | 4087 | if (DECL_CLASS_TEMPLATE_P (decl)) |
9e95d15f | 4088 | { |
a82e1a7d | 4089 | error ("use of class template %qT as expression", decl); |
9e95d15f NS |
4090 | return error_mark_node; |
4091 | } | |
c2aa34b5 NS |
4092 | |
4093 | if (TREE_CODE (decl) == TREE_LIST) | |
9e95d15f NS |
4094 | { |
4095 | /* Ambiguous reference to base members. */ | |
a82e1a7d | 4096 | error ("request for member %qD is ambiguous in " |
9e95d15f NS |
4097 | "multiple inheritance lattice", id_expression); |
4098 | print_candidates (decl); | |
4099 | return error_mark_node; | |
4100 | } | |
415d4636 MM |
4101 | |
4102 | /* Mark variable-like entities as used. Functions are similarly | |
4103 | marked either below or after overload resolution. */ | |
5a6ccc94 | 4104 | if ((VAR_P (decl) |
f27a59cf PC |
4105 | || TREE_CODE (decl) == PARM_DECL |
4106 | || TREE_CODE (decl) == CONST_DECL | |
4107 | || TREE_CODE (decl) == RESULT_DECL) | |
4108 | && !mark_used (decl)) | |
4109 | return error_mark_node; | |
415d4636 | 4110 | |
aef4a215 | 4111 | /* Only certain kinds of names are allowed in constant |
8d0d1915 | 4112 | expression. Template parameters have already |
aef4a215 | 4113 | been handled above. */ |
7f7d4b12 | 4114 | if (! error_operand_p (decl) |
88b811bd | 4115 | && !dependent_p |
7f7d4b12 | 4116 | && integral_constant_expression_p |
cb57504a | 4117 | && !decl_constant_var_p (decl) |
8d0d1915 | 4118 | && TREE_CODE (decl) != CONST_DECL |
cb57504a JM |
4119 | && !builtin_valid_in_constant_expr_p (decl) |
4120 | && !concept_check_p (decl)) | |
aef4a215 JM |
4121 | { |
4122 | if (!allow_non_integral_constant_expression_p) | |
4123 | { | |
4124 | error ("%qD cannot appear in a constant-expression", decl); | |
4125 | return error_mark_node; | |
4126 | } | |
4127 | *non_integral_constant_expression_p = true; | |
4128 | } | |
4129 | ||
5c3703c5 JJ |
4130 | if (tree wrap = maybe_get_tls_wrapper_call (decl)) |
4131 | /* Replace an evaluated use of the thread_local variable with | |
4132 | a call to its wrapper. */ | |
4133 | decl = wrap; | |
4a4f287d | 4134 | else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR |
88b811bd | 4135 | && !dependent_p |
cb57504a JM |
4136 | && variable_template_p (TREE_OPERAND (decl, 0)) |
4137 | && !concept_check_p (decl)) | |
4a4f287d BO |
4138 | { |
4139 | decl = finish_template_variable (decl); | |
5e0231c2 | 4140 | mark_used (decl); |
85171e78 | 4141 | decl = convert_from_reference (decl); |
4a4f287d | 4142 | } |
cb57504a JM |
4143 | else if (concept_check_p (decl)) |
4144 | { | |
861d4af8 AS |
4145 | /* Nothing more to do. All of the analysis for concept checks |
4146 | is done by build_conept_id, called from the parser. */ | |
cb57504a | 4147 | } |
7c424acd | 4148 | else if (scope) |
415d4636 | 4149 | { |
88b811bd JM |
4150 | if (TREE_CODE (decl) == SCOPE_REF) |
4151 | { | |
4152 | gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0))); | |
4153 | decl = TREE_OPERAND (decl, 1); | |
4154 | } | |
4155 | ||
c8094d83 | 4156 | decl = (adjust_result_of_qualified_name_lookup |
90677b8d | 4157 | (decl, scope, current_nonlambda_class_type())); |
e20bcc5e JH |
4158 | |
4159 | if (TREE_CODE (decl) == FUNCTION_DECL) | |
4160 | mark_used (decl); | |
4161 | ||
5857042a MP |
4162 | cp_warn_deprecated_use_scopes (scope); |
4163 | ||
e467c9d2 | 4164 | if (TYPE_P (scope)) |
02ed62dd MM |
4165 | decl = finish_qualified_id_expr (scope, |
4166 | decl, | |
4167 | done, | |
4168 | address_p, | |
4169 | template_p, | |
a378996b PC |
4170 | template_arg_p, |
4171 | tf_warning_or_error); | |
db24eb1f | 4172 | else |
e467c9d2 | 4173 | decl = convert_from_reference (decl); |
415d4636 | 4174 | } |
9e95d15f | 4175 | else if (TREE_CODE (decl) == FIELD_DECL) |
a26ddf11 KL |
4176 | { |
4177 | /* Since SCOPE is NULL here, this is an unqualified name. | |
4178 | Access checking has been performed during name lookup | |
4179 | already. Turn off checking to avoid duplicate errors. */ | |
4180 | push_deferring_access_checks (dk_no_check); | |
2defb926 | 4181 | decl = finish_non_static_data_member (decl, NULL_TREE, |
a26ddf11 KL |
4182 | /*qualifying_scope=*/NULL_TREE); |
4183 | pop_deferring_access_checks (); | |
4184 | } | |
9e95d15f NS |
4185 | else if (is_overloaded_fn (decl)) |
4186 | { | |
348dd384 NS |
4187 | /* We only need to look at the first function, |
4188 | because all the fns share the attribute we're | |
4189 | concerned with (all member fns or all non-members). */ | |
1f0ed17c | 4190 | tree first_fn = get_first_fn (decl); |
348dd384 | 4191 | first_fn = STRIP_TEMPLATE (first_fn); |
415d4636 | 4192 | |
626aeaa7 JM |
4193 | /* [basic.def.odr]: "A function whose name appears as a |
4194 | potentially-evaluated expression is odr-used if it is the unique | |
4195 | lookup result". | |
4196 | ||
4197 | But only mark it if it's a complete postfix-expression; in a call, | |
4198 | ADL might select a different function, and we'll call mark_used in | |
4199 | build_over_call. */ | |
4200 | if (done | |
4201 | && !really_overloaded_fn (decl) | |
9965f21f PC |
4202 | && !mark_used (first_fn)) |
4203 | return error_mark_node; | |
415d4636 | 4204 | |
02ed62dd | 4205 | if (!template_arg_p |
2139fd74 NS |
4206 | && (TREE_CODE (first_fn) == USING_DECL |
4207 | || (TREE_CODE (first_fn) == FUNCTION_DECL | |
4208 | && DECL_FUNCTION_MEMBER_P (first_fn) | |
4209 | && !shared_member_p (decl)))) | |
9e95d15f NS |
4210 | { |
4211 | /* A set of member functions. */ | |
4212 | decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0); | |
02ed62dd | 4213 | return finish_class_member_access_expr (decl, id_expression, |
5ade1ed2 DG |
4214 | /*template_p=*/false, |
4215 | tf_warning_or_error); | |
9e95d15f | 4216 | } |
eff3a276 MM |
4217 | |
4218 | decl = baselink_for_fns (decl); | |
9e95d15f NS |
4219 | } |
4220 | else | |
4221 | { | |
9e95d15f | 4222 | if (DECL_P (decl) && DECL_NONLOCAL (decl) |
24f58e74 | 4223 | && DECL_CLASS_SCOPE_P (decl)) |
9e95d15f | 4224 | { |
43e1e8b5 | 4225 | tree context = context_for_name_lookup (decl); |
24f58e74 PC |
4226 | if (context != current_class_type) |
4227 | { | |
4228 | tree path = currently_open_derived_class (context); | |
d5031040 JM |
4229 | if (!path) |
4230 | /* PATH can be null for using an enum of an unrelated | |
4231 | class; we checked its access in lookup_using_decl. | |
4232 | ||
4233 | ??? Should this case make a clone instead, like | |
4234 | handle_using_decl? */ | |
4235 | gcc_assert (TREE_CODE (decl) == CONST_DECL); | |
4236 | else | |
4237 | perform_or_defer_access_check (TYPE_BINFO (path), | |
4238 | decl, decl, | |
4239 | tf_warning_or_error); | |
24f58e74 | 4240 | } |
9e95d15f | 4241 | } |
c8094d83 | 4242 | |
db24eb1f | 4243 | decl = convert_from_reference (decl); |
9e95d15f | 4244 | } |
b3445994 MM |
4245 | } |
4246 | ||
e87eed2a | 4247 | return cp_expr (decl, location); |
b3445994 MM |
4248 | } |
4249 | ||
dfd7fdca DM |
4250 | /* As per finish_id_expression_1, but adding a wrapper node |
4251 | around the result if needed to express LOCATION. */ | |
4252 | ||
4253 | cp_expr | |
4254 | finish_id_expression (tree id_expression, | |
4255 | tree decl, | |
4256 | tree scope, | |
4257 | cp_id_kind *idk, | |
4258 | bool integral_constant_expression_p, | |
4259 | bool allow_non_integral_constant_expression_p, | |
4260 | bool *non_integral_constant_expression_p, | |
4261 | bool template_p, | |
4262 | bool done, | |
4263 | bool address_p, | |
4264 | bool template_arg_p, | |
4265 | const char **error_msg, | |
4266 | location_t location) | |
4267 | { | |
4268 | cp_expr result | |
4269 | = finish_id_expression_1 (id_expression, decl, scope, idk, | |
4270 | integral_constant_expression_p, | |
4271 | allow_non_integral_constant_expression_p, | |
4272 | non_integral_constant_expression_p, | |
4273 | template_p, done, address_p, template_arg_p, | |
4274 | error_msg, location); | |
4275 | return result.maybe_add_location_wrapper (); | |
4276 | } | |
4277 | ||
0213a355 JM |
4278 | /* Implement the __typeof keyword: Return the type of EXPR, suitable for |
4279 | use as a type-specifier. */ | |
4280 | ||
b894fc05 | 4281 | tree |
3a978d72 | 4282 | finish_typeof (tree expr) |
b894fc05 | 4283 | { |
65a5559b MM |
4284 | tree type; |
4285 | ||
dffbbe80 | 4286 | if (type_dependent_expression_p (expr)) |
b894fc05 | 4287 | { |
9e1e64ec | 4288 | type = cxx_make_type (TYPEOF_TYPE); |
eb34af89 | 4289 | TYPEOF_TYPE_EXPR (type) = expr; |
3ad6a8e1 | 4290 | SET_TYPE_STRUCTURAL_EQUALITY (type); |
b894fc05 | 4291 | |
65a5559b | 4292 | return type; |
b894fc05 JM |
4293 | } |
4294 | ||
03a904b5 JJ |
4295 | expr = mark_type_use (expr); |
4296 | ||
3c38f0ff | 4297 | type = unlowered_expr_type (expr); |
65a5559b MM |
4298 | |
4299 | if (!type || type == unknown_type_node) | |
4300 | { | |
a82e1a7d | 4301 | error ("type of %qE is unknown", expr); |
65a5559b MM |
4302 | return error_mark_node; |
4303 | } | |
4304 | ||
4305 | return type; | |
b894fc05 | 4306 | } |
558475f0 | 4307 | |
a0d260fc PC |
4308 | /* Implement the __underlying_type keyword: Return the underlying |
4309 | type of TYPE, suitable for use as a type-specifier. */ | |
4310 | ||
4311 | tree | |
4312 | finish_underlying_type (tree type) | |
4313 | { | |
4314 | tree underlying_type; | |
4315 | ||
4316 | if (processing_template_decl) | |
4317 | { | |
4318 | underlying_type = cxx_make_type (UNDERLYING_TYPE); | |
4319 | UNDERLYING_TYPE_TYPE (underlying_type) = type; | |
4320 | SET_TYPE_STRUCTURAL_EQUALITY (underlying_type); | |
4321 | ||
4322 | return underlying_type; | |
4323 | } | |
4324 | ||
8fdddd3d MP |
4325 | if (!complete_type_or_else (type, NULL_TREE)) |
4326 | return error_mark_node; | |
a0d260fc PC |
4327 | |
4328 | if (TREE_CODE (type) != ENUMERAL_TYPE) | |
4329 | { | |
ca2507dc | 4330 | error ("%qT is not an enumeration type", type); |
a0d260fc PC |
4331 | return error_mark_node; |
4332 | } | |
4333 | ||
4334 | underlying_type = ENUM_UNDERLYING_TYPE (type); | |
4335 | ||
4336 | /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE | |
4337 | includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information. | |
4338 | See finish_enum_value_list for details. */ | |
4339 | if (!ENUM_FIXED_UNDERLYING_TYPE_P (type)) | |
4340 | underlying_type | |
4341 | = c_common_type_for_mode (TYPE_MODE (underlying_type), | |
4342 | TYPE_UNSIGNED (underlying_type)); | |
4343 | ||
4344 | return underlying_type; | |
4345 | } | |
4346 | ||
4daba884 | 4347 | /* Implement the __direct_bases keyword: Return the direct base classes |
628a1534 | 4348 | of type. */ |
4daba884 BK |
4349 | |
4350 | tree | |
628a1534 | 4351 | calculate_direct_bases (tree type, tsubst_flags_t complain) |
4daba884 | 4352 | { |
628a1534 JJ |
4353 | if (!complete_type_or_maybe_complain (type, NULL_TREE, complain) |
4354 | || !NON_UNION_CLASS_TYPE_P (type)) | |
4daba884 BK |
4355 | return make_tree_vec (0); |
4356 | ||
cd9cf97b | 4357 | releasing_vec vector; |
628a1534 JJ |
4358 | vec<tree, va_gc> *base_binfos = BINFO_BASE_BINFOS (TYPE_BINFO (type)); |
4359 | tree binfo; | |
4360 | unsigned i; | |
4daba884 BK |
4361 | |
4362 | /* Virtual bases are initialized first */ | |
9771b263 | 4363 | for (i = 0; base_binfos->iterate (i, &binfo); i++) |
628a1534 JJ |
4364 | if (BINFO_VIRTUAL_P (binfo)) |
4365 | vec_safe_push (vector, binfo); | |
4daba884 BK |
4366 | |
4367 | /* Now non-virtuals */ | |
9771b263 | 4368 | for (i = 0; base_binfos->iterate (i, &binfo); i++) |
628a1534 JJ |
4369 | if (!BINFO_VIRTUAL_P (binfo)) |
4370 | vec_safe_push (vector, binfo); | |
4daba884 | 4371 | |
628a1534 | 4372 | tree bases_vec = make_tree_vec (vector->length ()); |
4daba884 | 4373 | |
9771b263 | 4374 | for (i = 0; i < vector->length (); ++i) |
628a1534 JJ |
4375 | TREE_VEC_ELT (bases_vec, i) = BINFO_TYPE ((*vector)[i]); |
4376 | ||
4daba884 BK |
4377 | return bases_vec; |
4378 | } | |
4379 | ||
4380 | /* Implement the __bases keyword: Return the base classes | |
4381 | of type */ | |
4382 | ||
4383 | /* Find morally non-virtual base classes by walking binfo hierarchy */ | |
4384 | /* Virtual base classes are handled separately in finish_bases */ | |
4385 | ||
4386 | static tree | |
12308bc6 | 4387 | dfs_calculate_bases_pre (tree binfo, void * /*data_*/) |
4daba884 BK |
4388 | { |
4389 | /* Don't walk bases of virtual bases */ | |
4390 | return BINFO_VIRTUAL_P (binfo) ? dfs_skip_bases : NULL_TREE; | |
4391 | } | |
4392 | ||
4393 | static tree | |
4394 | dfs_calculate_bases_post (tree binfo, void *data_) | |
4395 | { | |
9771b263 | 4396 | vec<tree, va_gc> **data = ((vec<tree, va_gc> **) data_); |
4daba884 | 4397 | if (!BINFO_VIRTUAL_P (binfo)) |
628a1534 | 4398 | vec_safe_push (*data, BINFO_TYPE (binfo)); |
4daba884 BK |
4399 | return NULL_TREE; |
4400 | } | |
4401 | ||
4402 | /* Calculates the morally non-virtual base classes of a class */ | |
9771b263 | 4403 | static vec<tree, va_gc> * |
4daba884 BK |
4404 | calculate_bases_helper (tree type) |
4405 | { | |
628a1534 | 4406 | vec<tree, va_gc> *vector = make_tree_vector (); |
4daba884 BK |
4407 | |
4408 | /* Now add non-virtual base classes in order of construction */ | |
2efc7218 PC |
4409 | if (TYPE_BINFO (type)) |
4410 | dfs_walk_all (TYPE_BINFO (type), | |
4411 | dfs_calculate_bases_pre, dfs_calculate_bases_post, &vector); | |
4daba884 BK |
4412 | return vector; |
4413 | } | |
4414 | ||
4415 | tree | |
628a1534 | 4416 | calculate_bases (tree type, tsubst_flags_t complain) |
4daba884 | 4417 | { |
628a1534 JJ |
4418 | if (!complete_type_or_maybe_complain (type, NULL_TREE, complain) |
4419 | || !NON_UNION_CLASS_TYPE_P (type)) | |
4420 | return make_tree_vec (0); | |
4421 | ||
cd9cf97b | 4422 | releasing_vec vector; |
4daba884 BK |
4423 | tree bases_vec = NULL_TREE; |
4424 | unsigned i; | |
9771b263 | 4425 | vec<tree, va_gc> *vbases; |
4daba884 BK |
4426 | tree binfo; |
4427 | ||
4daba884 BK |
4428 | /* First go through virtual base classes */ |
4429 | for (vbases = CLASSTYPE_VBASECLASSES (type), i = 0; | |
9771b263 | 4430 | vec_safe_iterate (vbases, i, &binfo); i++) |
4daba884 | 4431 | { |
cd9cf97b | 4432 | releasing_vec vbase_bases |
628a1534 | 4433 | = calculate_bases_helper (BINFO_TYPE (binfo)); |
9771b263 | 4434 | vec_safe_splice (vector, vbase_bases); |
4daba884 BK |
4435 | } |
4436 | ||
4437 | /* Now for the non-virtual bases */ | |
cd9cf97b | 4438 | releasing_vec nonvbases = calculate_bases_helper (type); |
9771b263 | 4439 | vec_safe_splice (vector, nonvbases); |
4daba884 | 4440 | |
2efc7218 PC |
4441 | /* Note that during error recovery vector->length can even be zero. */ |
4442 | if (vector->length () > 1) | |
4daba884 | 4443 | { |
2efc7218 | 4444 | /* Last element is entire class, so don't copy */ |
628a1534 | 4445 | bases_vec = make_tree_vec (vector->length () - 1); |
2efc7218 PC |
4446 | |
4447 | for (i = 0; i < vector->length () - 1; ++i) | |
4448 | TREE_VEC_ELT (bases_vec, i) = (*vector)[i]; | |
4daba884 | 4449 | } |
2efc7218 PC |
4450 | else |
4451 | bases_vec = make_tree_vec (0); | |
4452 | ||
4daba884 BK |
4453 | return bases_vec; |
4454 | } | |
4455 | ||
4456 | tree | |
4457 | finish_bases (tree type, bool direct) | |
4458 | { | |
4459 | tree bases = NULL_TREE; | |
4460 | ||
4461 | if (!processing_template_decl) | |
4462 | { | |
4463 | /* Parameter packs can only be used in templates */ | |
a9c697b8 | 4464 | error ("parameter pack %<__bases%> only valid in template declaration"); |
4daba884 BK |
4465 | return error_mark_node; |
4466 | } | |
4467 | ||
4468 | bases = cxx_make_type (BASES); | |
4469 | BASES_TYPE (bases) = type; | |
4470 | BASES_DIRECT (bases) = direct; | |
4471 | SET_TYPE_STRUCTURAL_EQUALITY (bases); | |
4472 | ||
4473 | return bases; | |
4474 | } | |
4475 | ||
c291f8b1 VR |
4476 | /* Perform C++-specific checks for __builtin_offsetof before calling |
4477 | fold_offsetof. */ | |
4478 | ||
4479 | tree | |
905d2812 | 4480 | finish_offsetof (tree object_ptr, tree expr, location_t loc) |
c291f8b1 | 4481 | { |
b433d944 JM |
4482 | /* If we're processing a template, we can't finish the semantics yet. |
4483 | Otherwise we can fold the entire expression now. */ | |
4484 | if (processing_template_decl) | |
4485 | { | |
905d2812 | 4486 | expr = build2 (OFFSETOF_EXPR, size_type_node, expr, object_ptr); |
b433d944 JM |
4487 | SET_EXPR_LOCATION (expr, loc); |
4488 | return expr; | |
4489 | } | |
4490 | ||
b8836dbe JM |
4491 | if (expr == error_mark_node) |
4492 | return error_mark_node; | |
4493 | ||
4c65a534 VR |
4494 | if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR) |
4495 | { | |
4496 | error ("cannot apply %<offsetof%> to destructor %<~%T%>", | |
4497 | TREE_OPERAND (expr, 2)); | |
4498 | return error_mark_node; | |
4499 | } | |
7bdc7e06 | 4500 | if (FUNC_OR_METHOD_TYPE_P (TREE_TYPE (expr)) |
fbfc8363 | 4501 | || TREE_TYPE (expr) == unknown_type_node) |
c291f8b1 | 4502 | { |
e9f59cfa JM |
4503 | while (TREE_CODE (expr) == COMPONENT_REF |
4504 | || TREE_CODE (expr) == COMPOUND_EXPR) | |
4505 | expr = TREE_OPERAND (expr, 1); | |
4506 | ||
4507 | if (DECL_P (expr)) | |
929f647a | 4508 | { |
929f647a | 4509 | error ("cannot apply %<offsetof%> to member function %qD", expr); |
e9f59cfa | 4510 | inform (DECL_SOURCE_LOCATION (expr), "declared here"); |
929f647a | 4511 | } |
e9f59cfa JM |
4512 | else |
4513 | error ("cannot apply %<offsetof%> to member function"); | |
c291f8b1 VR |
4514 | return error_mark_node; |
4515 | } | |
b01556f7 MP |
4516 | if (TREE_CODE (expr) == CONST_DECL) |
4517 | { | |
4518 | error ("cannot apply %<offsetof%> to an enumerator %qD", expr); | |
4519 | return error_mark_node; | |
4520 | } | |
31e292c7 | 4521 | if (REFERENCE_REF_P (expr)) |
60c4d135 | 4522 | expr = TREE_OPERAND (expr, 0); |
905d2812 JJ |
4523 | if (!complete_type_or_else (TREE_TYPE (TREE_TYPE (object_ptr)), object_ptr)) |
4524 | return error_mark_node; | |
4525 | if (warn_invalid_offsetof | |
4526 | && CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (object_ptr))) | |
4527 | && CLASSTYPE_NON_STD_LAYOUT (TREE_TYPE (TREE_TYPE (object_ptr))) | |
4528 | && cp_unevaluated_operand == 0) | |
a9c697b8 | 4529 | warning_at (loc, OPT_Winvalid_offsetof, "%<offsetof%> within " |
e9f59cfa JM |
4530 | "non-standard-layout type %qT is conditionally-supported", |
4531 | TREE_TYPE (TREE_TYPE (object_ptr))); | |
cf9e9959 | 4532 | return fold_offsetof (expr); |
c291f8b1 VR |
4533 | } |
4534 | ||
9eeb200f JM |
4535 | /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This |
4536 | function is broken out from the above for the benefit of the tree-ssa | |
4537 | project. */ | |
4538 | ||
4539 | void | |
4540 | simplify_aggr_init_expr (tree *tp) | |
4541 | { | |
4542 | tree aggr_init_expr = *tp; | |
4543 | ||
3eb24f73 | 4544 | /* Form an appropriate CALL_EXPR. */ |
5039610b SL |
4545 | tree fn = AGGR_INIT_EXPR_FN (aggr_init_expr); |
4546 | tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr); | |
2692eb7d | 4547 | tree type = TREE_TYPE (slot); |
9eeb200f JM |
4548 | |
4549 | tree call_expr; | |
4550 | enum style_t { ctor, arg, pcc } style; | |
4977bab6 | 4551 | |
3eb24f73 | 4552 | if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr)) |
4977bab6 ZW |
4553 | style = ctor; |
4554 | #ifdef PCC_STATIC_STRUCT_RETURN | |
4555 | else if (1) | |
4556 | style = pcc; | |
4557 | #endif | |
4977bab6 | 4558 | else |
315fb5db NS |
4559 | { |
4560 | gcc_assert (TREE_ADDRESSABLE (type)); | |
4561 | style = arg; | |
4562 | } | |
4977bab6 | 4563 | |
db3927fb AH |
4564 | call_expr = build_call_array_loc (input_location, |
4565 | TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), | |
4566 | fn, | |
4567 | aggr_init_expr_nargs (aggr_init_expr), | |
4568 | AGGR_INIT_EXPR_ARGP (aggr_init_expr)); | |
d8a0d13e | 4569 | TREE_NOTHROW (call_expr) = TREE_NOTHROW (aggr_init_expr); |
8ba8c375 | 4570 | CALL_FROM_THUNK_P (call_expr) = AGGR_INIT_FROM_THUNK_P (aggr_init_expr); |
4eb24e01 JM |
4571 | CALL_EXPR_OPERATOR_SYNTAX (call_expr) |
4572 | = CALL_EXPR_OPERATOR_SYNTAX (aggr_init_expr); | |
4573 | CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (aggr_init_expr); | |
4574 | CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (aggr_init_expr); | |
5039610b | 4575 | |
fa47911c | 4576 | if (style == ctor) |
3eb24f73 | 4577 | { |
fa47911c JM |
4578 | /* Replace the first argument to the ctor with the address of the |
4579 | slot. */ | |
dffd7eb6 | 4580 | cxx_mark_addressable (slot); |
5039610b SL |
4581 | CALL_EXPR_ARG (call_expr, 0) = |
4582 | build1 (ADDR_EXPR, build_pointer_type (type), slot); | |
3eb24f73 | 4583 | } |
5039610b | 4584 | else if (style == arg) |
fa47911c JM |
4585 | { |
4586 | /* Just mark it addressable here, and leave the rest to | |
4587 | expand_call{,_inline}. */ | |
4588 | cxx_mark_addressable (slot); | |
4589 | CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true; | |
71d1add3 | 4590 | call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr); |
fa47911c | 4591 | } |
4977bab6 | 4592 | else if (style == pcc) |
3eb24f73 | 4593 | { |
4977bab6 ZW |
4594 | /* If we're using the non-reentrant PCC calling convention, then we |
4595 | need to copy the returned value out of the static buffer into the | |
4596 | SLOT. */ | |
78757caa | 4597 | push_deferring_access_checks (dk_no_check); |
71d1add3 JM |
4598 | call_expr = build_aggr_init (slot, call_expr, |
4599 | DIRECT_BIND | LOOKUP_ONLYCONVERTING, | |
4600 | tf_warning_or_error); | |
78757caa | 4601 | pop_deferring_access_checks (); |
71d1add3 | 4602 | call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot); |
4561285b JM |
4603 | } |
4604 | ||
450a927a JM |
4605 | if (AGGR_INIT_ZERO_FIRST (aggr_init_expr)) |
4606 | { | |
4607 | tree init = build_zero_init (type, NULL_TREE, | |
4608 | /*static_storage_p=*/false); | |
4609 | init = build2 (INIT_EXPR, void_type_node, slot, init); | |
71d1add3 JM |
4610 | call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr), |
4611 | init, call_expr); | |
450a927a JM |
4612 | } |
4613 | ||
71d1add3 | 4614 | *tp = call_expr; |
3eb24f73 MM |
4615 | } |
4616 | ||
31f8e4f3 MM |
4617 | /* Emit all thunks to FN that should be emitted when FN is emitted. */ |
4618 | ||
e89d6010 | 4619 | void |
3a978d72 | 4620 | emit_associated_thunks (tree fn) |
31f8e4f3 MM |
4621 | { |
4622 | /* When we use vcall offsets, we emit thunks with the virtual | |
4623 | functions to which they thunk. The whole point of vcall offsets | |
4624 | is so that you can know statically the entire set of thunks that | |
4625 | will ever be needed for a given virtual function, thereby | |
4626 | enabling you to output all the thunks with the function itself. */ | |
4537ec0c DN |
4627 | if (DECL_VIRTUAL_P (fn) |
4628 | /* Do not emit thunks for extern template instantiations. */ | |
4629 | && ! DECL_REALLY_EXTERN (fn)) | |
31f8e4f3 | 4630 | { |
bb5e8a7f | 4631 | tree thunk; |
c8094d83 | 4632 | |
910ad8de | 4633 | for (thunk = DECL_THUNKS (fn); thunk; thunk = DECL_CHAIN (thunk)) |
4977bab6 | 4634 | { |
e00853fd | 4635 | if (!THUNK_ALIAS (thunk)) |
4977bab6 | 4636 | { |
bb885938 NS |
4637 | use_thunk (thunk, /*emit_p=*/1); |
4638 | if (DECL_RESULT_THUNK_P (thunk)) | |
4639 | { | |
4640 | tree probe; | |
c8094d83 | 4641 | |
bb885938 | 4642 | for (probe = DECL_THUNKS (thunk); |
910ad8de | 4643 | probe; probe = DECL_CHAIN (probe)) |
bb885938 NS |
4644 | use_thunk (probe, /*emit_p=*/1); |
4645 | } | |
4977bab6 | 4646 | } |
bb885938 | 4647 | else |
50bc768d | 4648 | gcc_assert (!DECL_THUNKS (thunk)); |
4977bab6 | 4649 | } |
31f8e4f3 MM |
4650 | } |
4651 | } | |
4652 | ||
558475f0 MM |
4653 | /* Generate RTL for FN. */ |
4654 | ||
b2583345 JJ |
4655 | bool |
4656 | expand_or_defer_fn_1 (tree fn) | |
8cd2462c JH |
4657 | { |
4658 | /* When the parser calls us after finishing the body of a template | |
c353b8e3 MM |
4659 | function, we don't really want to expand the body. */ |
4660 | if (processing_template_decl) | |
8cd2462c JH |
4661 | { |
4662 | /* Normally, collection only occurs in rest_of_compilation. So, | |
4663 | if we don't collect here, we never collect junk generated | |
4664 | during the processing of templates until we hit a | |
27250734 MM |
4665 | non-template function. It's not safe to do this inside a |
4666 | nested class, though, as the parser may have local state that | |
4667 | is not a GC root. */ | |
4668 | if (!function_depth) | |
4669 | ggc_collect (); | |
b2583345 | 4670 | return false; |
8cd2462c JH |
4671 | } |
4672 | ||
a406865a | 4673 | gcc_assert (DECL_SAVED_TREE (fn)); |
726a989a | 4674 | |
4684cd27 MM |
4675 | /* We make a decision about linkage for these functions at the end |
4676 | of the compilation. Until that point, we do not want the back | |
4677 | end to output them -- but we do want it to see the bodies of | |
1a10290c | 4678 | these functions so that it can inline them as appropriate. */ |
4684cd27 MM |
4679 | if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn)) |
4680 | { | |
1ef0df47 MM |
4681 | if (DECL_INTERFACE_KNOWN (fn)) |
4682 | /* We've already made a decision as to how this function will | |
4683 | be handled. */; | |
b3f44388 JJ |
4684 | else if (!at_eof |
4685 | || DECL_IMMEDIATE_FUNCTION_P (fn) | |
4686 | || DECL_OMP_DECLARE_REDUCTION_P (fn)) | |
944b63db | 4687 | tentative_decl_linkage (fn); |
4684cd27 MM |
4688 | else |
4689 | import_export_decl (fn); | |
1a10290c MM |
4690 | |
4691 | /* If the user wants us to keep all inline functions, then mark | |
4692 | this function as needed so that finish_file will make sure to | |
fe2978fb MM |
4693 | output it later. Similarly, all dllexport'd functions must |
4694 | be emitted; there may be callers in other DLLs. */ | |
322d490e KT |
4695 | if (DECL_DECLARED_INLINE_P (fn) |
4696 | && !DECL_REALLY_EXTERN (fn) | |
f968ef9b | 4697 | && !DECL_IMMEDIATE_FUNCTION_P (fn) |
b3f44388 | 4698 | && !DECL_OMP_DECLARE_REDUCTION_P (fn) |
322d490e KT |
4699 | && (flag_keep_inline_functions |
4700 | || (flag_keep_inline_dllexport | |
4701 | && lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn))))) | |
ffca9d53 JM |
4702 | { |
4703 | mark_needed (fn); | |
4704 | DECL_EXTERNAL (fn) = 0; | |
4705 | } | |
4684cd27 MM |
4706 | } |
4707 | ||
1f26ac87 JM |
4708 | /* If this is a constructor or destructor body, we have to clone |
4709 | it. */ | |
4710 | if (maybe_clone_body (fn)) | |
4711 | { | |
4712 | /* We don't want to process FN again, so pretend we've written | |
4713 | it out, even though we haven't. */ | |
4714 | TREE_ASM_WRITTEN (fn) = 1; | |
ca30abcd | 4715 | /* If this is a constexpr function, keep DECL_SAVED_TREE. */ |
cf97b970 NS |
4716 | if (!DECL_DECLARED_CONSTEXPR_P (fn) |
4717 | && !(modules_p () && DECL_DECLARED_INLINE_P (fn))) | |
1f26ac87 JM |
4718 | DECL_SAVED_TREE (fn) = NULL_TREE; |
4719 | return false; | |
4720 | } | |
4721 | ||
8cd2462c JH |
4722 | /* There's no reason to do any of the work here if we're only doing |
4723 | semantic analysis; this code just generates RTL. */ | |
4724 | if (flag_syntax_only) | |
e843f189 JJ |
4725 | { |
4726 | /* Pretend that this function has been written out so that we don't try | |
4727 | to expand it again. */ | |
4728 | TREE_ASM_WRITTEN (fn) = 1; | |
4729 | return false; | |
4730 | } | |
b2583345 | 4731 | |
b3f44388 JJ |
4732 | if (DECL_OMP_DECLARE_REDUCTION_P (fn)) |
4733 | return false; | |
4734 | ||
b2583345 JJ |
4735 | return true; |
4736 | } | |
8cd2462c | 4737 | |
b2583345 JJ |
4738 | void |
4739 | expand_or_defer_fn (tree fn) | |
4740 | { | |
4741 | if (expand_or_defer_fn_1 (fn)) | |
4742 | { | |
4743 | function_depth++; | |
99edd65d | 4744 | |
b2583345 | 4745 | /* Expand or defer, at the whim of the compilation unit manager. */ |
3dafb85c | 4746 | cgraph_node::finalize_function (fn, function_depth > 1); |
6744a6ab | 4747 | emit_associated_thunks (fn); |
99edd65d | 4748 | |
b2583345 JJ |
4749 | function_depth--; |
4750 | } | |
8cd2462c JH |
4751 | } |
4752 | ||
6c1dae73 | 4753 | class nrv_data |
6de9cd9a | 4754 | { |
6c1dae73 | 4755 | public: |
c203e8a7 TS |
4756 | nrv_data () : visited (37) {} |
4757 | ||
6de9cd9a DN |
4758 | tree var; |
4759 | tree result; | |
8d67ee55 | 4760 | hash_table<nofree_ptr_hash <tree_node> > visited; |
6de9cd9a | 4761 | }; |
0d97bf4c | 4762 | |
6de9cd9a DN |
4763 | /* Helper function for walk_tree, used by finalize_nrv below. */ |
4764 | ||
4765 | static tree | |
4766 | finalize_nrv_r (tree* tp, int* walk_subtrees, void* data) | |
0d97bf4c | 4767 | { |
99b1c316 | 4768 | class nrv_data *dp = (class nrv_data *)data; |
703c8606 | 4769 | tree_node **slot; |
07b2f2fd JM |
4770 | |
4771 | /* No need to walk into types. There wouldn't be any need to walk into | |
4772 | non-statements, except that we have to consider STMT_EXPRs. */ | |
0d97bf4c JM |
4773 | if (TYPE_P (*tp)) |
4774 | *walk_subtrees = 0; | |
6de9cd9a DN |
4775 | /* Change all returns to just refer to the RESULT_DECL; this is a nop, |
4776 | but differs from using NULL_TREE in that it indicates that we care | |
4777 | about the value of the RESULT_DECL. */ | |
5088b058 RH |
4778 | else if (TREE_CODE (*tp) == RETURN_EXPR) |
4779 | TREE_OPERAND (*tp, 0) = dp->result; | |
6de9cd9a DN |
4780 | /* Change all cleanups for the NRV to only run when an exception is |
4781 | thrown. */ | |
07b2f2fd | 4782 | else if (TREE_CODE (*tp) == CLEANUP_STMT |
6de9cd9a | 4783 | && CLEANUP_DECL (*tp) == dp->var) |
659e5a7a | 4784 | CLEANUP_EH_ONLY (*tp) = 1; |
350fae66 | 4785 | /* Replace the DECL_EXPR for the NRV with an initialization of the |
6de9cd9a | 4786 | RESULT_DECL, if needed. */ |
350fae66 RK |
4787 | else if (TREE_CODE (*tp) == DECL_EXPR |
4788 | && DECL_EXPR_DECL (*tp) == dp->var) | |
6de9cd9a DN |
4789 | { |
4790 | tree init; | |
4791 | if (DECL_INITIAL (dp->var) | |
4792 | && DECL_INITIAL (dp->var) != error_mark_node) | |
2d188530 JJ |
4793 | init = build2 (INIT_EXPR, void_type_node, dp->result, |
4794 | DECL_INITIAL (dp->var)); | |
6de9cd9a | 4795 | else |
c2255bc4 | 4796 | init = build_empty_stmt (EXPR_LOCATION (*tp)); |
2d188530 | 4797 | DECL_INITIAL (dp->var) = NULL_TREE; |
5e278028 | 4798 | SET_EXPR_LOCATION (init, EXPR_LOCATION (*tp)); |
6de9cd9a DN |
4799 | *tp = init; |
4800 | } | |
4801 | /* And replace all uses of the NRV with the RESULT_DECL. */ | |
4802 | else if (*tp == dp->var) | |
4803 | *tp = dp->result; | |
4804 | ||
4805 | /* Avoid walking into the same tree more than once. Unfortunately, we | |
4806 | can't just use walk_tree_without duplicates because it would only call | |
4807 | us for the first occurrence of dp->var in the function body. */ | |
703c8606 | 4808 | slot = dp->visited.find_slot (*tp, INSERT); |
6de9cd9a DN |
4809 | if (*slot) |
4810 | *walk_subtrees = 0; | |
4811 | else | |
4812 | *slot = *tp; | |
0d97bf4c JM |
4813 | |
4814 | /* Keep iterating. */ | |
4815 | return NULL_TREE; | |
4816 | } | |
4817 | ||
6de9cd9a | 4818 | /* Called from finish_function to implement the named return value |
5088b058 | 4819 | optimization by overriding all the RETURN_EXPRs and pertinent |
6de9cd9a DN |
4820 | CLEANUP_STMTs and replacing all occurrences of VAR with RESULT, the |
4821 | RESULT_DECL for the function. */ | |
f444e36b | 4822 | |
4985cde3 | 4823 | void |
6de9cd9a | 4824 | finalize_nrv (tree *tp, tree var, tree result) |
f444e36b | 4825 | { |
99b1c316 | 4826 | class nrv_data data; |
6de9cd9a | 4827 | |
add86e09 | 4828 | /* Copy name from VAR to RESULT. */ |
6de9cd9a | 4829 | DECL_NAME (result) = DECL_NAME (var); |
6de9cd9a DN |
4830 | /* Don't forget that we take its address. */ |
4831 | TREE_ADDRESSABLE (result) = TREE_ADDRESSABLE (var); | |
add86e09 JJ |
4832 | /* Finally set DECL_VALUE_EXPR to avoid assigning |
4833 | a stack slot at -O0 for the original var and debug info | |
4834 | uses RESULT location for VAR. */ | |
4835 | SET_DECL_VALUE_EXPR (var, result); | |
4836 | DECL_HAS_VALUE_EXPR_P (var) = 1; | |
6de9cd9a DN |
4837 | |
4838 | data.var = var; | |
4839 | data.result = result; | |
14588106 | 4840 | cp_walk_tree (tp, finalize_nrv_r, &data, 0); |
b850de4f | 4841 | } |
1799e5d5 | 4842 | \f |
a68ab351 JJ |
4843 | /* Create CP_OMP_CLAUSE_INFO for clause C. Returns true if it is invalid. */ |
4844 | ||
4845 | bool | |
4846 | cxx_omp_create_clause_info (tree c, tree type, bool need_default_ctor, | |
acf0174b JJ |
4847 | bool need_copy_ctor, bool need_copy_assignment, |
4848 | bool need_dtor) | |
a68ab351 JJ |
4849 | { |
4850 | int save_errorcount = errorcount; | |
4851 | tree info, t; | |
4852 | ||
4853 | /* Always allocate 3 elements for simplicity. These are the | |
4854 | function decls for the ctor, dtor, and assignment op. | |
4855 | This layout is known to the three lang hooks, | |
4856 | cxx_omp_clause_default_init, cxx_omp_clause_copy_init, | |
4857 | and cxx_omp_clause_assign_op. */ | |
4858 | info = make_tree_vec (3); | |
4859 | CP_OMP_CLAUSE_INFO (c) = info; | |
4860 | ||
ac177431 | 4861 | if (need_default_ctor || need_copy_ctor) |
a68ab351 JJ |
4862 | { |
4863 | if (need_default_ctor) | |
ac177431 | 4864 | t = get_default_ctor (type); |
a68ab351 | 4865 | else |
4577f730 | 4866 | t = get_copy_ctor (type, tf_warning_or_error); |
ac177431 JM |
4867 | |
4868 | if (t && !trivial_fn_p (t)) | |
4869 | TREE_VEC_ELT (info, 0) = t; | |
a68ab351 JJ |
4870 | } |
4871 | ||
acf0174b | 4872 | if (need_dtor && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) |
4577f730 | 4873 | TREE_VEC_ELT (info, 1) = get_dtor (type, tf_warning_or_error); |
a68ab351 | 4874 | |
ac177431 | 4875 | if (need_copy_assignment) |
a68ab351 | 4876 | { |
ac177431 JM |
4877 | t = get_copy_assign (type); |
4878 | ||
4879 | if (t && !trivial_fn_p (t)) | |
4880 | TREE_VEC_ELT (info, 2) = t; | |
a68ab351 JJ |
4881 | } |
4882 | ||
4883 | return errorcount != save_errorcount; | |
4884 | } | |
4885 | ||
d9a6bd32 JJ |
4886 | /* If DECL is DECL_OMP_PRIVATIZED_MEMBER, return corresponding |
4887 | FIELD_DECL, otherwise return DECL itself. */ | |
4888 | ||
4889 | static tree | |
4890 | omp_clause_decl_field (tree decl) | |
4891 | { | |
4892 | if (VAR_P (decl) | |
4893 | && DECL_HAS_VALUE_EXPR_P (decl) | |
4894 | && DECL_ARTIFICIAL (decl) | |
4895 | && DECL_LANG_SPECIFIC (decl) | |
4896 | && DECL_OMP_PRIVATIZED_MEMBER (decl)) | |
4897 | { | |
4898 | tree f = DECL_VALUE_EXPR (decl); | |
a7f8415c | 4899 | if (INDIRECT_REF_P (f)) |
d9a6bd32 JJ |
4900 | f = TREE_OPERAND (f, 0); |
4901 | if (TREE_CODE (f) == COMPONENT_REF) | |
4902 | { | |
4903 | f = TREE_OPERAND (f, 1); | |
4904 | gcc_assert (TREE_CODE (f) == FIELD_DECL); | |
4905 | return f; | |
4906 | } | |
4907 | } | |
4908 | return NULL_TREE; | |
4909 | } | |
4910 | ||
4911 | /* Adjust DECL if needed for printing using %qE. */ | |
4912 | ||
4913 | static tree | |
4914 | omp_clause_printable_decl (tree decl) | |
4915 | { | |
4916 | tree t = omp_clause_decl_field (decl); | |
4917 | if (t) | |
4918 | return t; | |
4919 | return decl; | |
4920 | } | |
4921 | ||
4922 | /* For a FIELD_DECL F and corresponding DECL_OMP_PRIVATIZED_MEMBER | |
4923 | VAR_DECL T that doesn't need a DECL_EXPR added, record it for | |
4924 | privatization. */ | |
4925 | ||
4926 | static void | |
4927 | omp_note_field_privatization (tree f, tree t) | |
4928 | { | |
4929 | if (!omp_private_member_map) | |
4930 | omp_private_member_map = new hash_map<tree, tree>; | |
4931 | tree &v = omp_private_member_map->get_or_insert (f); | |
4932 | if (v == NULL_TREE) | |
4933 | { | |
4934 | v = t; | |
4935 | omp_private_member_vec.safe_push (f); | |
4936 | /* Signal that we don't want to create DECL_EXPR for this dummy var. */ | |
4937 | omp_private_member_vec.safe_push (integer_zero_node); | |
4938 | } | |
4939 | } | |
4940 | ||
4941 | /* Privatize FIELD_DECL T, return corresponding DECL_OMP_PRIVATIZED_MEMBER | |
4942 | dummy VAR_DECL. */ | |
4943 | ||
4944 | tree | |
e01d41e5 | 4945 | omp_privatize_field (tree t, bool shared) |
d9a6bd32 JJ |
4946 | { |
4947 | tree m = finish_non_static_data_member (t, NULL_TREE, NULL_TREE); | |
4948 | if (m == error_mark_node) | |
4949 | return error_mark_node; | |
e01d41e5 | 4950 | if (!omp_private_member_map && !shared) |
d9a6bd32 | 4951 | omp_private_member_map = new hash_map<tree, tree>; |
9f613f06 | 4952 | if (TYPE_REF_P (TREE_TYPE (t))) |
d9a6bd32 | 4953 | { |
a7f8415c | 4954 | gcc_assert (INDIRECT_REF_P (m)); |
d9a6bd32 JJ |
4955 | m = TREE_OPERAND (m, 0); |
4956 | } | |
e01d41e5 JJ |
4957 | tree vb = NULL_TREE; |
4958 | tree &v = shared ? vb : omp_private_member_map->get_or_insert (t); | |
d9a6bd32 JJ |
4959 | if (v == NULL_TREE) |
4960 | { | |
4961 | v = create_temporary_var (TREE_TYPE (m)); | |
7187a6c8 | 4962 | retrofit_lang_decl (v); |
d9a6bd32 JJ |
4963 | DECL_OMP_PRIVATIZED_MEMBER (v) = 1; |
4964 | SET_DECL_VALUE_EXPR (v, m); | |
4965 | DECL_HAS_VALUE_EXPR_P (v) = 1; | |
e01d41e5 JJ |
4966 | if (!shared) |
4967 | omp_private_member_vec.safe_push (t); | |
d9a6bd32 JJ |
4968 | } |
4969 | return v; | |
4970 | } | |
4971 | ||
acf0174b JJ |
4972 | /* Helper function for handle_omp_array_sections. Called recursively |
4973 | to handle multiple array-section-subscripts. C is the clause, | |
4974 | T current expression (initially OMP_CLAUSE_DECL), which is either | |
4975 | a TREE_LIST for array-section-subscript (TREE_PURPOSE is low-bound | |
4976 | expression if specified, TREE_VALUE length expression if specified, | |
4977 | TREE_CHAIN is what it has been specified after, or some decl. | |
4978 | TYPES vector is populated with array section types, MAYBE_ZERO_LEN | |
4979 | set to true if any of the array-section-subscript could have length | |
4980 | of zero (explicit or implicit), FIRST_NON_ONE is the index of the | |
4981 | first array-section-subscript which is known not to have length | |
4982 | of one. Given say: | |
4983 | map(a[:b][2:1][:c][:2][:d][e:f][2:5]) | |
4984 | FIRST_NON_ONE will be 3, array-section-subscript [:b], [2:1] and [:c] | |
4985 | all are or may have length of 1, array-section-subscript [:2] is the | |
d9a6bd32 | 4986 | first one known not to have length 1. For array-section-subscript |
acf0174b JJ |
4987 | <= FIRST_NON_ONE we diagnose non-contiguous arrays if low bound isn't |
4988 | 0 or length isn't the array domain max + 1, for > FIRST_NON_ONE we | |
4989 | can if MAYBE_ZERO_LEN is false. MAYBE_ZERO_LEN will be true in the above | |
4990 | case though, as some lengths could be zero. */ | |
4991 | ||
4992 | static tree | |
4993 | handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types, | |
d9a6bd32 | 4994 | bool &maybe_zero_len, unsigned int &first_non_one, |
e46c7770 | 4995 | enum c_omp_region_type ort) |
acf0174b JJ |
4996 | { |
4997 | tree ret, low_bound, length, type; | |
4998 | if (TREE_CODE (t) != TREE_LIST) | |
4999 | { | |
5000 | if (error_operand_p (t)) | |
5001 | return error_mark_node; | |
d9a6bd32 JJ |
5002 | if (REFERENCE_REF_P (t) |
5003 | && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF) | |
5004 | t = TREE_OPERAND (t, 0); | |
5005 | ret = t; | |
5006 | if (TREE_CODE (t) == COMPONENT_REF | |
d9a6bd32 JJ |
5007 | && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
5008 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO | |
5009 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FROM) | |
5010 | && !type_dependent_expression_p (t)) | |
5011 | { | |
9b6a8d0f JJ |
5012 | if (TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL |
5013 | && DECL_BIT_FIELD (TREE_OPERAND (t, 1))) | |
d9a6bd32 JJ |
5014 | { |
5015 | error_at (OMP_CLAUSE_LOCATION (c), | |
5016 | "bit-field %qE in %qs clause", | |
5017 | t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5018 | return error_mark_node; | |
5019 | } | |
5020 | while (TREE_CODE (t) == COMPONENT_REF) | |
5021 | { | |
9b6a8d0f JJ |
5022 | if (TREE_TYPE (TREE_OPERAND (t, 0)) |
5023 | && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE) | |
d9a6bd32 JJ |
5024 | { |
5025 | error_at (OMP_CLAUSE_LOCATION (c), | |
5026 | "%qE is a member of a union", t); | |
5027 | return error_mark_node; | |
5028 | } | |
5029 | t = TREE_OPERAND (t, 0); | |
519d7496 JB |
5030 | if (ort == C_ORT_ACC && TREE_CODE (t) == INDIRECT_REF) |
5031 | t = TREE_OPERAND (t, 0); | |
d9a6bd32 | 5032 | } |
9b6a8d0f JJ |
5033 | if (REFERENCE_REF_P (t)) |
5034 | t = TREE_OPERAND (t, 0); | |
d9a6bd32 | 5035 | } |
098f4e98 JJ |
5036 | if (TREE_CODE (t) == FIELD_DECL |
5037 | && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY | |
5038 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)) | |
5039 | ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE); | |
5040 | else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
acf0174b | 5041 | { |
cb8d1b01 | 5042 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
acf0174b JJ |
5043 | return NULL_TREE; |
5044 | if (DECL_P (t)) | |
5045 | error_at (OMP_CLAUSE_LOCATION (c), | |
5046 | "%qD is not a variable in %qs clause", t, | |
5047 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5048 | else | |
5049 | error_at (OMP_CLAUSE_LOCATION (c), | |
5050 | "%qE is not a variable in %qs clause", t, | |
5051 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5052 | return error_mark_node; | |
5053 | } | |
7619d334 | 5054 | else if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP |
87a5ccfb | 5055 | && TREE_CODE (t) == PARM_DECL |
d9a6bd32 | 5056 | && DECL_ARTIFICIAL (t) |
098f4e98 JJ |
5057 | && DECL_NAME (t) == this_identifier |
5058 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY | |
5059 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND) | |
d9a6bd32 JJ |
5060 | { |
5061 | error_at (OMP_CLAUSE_LOCATION (c), | |
5062 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
5063 | " clauses"); | |
5064 | return error_mark_node; | |
5065 | } | |
9a5de4d5 TB |
5066 | else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY |
5067 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND | |
3048c0c7 | 5068 | && VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) |
acf0174b JJ |
5069 | { |
5070 | error_at (OMP_CLAUSE_LOCATION (c), | |
5071 | "%qD is threadprivate variable in %qs clause", t, | |
5072 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5073 | return error_mark_node; | |
5074 | } | |
d9a6bd32 | 5075 | if (type_dependent_expression_p (ret)) |
7da8534d | 5076 | return NULL_TREE; |
d9a6bd32 JJ |
5077 | ret = convert_from_reference (ret); |
5078 | return ret; | |
acf0174b JJ |
5079 | } |
5080 | ||
7619d334 | 5081 | if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP |
28567c40 JJ |
5082 | && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5083 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5084 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 | 5085 | && TREE_CODE (TREE_CHAIN (t)) == FIELD_DECL) |
e01d41e5 | 5086 | TREE_CHAIN (t) = omp_privatize_field (TREE_CHAIN (t), false); |
acf0174b | 5087 | ret = handle_omp_array_sections_1 (c, TREE_CHAIN (t), types, |
e46c7770 | 5088 | maybe_zero_len, first_non_one, ort); |
acf0174b JJ |
5089 | if (ret == error_mark_node || ret == NULL_TREE) |
5090 | return ret; | |
5091 | ||
5092 | type = TREE_TYPE (ret); | |
5093 | low_bound = TREE_PURPOSE (t); | |
5094 | length = TREE_VALUE (t); | |
5095 | if ((low_bound && type_dependent_expression_p (low_bound)) | |
5096 | || (length && type_dependent_expression_p (length))) | |
5097 | return NULL_TREE; | |
5098 | ||
5099 | if (low_bound == error_mark_node || length == error_mark_node) | |
5100 | return error_mark_node; | |
5101 | ||
5102 | if (low_bound && !INTEGRAL_TYPE_P (TREE_TYPE (low_bound))) | |
5103 | { | |
5104 | error_at (OMP_CLAUSE_LOCATION (c), | |
5105 | "low bound %qE of array section does not have integral type", | |
5106 | low_bound); | |
5107 | return error_mark_node; | |
5108 | } | |
5109 | if (length && !INTEGRAL_TYPE_P (TREE_TYPE (length))) | |
5110 | { | |
5111 | error_at (OMP_CLAUSE_LOCATION (c), | |
5112 | "length %qE of array section does not have integral type", | |
5113 | length); | |
5114 | return error_mark_node; | |
5115 | } | |
d90c0a59 JJ |
5116 | if (low_bound) |
5117 | low_bound = mark_rvalue_use (low_bound); | |
5118 | if (length) | |
5119 | length = mark_rvalue_use (length); | |
cda0a029 JM |
5120 | /* We need to reduce to real constant-values for checks below. */ |
5121 | if (length) | |
5122 | length = fold_simple (length); | |
5123 | if (low_bound) | |
5124 | low_bound = fold_simple (low_bound); | |
acf0174b JJ |
5125 | if (low_bound |
5126 | && TREE_CODE (low_bound) == INTEGER_CST | |
5127 | && TYPE_PRECISION (TREE_TYPE (low_bound)) | |
5128 | > TYPE_PRECISION (sizetype)) | |
5129 | low_bound = fold_convert (sizetype, low_bound); | |
5130 | if (length | |
5131 | && TREE_CODE (length) == INTEGER_CST | |
5132 | && TYPE_PRECISION (TREE_TYPE (length)) | |
5133 | > TYPE_PRECISION (sizetype)) | |
5134 | length = fold_convert (sizetype, length); | |
5135 | if (low_bound == NULL_TREE) | |
5136 | low_bound = integer_zero_node; | |
5137 | ||
519d7496 JB |
5138 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
5139 | && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH | |
5140 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)) | |
5141 | { | |
5142 | if (length != integer_one_node) | |
5143 | { | |
5144 | error_at (OMP_CLAUSE_LOCATION (c), | |
5145 | "expected single pointer in %qs clause", | |
5146 | c_omp_map_clause_name (c, ort == C_ORT_ACC)); | |
5147 | return error_mark_node; | |
5148 | } | |
5149 | } | |
acf0174b JJ |
5150 | if (length != NULL_TREE) |
5151 | { | |
5152 | if (!integer_nonzerop (length)) | |
d9a6bd32 | 5153 | { |
9a5de4d5 TB |
5154 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY |
5155 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND | |
28567c40 JJ |
5156 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5157 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5158 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 JJ |
5159 | { |
5160 | if (integer_zerop (length)) | |
5161 | { | |
5162 | error_at (OMP_CLAUSE_LOCATION (c), | |
5163 | "zero length array section in %qs clause", | |
5164 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5165 | return error_mark_node; | |
5166 | } | |
5167 | } | |
5168 | else | |
5169 | maybe_zero_len = true; | |
5170 | } | |
acf0174b JJ |
5171 | if (first_non_one == types.length () |
5172 | && (TREE_CODE (length) != INTEGER_CST || integer_onep (length))) | |
5173 | first_non_one++; | |
5174 | } | |
5175 | if (TREE_CODE (type) == ARRAY_TYPE) | |
5176 | { | |
5177 | if (length == NULL_TREE | |
5178 | && (TYPE_DOMAIN (type) == NULL_TREE | |
5179 | || TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL_TREE)) | |
5180 | { | |
5181 | error_at (OMP_CLAUSE_LOCATION (c), | |
5182 | "for unknown bound array type length expression must " | |
5183 | "be specified"); | |
5184 | return error_mark_node; | |
5185 | } | |
5186 | if (TREE_CODE (low_bound) == INTEGER_CST | |
5187 | && tree_int_cst_sgn (low_bound) == -1) | |
5188 | { | |
5189 | error_at (OMP_CLAUSE_LOCATION (c), | |
5190 | "negative low bound in array section in %qs clause", | |
5191 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5192 | return error_mark_node; | |
5193 | } | |
5194 | if (length != NULL_TREE | |
5195 | && TREE_CODE (length) == INTEGER_CST | |
5196 | && tree_int_cst_sgn (length) == -1) | |
5197 | { | |
5198 | error_at (OMP_CLAUSE_LOCATION (c), | |
5199 | "negative length in array section in %qs clause", | |
5200 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5201 | return error_mark_node; | |
5202 | } | |
5203 | if (TYPE_DOMAIN (type) | |
5204 | && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) | |
5205 | && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) | |
5206 | == INTEGER_CST) | |
5207 | { | |
8ab7005b JJ |
5208 | tree size |
5209 | = fold_convert (sizetype, TYPE_MAX_VALUE (TYPE_DOMAIN (type))); | |
5210 | size = size_binop (PLUS_EXPR, size, size_one_node); | |
acf0174b JJ |
5211 | if (TREE_CODE (low_bound) == INTEGER_CST) |
5212 | { | |
5213 | if (tree_int_cst_lt (size, low_bound)) | |
5214 | { | |
5215 | error_at (OMP_CLAUSE_LOCATION (c), | |
5216 | "low bound %qE above array section size " | |
5217 | "in %qs clause", low_bound, | |
5218 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5219 | return error_mark_node; | |
5220 | } | |
5221 | if (tree_int_cst_equal (size, low_bound)) | |
d9a6bd32 | 5222 | { |
9a5de4d5 TB |
5223 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY |
5224 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND | |
28567c40 JJ |
5225 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5226 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5227 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 JJ |
5228 | { |
5229 | error_at (OMP_CLAUSE_LOCATION (c), | |
5230 | "zero length array section in %qs clause", | |
5231 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5232 | return error_mark_node; | |
5233 | } | |
5234 | maybe_zero_len = true; | |
5235 | } | |
acf0174b JJ |
5236 | else if (length == NULL_TREE |
5237 | && first_non_one == types.length () | |
5238 | && tree_int_cst_equal | |
5239 | (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), | |
5240 | low_bound)) | |
5241 | first_non_one++; | |
5242 | } | |
5243 | else if (length == NULL_TREE) | |
5244 | { | |
9a5de4d5 TB |
5245 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY |
5246 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND | |
28567c40 JJ |
5247 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION |
5248 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION | |
5249 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 | 5250 | maybe_zero_len = true; |
acf0174b JJ |
5251 | if (first_non_one == types.length ()) |
5252 | first_non_one++; | |
5253 | } | |
5254 | if (length && TREE_CODE (length) == INTEGER_CST) | |
5255 | { | |
5256 | if (tree_int_cst_lt (size, length)) | |
5257 | { | |
5258 | error_at (OMP_CLAUSE_LOCATION (c), | |
5259 | "length %qE above array section size " | |
5260 | "in %qs clause", length, | |
5261 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5262 | return error_mark_node; | |
5263 | } | |
5264 | if (TREE_CODE (low_bound) == INTEGER_CST) | |
5265 | { | |
5266 | tree lbpluslen | |
5267 | = size_binop (PLUS_EXPR, | |
5268 | fold_convert (sizetype, low_bound), | |
5269 | fold_convert (sizetype, length)); | |
5270 | if (TREE_CODE (lbpluslen) == INTEGER_CST | |
5271 | && tree_int_cst_lt (size, lbpluslen)) | |
5272 | { | |
5273 | error_at (OMP_CLAUSE_LOCATION (c), | |
5274 | "high bound %qE above array section size " | |
5275 | "in %qs clause", lbpluslen, | |
5276 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5277 | return error_mark_node; | |
5278 | } | |
5279 | } | |
5280 | } | |
5281 | } | |
5282 | else if (length == NULL_TREE) | |
5283 | { | |
9a5de4d5 TB |
5284 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY |
5285 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND | |
28567c40 JJ |
5286 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION |
5287 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IN_REDUCTION | |
5288 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 | 5289 | maybe_zero_len = true; |
acf0174b JJ |
5290 | if (first_non_one == types.length ()) |
5291 | first_non_one++; | |
5292 | } | |
5293 | ||
5294 | /* For [lb:] we will need to evaluate lb more than once. */ | |
5295 | if (length == NULL_TREE && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND) | |
5296 | { | |
5297 | tree lb = cp_save_expr (low_bound); | |
5298 | if (lb != low_bound) | |
5299 | { | |
5300 | TREE_PURPOSE (t) = lb; | |
5301 | low_bound = lb; | |
5302 | } | |
5303 | } | |
5304 | } | |
9f613f06 | 5305 | else if (TYPE_PTR_P (type)) |
acf0174b JJ |
5306 | { |
5307 | if (length == NULL_TREE) | |
5308 | { | |
a37b0ccc | 5309 | if (TREE_CODE (ret) == PARM_DECL && DECL_ARRAY_PARAMETER_P (ret)) |
3d5ed337 TB |
5310 | error_at (OMP_CLAUSE_LOCATION (c), |
5311 | "for array function parameter length expression " | |
5312 | "must be specified"); | |
5313 | else | |
5314 | error_at (OMP_CLAUSE_LOCATION (c), | |
5315 | "for pointer type length expression must be specified"); | |
acf0174b JJ |
5316 | return error_mark_node; |
5317 | } | |
d9a6bd32 JJ |
5318 | if (length != NULL_TREE |
5319 | && TREE_CODE (length) == INTEGER_CST | |
5320 | && tree_int_cst_sgn (length) == -1) | |
5321 | { | |
5322 | error_at (OMP_CLAUSE_LOCATION (c), | |
5323 | "negative length in array section in %qs clause", | |
5324 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5325 | return error_mark_node; | |
5326 | } | |
acf0174b JJ |
5327 | /* If there is a pointer type anywhere but in the very first |
5328 | array-section-subscript, the array section can't be contiguous. */ | |
9a5de4d5 TB |
5329 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY |
5330 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND | |
acf0174b JJ |
5331 | && TREE_CODE (TREE_CHAIN (t)) == TREE_LIST) |
5332 | { | |
5333 | error_at (OMP_CLAUSE_LOCATION (c), | |
5334 | "array section is not contiguous in %qs clause", | |
5335 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
5336 | return error_mark_node; | |
5337 | } | |
5338 | } | |
5339 | else | |
5340 | { | |
5341 | error_at (OMP_CLAUSE_LOCATION (c), | |
5342 | "%qE does not have pointer or array type", ret); | |
5343 | return error_mark_node; | |
5344 | } | |
5345 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND) | |
5346 | types.safe_push (TREE_TYPE (ret)); | |
5347 | /* We will need to evaluate lb more than once. */ | |
5348 | tree lb = cp_save_expr (low_bound); | |
5349 | if (lb != low_bound) | |
5350 | { | |
5351 | TREE_PURPOSE (t) = lb; | |
5352 | low_bound = lb; | |
5353 | } | |
1a37b6d9 JJ |
5354 | /* Temporarily disable -fstrong-eval-order for array reductions. |
5355 | The SAVE_EXPR and COMPOUND_EXPR added if low_bound has side-effects | |
5356 | is something the middle-end can't cope with and more importantly, | |
5357 | it needs to be the actual base variable that is privatized, not some | |
5358 | temporary assigned previous value of it. That, together with OpenMP | |
5359 | saying how many times the side-effects are evaluated is unspecified, | |
5360 | makes int *a, *b; ... reduction(+:a[a = b, 3:10]) really unspecified. */ | |
5361 | warning_sentinel s (flag_strong_eval_order, | |
f1cb5c0a JJ |
5362 | OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5363 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5364 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION); | |
acf0174b JJ |
5365 | ret = grok_array_decl (OMP_CLAUSE_LOCATION (c), ret, low_bound, false); |
5366 | return ret; | |
5367 | } | |
5368 | ||
5369 | /* Handle array sections for clause C. */ | |
5370 | ||
5371 | static bool | |
e46c7770 | 5372 | handle_omp_array_sections (tree c, enum c_omp_region_type ort) |
acf0174b JJ |
5373 | { |
5374 | bool maybe_zero_len = false; | |
5375 | unsigned int first_non_one = 0; | |
d9a6bd32 | 5376 | auto_vec<tree, 10> types; |
28567c40 | 5377 | tree *tp = &OMP_CLAUSE_DECL (c); |
9a5de4d5 TB |
5378 | if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND |
5379 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) | |
28567c40 JJ |
5380 | && TREE_CODE (*tp) == TREE_LIST |
5381 | && TREE_PURPOSE (*tp) | |
5382 | && TREE_CODE (TREE_PURPOSE (*tp)) == TREE_VEC) | |
5383 | tp = &TREE_VALUE (*tp); | |
5384 | tree first = handle_omp_array_sections_1 (c, *tp, types, | |
d9a6bd32 | 5385 | maybe_zero_len, first_non_one, |
e46c7770 | 5386 | ort); |
acf0174b | 5387 | if (first == error_mark_node) |
ef062b13 | 5388 | return true; |
acf0174b | 5389 | if (first == NULL_TREE) |
ef062b13 | 5390 | return false; |
9a5de4d5 TB |
5391 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND |
5392 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY) | |
acf0174b | 5393 | { |
28567c40 | 5394 | tree t = *tp; |
acf0174b | 5395 | tree tem = NULL_TREE; |
acf0174b JJ |
5396 | if (processing_template_decl) |
5397 | return false; | |
5398 | /* Need to evaluate side effects in the length expressions | |
5399 | if any. */ | |
5400 | while (TREE_CODE (t) == TREE_LIST) | |
5401 | { | |
5402 | if (TREE_VALUE (t) && TREE_SIDE_EFFECTS (TREE_VALUE (t))) | |
5403 | { | |
5404 | if (tem == NULL_TREE) | |
5405 | tem = TREE_VALUE (t); | |
5406 | else | |
5407 | tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), | |
5408 | TREE_VALUE (t), tem); | |
5409 | } | |
5410 | t = TREE_CHAIN (t); | |
5411 | } | |
5412 | if (tem) | |
5413 | first = build2 (COMPOUND_EXPR, TREE_TYPE (first), tem, first); | |
28567c40 | 5414 | *tp = first; |
acf0174b JJ |
5415 | } |
5416 | else | |
5417 | { | |
5418 | unsigned int num = types.length (), i; | |
5419 | tree t, side_effects = NULL_TREE, size = NULL_TREE; | |
5420 | tree condition = NULL_TREE; | |
5421 | ||
5422 | if (int_size_in_bytes (TREE_TYPE (first)) <= 0) | |
5423 | maybe_zero_len = true; | |
5424 | if (processing_template_decl && maybe_zero_len) | |
ef062b13 | 5425 | return false; |
acf0174b JJ |
5426 | |
5427 | for (i = num, t = OMP_CLAUSE_DECL (c); i > 0; | |
5428 | t = TREE_CHAIN (t)) | |
5429 | { | |
5430 | tree low_bound = TREE_PURPOSE (t); | |
5431 | tree length = TREE_VALUE (t); | |
5432 | ||
5433 | i--; | |
5434 | if (low_bound | |
5435 | && TREE_CODE (low_bound) == INTEGER_CST | |
5436 | && TYPE_PRECISION (TREE_TYPE (low_bound)) | |
5437 | > TYPE_PRECISION (sizetype)) | |
5438 | low_bound = fold_convert (sizetype, low_bound); | |
5439 | if (length | |
5440 | && TREE_CODE (length) == INTEGER_CST | |
5441 | && TYPE_PRECISION (TREE_TYPE (length)) | |
5442 | > TYPE_PRECISION (sizetype)) | |
5443 | length = fold_convert (sizetype, length); | |
5444 | if (low_bound == NULL_TREE) | |
5445 | low_bound = integer_zero_node; | |
5446 | if (!maybe_zero_len && i > first_non_one) | |
5447 | { | |
5448 | if (integer_nonzerop (low_bound)) | |
5449 | goto do_warn_noncontiguous; | |
5450 | if (length != NULL_TREE | |
5451 | && TREE_CODE (length) == INTEGER_CST | |
5452 | && TYPE_DOMAIN (types[i]) | |
5453 | && TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])) | |
5454 | && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (types[i]))) | |
5455 | == INTEGER_CST) | |
5456 | { | |
5457 | tree size; | |
5458 | size = size_binop (PLUS_EXPR, | |
5459 | TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])), | |
5460 | size_one_node); | |
5461 | if (!tree_int_cst_equal (length, size)) | |
5462 | { | |
5463 | do_warn_noncontiguous: | |
5464 | error_at (OMP_CLAUSE_LOCATION (c), | |
5465 | "array section is not contiguous in %qs " | |
5466 | "clause", | |
5467 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
5468 | return true; |
5469 | } | |
5470 | } | |
5471 | if (!processing_template_decl | |
5472 | && length != NULL_TREE | |
5473 | && TREE_SIDE_EFFECTS (length)) | |
5474 | { | |
5475 | if (side_effects == NULL_TREE) | |
5476 | side_effects = length; | |
5477 | else | |
5478 | side_effects = build2 (COMPOUND_EXPR, | |
5479 | TREE_TYPE (side_effects), | |
5480 | length, side_effects); | |
5481 | } | |
5482 | } | |
5483 | else if (processing_template_decl) | |
5484 | continue; | |
5485 | else | |
5486 | { | |
5487 | tree l; | |
5488 | ||
d9a6bd32 JJ |
5489 | if (i > first_non_one |
5490 | && ((length && integer_nonzerop (length)) | |
28567c40 JJ |
5491 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5492 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5493 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION)) | |
acf0174b JJ |
5494 | continue; |
5495 | if (length) | |
5496 | l = fold_convert (sizetype, length); | |
5497 | else | |
5498 | { | |
5499 | l = size_binop (PLUS_EXPR, | |
5500 | TYPE_MAX_VALUE (TYPE_DOMAIN (types[i])), | |
5501 | size_one_node); | |
5502 | l = size_binop (MINUS_EXPR, l, | |
5503 | fold_convert (sizetype, low_bound)); | |
5504 | } | |
5505 | if (i > first_non_one) | |
5506 | { | |
5507 | l = fold_build2 (NE_EXPR, boolean_type_node, l, | |
5508 | size_zero_node); | |
5509 | if (condition == NULL_TREE) | |
5510 | condition = l; | |
5511 | else | |
5512 | condition = fold_build2 (BIT_AND_EXPR, boolean_type_node, | |
5513 | l, condition); | |
5514 | } | |
5515 | else if (size == NULL_TREE) | |
5516 | { | |
5517 | size = size_in_bytes (TREE_TYPE (types[i])); | |
d9a6bd32 JJ |
5518 | tree eltype = TREE_TYPE (types[num - 1]); |
5519 | while (TREE_CODE (eltype) == ARRAY_TYPE) | |
5520 | eltype = TREE_TYPE (eltype); | |
28567c40 JJ |
5521 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5522 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5523 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 JJ |
5524 | size = size_binop (EXACT_DIV_EXPR, size, |
5525 | size_in_bytes (eltype)); | |
acf0174b JJ |
5526 | size = size_binop (MULT_EXPR, size, l); |
5527 | if (condition) | |
5528 | size = fold_build3 (COND_EXPR, sizetype, condition, | |
5529 | size, size_zero_node); | |
5530 | } | |
5531 | else | |
5532 | size = size_binop (MULT_EXPR, size, l); | |
5533 | } | |
5534 | } | |
acf0174b JJ |
5535 | if (!processing_template_decl) |
5536 | { | |
5537 | if (side_effects) | |
5538 | size = build2 (COMPOUND_EXPR, sizetype, side_effects, size); | |
28567c40 JJ |
5539 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
5540 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
5541 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
d9a6bd32 JJ |
5542 | { |
5543 | size = size_binop (MINUS_EXPR, size, size_one_node); | |
28567c40 | 5544 | size = save_expr (size); |
d9a6bd32 JJ |
5545 | tree index_type = build_index_type (size); |
5546 | tree eltype = TREE_TYPE (first); | |
5547 | while (TREE_CODE (eltype) == ARRAY_TYPE) | |
5548 | eltype = TREE_TYPE (eltype); | |
5549 | tree type = build_array_type (eltype, index_type); | |
5550 | tree ptype = build_pointer_type (eltype); | |
9f613f06 | 5551 | if (TYPE_REF_P (TREE_TYPE (t)) |
71a93b08 | 5552 | && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t)))) |
d9a6bd32 JJ |
5553 | t = convert_from_reference (t); |
5554 | else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) | |
5555 | t = build_fold_addr_expr (t); | |
e01d41e5 JJ |
5556 | tree t2 = build_fold_addr_expr (first); |
5557 | t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c), | |
5558 | ptrdiff_type_node, t2); | |
5559 | t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR, | |
5560 | ptrdiff_type_node, t2, | |
5561 | fold_convert_loc (OMP_CLAUSE_LOCATION (c), | |
5562 | ptrdiff_type_node, t)); | |
5563 | if (tree_fits_shwi_p (t2)) | |
5564 | t = build2 (MEM_REF, type, t, | |
5565 | build_int_cst (ptype, tree_to_shwi (t2))); | |
5566 | else | |
5567 | { | |
5568 | t2 = fold_convert_loc (OMP_CLAUSE_LOCATION (c), | |
5569 | sizetype, t2); | |
5570 | t = build2_loc (OMP_CLAUSE_LOCATION (c), POINTER_PLUS_EXPR, | |
5571 | TREE_TYPE (t), t, t2); | |
5572 | t = build2 (MEM_REF, type, t, build_int_cst (ptype, 0)); | |
5573 | } | |
d9a6bd32 JJ |
5574 | OMP_CLAUSE_DECL (c) = t; |
5575 | return false; | |
5576 | } | |
acf0174b JJ |
5577 | OMP_CLAUSE_DECL (c) = first; |
5578 | OMP_CLAUSE_SIZE (c) = size; | |
d9a6bd32 JJ |
5579 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP |
5580 | || (TREE_CODE (t) == COMPONENT_REF | |
5581 | && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)) | |
acf0174b | 5582 | return false; |
7619d334 JJ |
5583 | switch (OMP_CLAUSE_MAP_KIND (c)) |
5584 | { | |
5585 | case GOMP_MAP_ALLOC: | |
5586 | case GOMP_MAP_IF_PRESENT: | |
5587 | case GOMP_MAP_TO: | |
5588 | case GOMP_MAP_FROM: | |
5589 | case GOMP_MAP_TOFROM: | |
5590 | case GOMP_MAP_ALWAYS_TO: | |
5591 | case GOMP_MAP_ALWAYS_FROM: | |
5592 | case GOMP_MAP_ALWAYS_TOFROM: | |
5593 | case GOMP_MAP_RELEASE: | |
5594 | case GOMP_MAP_DELETE: | |
5595 | case GOMP_MAP_FORCE_TO: | |
5596 | case GOMP_MAP_FORCE_FROM: | |
5597 | case GOMP_MAP_FORCE_TOFROM: | |
5598 | case GOMP_MAP_FORCE_PRESENT: | |
5599 | OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION (c) = 1; | |
5600 | break; | |
5601 | default: | |
5602 | break; | |
5603 | } | |
acf0174b JJ |
5604 | tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), |
5605 | OMP_CLAUSE_MAP); | |
7619d334 | 5606 | if (TREE_CODE (t) == COMPONENT_REF) |
9e628024 | 5607 | OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH); |
e01d41e5 JJ |
5608 | else if (REFERENCE_REF_P (t) |
5609 | && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF) | |
5610 | { | |
5611 | t = TREE_OPERAND (t, 0); | |
519d7496 JB |
5612 | gomp_map_kind k = (ort == C_ORT_ACC) ? GOMP_MAP_ATTACH_DETACH |
5613 | : GOMP_MAP_ALWAYS_POINTER; | |
5614 | OMP_CLAUSE_SET_MAP_KIND (c2, k); | |
e01d41e5 JJ |
5615 | } |
5616 | else | |
5617 | OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_FIRSTPRIVATE_POINTER); | |
c94424b0 | 5618 | OMP_CLAUSE_MAP_IMPLICIT (c2) = OMP_CLAUSE_MAP_IMPLICIT (c); |
e01d41e5 JJ |
5619 | if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER |
5620 | && !cxx_mark_addressable (t)) | |
acf0174b JJ |
5621 | return false; |
5622 | OMP_CLAUSE_DECL (c2) = t; | |
5623 | t = build_fold_addr_expr (first); | |
5624 | t = fold_convert_loc (OMP_CLAUSE_LOCATION (c), | |
5625 | ptrdiff_type_node, t); | |
5626 | tree ptr = OMP_CLAUSE_DECL (c2); | |
5627 | ptr = convert_from_reference (ptr); | |
71a93b08 | 5628 | if (!INDIRECT_TYPE_P (TREE_TYPE (ptr))) |
acf0174b JJ |
5629 | ptr = build_fold_addr_expr (ptr); |
5630 | t = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR, | |
5631 | ptrdiff_type_node, t, | |
5632 | fold_convert_loc (OMP_CLAUSE_LOCATION (c), | |
5633 | ptrdiff_type_node, ptr)); | |
5634 | OMP_CLAUSE_SIZE (c2) = t; | |
5635 | OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c); | |
5636 | OMP_CLAUSE_CHAIN (c) = c2; | |
5637 | ptr = OMP_CLAUSE_DECL (c2); | |
e01d41e5 | 5638 | if (OMP_CLAUSE_MAP_KIND (c2) != GOMP_MAP_FIRSTPRIVATE_POINTER |
9f613f06 | 5639 | && TYPE_REF_P (TREE_TYPE (ptr)) |
71a93b08 | 5640 | && INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (ptr)))) |
acf0174b JJ |
5641 | { |
5642 | tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), | |
5643 | OMP_CLAUSE_MAP); | |
e01d41e5 | 5644 | OMP_CLAUSE_SET_MAP_KIND (c3, OMP_CLAUSE_MAP_KIND (c2)); |
c94424b0 | 5645 | OMP_CLAUSE_MAP_IMPLICIT (c2) = OMP_CLAUSE_MAP_IMPLICIT (c); |
acf0174b | 5646 | OMP_CLAUSE_DECL (c3) = ptr; |
9e628024 CLT |
5647 | if (OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ALWAYS_POINTER |
5648 | || OMP_CLAUSE_MAP_KIND (c2) == GOMP_MAP_ATTACH_DETACH) | |
5649 | { | |
5650 | OMP_CLAUSE_DECL (c2) = build_simple_mem_ref (ptr); | |
5651 | OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ALWAYS_POINTER); | |
5652 | } | |
e01d41e5 JJ |
5653 | else |
5654 | OMP_CLAUSE_DECL (c2) = convert_from_reference (ptr); | |
acf0174b JJ |
5655 | OMP_CLAUSE_SIZE (c3) = size_zero_node; |
5656 | OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2); | |
5657 | OMP_CLAUSE_CHAIN (c2) = c3; | |
5658 | } | |
5659 | } | |
5660 | } | |
5661 | return false; | |
5662 | } | |
5663 | ||
5664 | /* Return identifier to look up for omp declare reduction. */ | |
5665 | ||
5666 | tree | |
5667 | omp_reduction_id (enum tree_code reduction_code, tree reduction_id, tree type) | |
5668 | { | |
5669 | const char *p = NULL; | |
5670 | const char *m = NULL; | |
5671 | switch (reduction_code) | |
5672 | { | |
5673 | case PLUS_EXPR: | |
5674 | case MULT_EXPR: | |
5675 | case MINUS_EXPR: | |
5676 | case BIT_AND_EXPR: | |
5677 | case BIT_XOR_EXPR: | |
5678 | case BIT_IOR_EXPR: | |
5679 | case TRUTH_ANDIF_EXPR: | |
5680 | case TRUTH_ORIF_EXPR: | |
88a819be | 5681 | reduction_id = ovl_op_identifier (false, reduction_code); |
acf0174b JJ |
5682 | break; |
5683 | case MIN_EXPR: | |
5684 | p = "min"; | |
5685 | break; | |
5686 | case MAX_EXPR: | |
5687 | p = "max"; | |
5688 | break; | |
5689 | default: | |
5690 | break; | |
5691 | } | |
5692 | ||
5693 | if (p == NULL) | |
5694 | { | |
5695 | if (TREE_CODE (reduction_id) != IDENTIFIER_NODE) | |
5696 | return error_mark_node; | |
5697 | p = IDENTIFIER_POINTER (reduction_id); | |
5698 | } | |
5699 | ||
5700 | if (type != NULL_TREE) | |
5701 | m = mangle_type_string (TYPE_MAIN_VARIANT (type)); | |
5702 | ||
5703 | const char prefix[] = "omp declare reduction "; | |
5704 | size_t lenp = sizeof (prefix); | |
5705 | if (strncmp (p, prefix, lenp - 1) == 0) | |
5706 | lenp = 1; | |
5707 | size_t len = strlen (p); | |
5708 | size_t lenm = m ? strlen (m) + 1 : 0; | |
5709 | char *name = XALLOCAVEC (char, lenp + len + lenm); | |
5710 | if (lenp > 1) | |
5711 | memcpy (name, prefix, lenp - 1); | |
5712 | memcpy (name + lenp - 1, p, len + 1); | |
5713 | if (m) | |
5714 | { | |
5715 | name[lenp + len - 1] = '~'; | |
5716 | memcpy (name + lenp + len, m, lenm); | |
5717 | } | |
5718 | return get_identifier (name); | |
5719 | } | |
5720 | ||
5721 | /* Lookup OpenMP UDR ID for TYPE, return the corresponding artificial | |
5722 | FUNCTION_DECL or NULL_TREE if not found. */ | |
5723 | ||
5724 | static tree | |
5725 | omp_reduction_lookup (location_t loc, tree id, tree type, tree *baselinkp, | |
5726 | vec<tree> *ambiguousp) | |
5727 | { | |
5728 | tree orig_id = id; | |
5729 | tree baselink = NULL_TREE; | |
5730 | if (identifier_p (id)) | |
5731 | { | |
5732 | cp_id_kind idk; | |
5733 | bool nonint_cst_expression_p; | |
5734 | const char *error_msg; | |
5735 | id = omp_reduction_id (ERROR_MARK, id, type); | |
5736 | tree decl = lookup_name (id); | |
5737 | if (decl == NULL_TREE) | |
5738 | decl = error_mark_node; | |
5739 | id = finish_id_expression (id, decl, NULL_TREE, &idk, false, true, | |
5740 | &nonint_cst_expression_p, false, true, false, | |
5741 | false, &error_msg, loc); | |
5742 | if (idk == CP_ID_KIND_UNQUALIFIED | |
5743 | && identifier_p (id)) | |
5744 | { | |
5745 | vec<tree, va_gc> *args = NULL; | |
5746 | vec_safe_push (args, build_reference_type (type)); | |
cdc23b1b | 5747 | id = perform_koenig_lookup (id, args, tf_none); |
acf0174b JJ |
5748 | } |
5749 | } | |
5750 | else if (TREE_CODE (id) == SCOPE_REF) | |
5751 | id = lookup_qualified_name (TREE_OPERAND (id, 0), | |
5752 | omp_reduction_id (ERROR_MARK, | |
5753 | TREE_OPERAND (id, 1), | |
5754 | type), | |
4c58a32f | 5755 | LOOK_want::NORMAL, false); |
acf0174b | 5756 | tree fns = id; |
3f267553 NS |
5757 | id = NULL_TREE; |
5758 | if (fns && is_overloaded_fn (fns)) | |
acf0174b | 5759 | { |
3f267553 | 5760 | for (lkp_iterator iter (get_fns (fns)); iter; ++iter) |
acf0174b | 5761 | { |
3f267553 NS |
5762 | tree fndecl = *iter; |
5763 | if (TREE_CODE (fndecl) == FUNCTION_DECL) | |
5764 | { | |
5765 | tree argtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); | |
5766 | if (same_type_p (TREE_TYPE (argtype), type)) | |
5767 | { | |
5768 | id = fndecl; | |
5769 | break; | |
5770 | } | |
5771 | } | |
5772 | } | |
5773 | ||
5774 | if (id && BASELINK_P (fns)) | |
5775 | { | |
5776 | if (baselinkp) | |
5777 | *baselinkp = fns; | |
5778 | else | |
5779 | baselink = fns; | |
acf0174b JJ |
5780 | } |
5781 | } | |
3f267553 NS |
5782 | |
5783 | if (!id && CLASS_TYPE_P (type) && TYPE_BINFO (type)) | |
acf0174b | 5784 | { |
91bb571d | 5785 | auto_vec<tree> ambiguous; |
acf0174b JJ |
5786 | tree binfo = TYPE_BINFO (type), base_binfo, ret = NULL_TREE; |
5787 | unsigned int ix; | |
5788 | if (ambiguousp == NULL) | |
5789 | ambiguousp = &ambiguous; | |
5790 | for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++) | |
5791 | { | |
5792 | id = omp_reduction_lookup (loc, orig_id, BINFO_TYPE (base_binfo), | |
5793 | baselinkp ? baselinkp : &baselink, | |
5794 | ambiguousp); | |
5795 | if (id == NULL_TREE) | |
5796 | continue; | |
5797 | if (!ambiguousp->is_empty ()) | |
5798 | ambiguousp->safe_push (id); | |
5799 | else if (ret != NULL_TREE) | |
5800 | { | |
5801 | ambiguousp->safe_push (ret); | |
5802 | ambiguousp->safe_push (id); | |
5803 | ret = NULL_TREE; | |
5804 | } | |
5805 | else | |
5806 | ret = id; | |
5807 | } | |
5808 | if (ambiguousp != &ambiguous) | |
5809 | return ret; | |
5810 | if (!ambiguous.is_empty ()) | |
5811 | { | |
5812 | const char *str = _("candidates are:"); | |
5813 | unsigned int idx; | |
5814 | tree udr; | |
5815 | error_at (loc, "user defined reduction lookup is ambiguous"); | |
5816 | FOR_EACH_VEC_ELT (ambiguous, idx, udr) | |
5817 | { | |
0f2c4a8f | 5818 | inform (DECL_SOURCE_LOCATION (udr), "%s %#qD", str, udr); |
acf0174b JJ |
5819 | if (idx == 0) |
5820 | str = get_spaces (str); | |
5821 | } | |
acf0174b JJ |
5822 | ret = error_mark_node; |
5823 | baselink = NULL_TREE; | |
5824 | } | |
5825 | id = ret; | |
5826 | } | |
5827 | if (id && baselink) | |
5828 | perform_or_defer_access_check (BASELINK_BINFO (baselink), | |
5829 | id, id, tf_warning_or_error); | |
5830 | return id; | |
5831 | } | |
5832 | ||
5833 | /* Helper function for cp_parser_omp_declare_reduction_exprs | |
5834 | and tsubst_omp_udr. | |
5835 | Remove CLEANUP_STMT for data (omp_priv variable). | |
5836 | Also append INIT_EXPR for DECL_INITIAL of omp_priv after its | |
5837 | DECL_EXPR. */ | |
5838 | ||
5839 | tree | |
5840 | cp_remove_omp_priv_cleanup_stmt (tree *tp, int *walk_subtrees, void *data) | |
5841 | { | |
5842 | if (TYPE_P (*tp)) | |
5843 | *walk_subtrees = 0; | |
5844 | else if (TREE_CODE (*tp) == CLEANUP_STMT && CLEANUP_DECL (*tp) == (tree) data) | |
5845 | *tp = CLEANUP_BODY (*tp); | |
5846 | else if (TREE_CODE (*tp) == DECL_EXPR) | |
5847 | { | |
5848 | tree decl = DECL_EXPR_DECL (*tp); | |
5849 | if (!processing_template_decl | |
5850 | && decl == (tree) data | |
5851 | && DECL_INITIAL (decl) | |
5852 | && DECL_INITIAL (decl) != error_mark_node) | |
5853 | { | |
5854 | tree list = NULL_TREE; | |
5855 | append_to_statement_list_force (*tp, &list); | |
5856 | tree init_expr = build2 (INIT_EXPR, void_type_node, | |
5857 | decl, DECL_INITIAL (decl)); | |
5858 | DECL_INITIAL (decl) = NULL_TREE; | |
5859 | append_to_statement_list_force (init_expr, &list); | |
5860 | *tp = list; | |
5861 | } | |
5862 | } | |
5863 | return NULL_TREE; | |
5864 | } | |
5865 | ||
5866 | /* Data passed from cp_check_omp_declare_reduction to | |
5867 | cp_check_omp_declare_reduction_r. */ | |
5868 | ||
5869 | struct cp_check_omp_declare_reduction_data | |
5870 | { | |
5871 | location_t loc; | |
5872 | tree stmts[7]; | |
5873 | bool combiner_p; | |
5874 | }; | |
5875 | ||
5876 | /* Helper function for cp_check_omp_declare_reduction, called via | |
5877 | cp_walk_tree. */ | |
5878 | ||
5879 | static tree | |
5880 | cp_check_omp_declare_reduction_r (tree *tp, int *, void *data) | |
5881 | { | |
5882 | struct cp_check_omp_declare_reduction_data *udr_data | |
5883 | = (struct cp_check_omp_declare_reduction_data *) data; | |
5884 | if (SSA_VAR_P (*tp) | |
5885 | && !DECL_ARTIFICIAL (*tp) | |
5886 | && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 0 : 3]) | |
5887 | && *tp != DECL_EXPR_DECL (udr_data->stmts[udr_data->combiner_p ? 1 : 4])) | |
5888 | { | |
5889 | location_t loc = udr_data->loc; | |
5890 | if (udr_data->combiner_p) | |
5891 | error_at (loc, "%<#pragma omp declare reduction%> combiner refers to " | |
5892 | "variable %qD which is not %<omp_out%> nor %<omp_in%>", | |
5893 | *tp); | |
5894 | else | |
5895 | error_at (loc, "%<#pragma omp declare reduction%> initializer refers " | |
5896 | "to variable %qD which is not %<omp_priv%> nor " | |
5897 | "%<omp_orig%>", | |
5898 | *tp); | |
5899 | return *tp; | |
5900 | } | |
5901 | return NULL_TREE; | |
5902 | } | |
5903 | ||
5904 | /* Diagnose violation of OpenMP #pragma omp declare reduction restrictions. */ | |
5905 | ||
8155316c | 5906 | bool |
acf0174b JJ |
5907 | cp_check_omp_declare_reduction (tree udr) |
5908 | { | |
5909 | tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (udr))); | |
9f613f06 | 5910 | gcc_assert (TYPE_REF_P (type)); |
acf0174b JJ |
5911 | type = TREE_TYPE (type); |
5912 | int i; | |
5913 | location_t loc = DECL_SOURCE_LOCATION (udr); | |
5914 | ||
5915 | if (type == error_mark_node) | |
8155316c | 5916 | return false; |
acf0174b JJ |
5917 | if (ARITHMETIC_TYPE_P (type)) |
5918 | { | |
5919 | static enum tree_code predef_codes[] | |
5920 | = { PLUS_EXPR, MULT_EXPR, MINUS_EXPR, BIT_AND_EXPR, BIT_XOR_EXPR, | |
5921 | BIT_IOR_EXPR, TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR }; | |
5922 | for (i = 0; i < 8; i++) | |
5923 | { | |
5924 | tree id = omp_reduction_id (predef_codes[i], NULL_TREE, NULL_TREE); | |
5925 | const char *n1 = IDENTIFIER_POINTER (DECL_NAME (udr)); | |
5926 | const char *n2 = IDENTIFIER_POINTER (id); | |
5927 | if (strncmp (n1, n2, IDENTIFIER_LENGTH (id)) == 0 | |
5928 | && (n1[IDENTIFIER_LENGTH (id)] == '~' | |
5929 | || n1[IDENTIFIER_LENGTH (id)] == '\0')) | |
5930 | break; | |
5931 | } | |
5932 | ||
5933 | if (i == 8 | |
5934 | && TREE_CODE (type) != COMPLEX_EXPR) | |
5935 | { | |
5936 | const char prefix_minmax[] = "omp declare reduction m"; | |
5937 | size_t prefix_size = sizeof (prefix_minmax) - 1; | |
5938 | const char *n = IDENTIFIER_POINTER (DECL_NAME (udr)); | |
5939 | if (strncmp (IDENTIFIER_POINTER (DECL_NAME (udr)), | |
5940 | prefix_minmax, prefix_size) == 0 | |
5941 | && ((n[prefix_size] == 'i' && n[prefix_size + 1] == 'n') | |
5942 | || (n[prefix_size] == 'a' && n[prefix_size + 1] == 'x')) | |
5943 | && (n[prefix_size + 2] == '~' || n[prefix_size + 2] == '\0')) | |
5944 | i = 0; | |
5945 | } | |
5946 | if (i < 8) | |
5947 | { | |
5948 | error_at (loc, "predeclared arithmetic type %qT in " | |
5949 | "%<#pragma omp declare reduction%>", type); | |
8155316c | 5950 | return false; |
acf0174b JJ |
5951 | } |
5952 | } | |
7bdc7e06 | 5953 | else if (FUNC_OR_METHOD_TYPE_P (type) |
acf0174b JJ |
5954 | || TREE_CODE (type) == ARRAY_TYPE) |
5955 | { | |
5956 | error_at (loc, "function or array type %qT in " | |
5957 | "%<#pragma omp declare reduction%>", type); | |
8155316c | 5958 | return false; |
acf0174b | 5959 | } |
9f613f06 | 5960 | else if (TYPE_REF_P (type)) |
acf0174b JJ |
5961 | { |
5962 | error_at (loc, "reference type %qT in %<#pragma omp declare reduction%>", | |
5963 | type); | |
8155316c | 5964 | return false; |
acf0174b JJ |
5965 | } |
5966 | else if (TYPE_QUALS_NO_ADDR_SPACE (type)) | |
5967 | { | |
a9c697b8 MS |
5968 | error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified " |
5969 | "type %qT in %<#pragma omp declare reduction%>", type); | |
8155316c | 5970 | return false; |
acf0174b JJ |
5971 | } |
5972 | ||
5973 | tree body = DECL_SAVED_TREE (udr); | |
5974 | if (body == NULL_TREE || TREE_CODE (body) != STATEMENT_LIST) | |
8155316c | 5975 | return true; |
acf0174b JJ |
5976 | |
5977 | tree_stmt_iterator tsi; | |
5978 | struct cp_check_omp_declare_reduction_data data; | |
5979 | memset (data.stmts, 0, sizeof data.stmts); | |
5980 | for (i = 0, tsi = tsi_start (body); | |
5981 | i < 7 && !tsi_end_p (tsi); | |
5982 | i++, tsi_next (&tsi)) | |
5983 | data.stmts[i] = tsi_stmt (tsi); | |
5984 | data.loc = loc; | |
5985 | gcc_assert (tsi_end_p (tsi)); | |
5986 | if (i >= 3) | |
5987 | { | |
5988 | gcc_assert (TREE_CODE (data.stmts[0]) == DECL_EXPR | |
5989 | && TREE_CODE (data.stmts[1]) == DECL_EXPR); | |
65870e75 | 5990 | if (warning_suppressed_p (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */)) |
8155316c | 5991 | return true; |
acf0174b JJ |
5992 | data.combiner_p = true; |
5993 | if (cp_walk_tree (&data.stmts[2], cp_check_omp_declare_reduction_r, | |
5994 | &data, NULL)) | |
65870e75 | 5995 | suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* What warning? */); |
acf0174b JJ |
5996 | } |
5997 | if (i >= 6) | |
5998 | { | |
5999 | gcc_assert (TREE_CODE (data.stmts[3]) == DECL_EXPR | |
6000 | && TREE_CODE (data.stmts[4]) == DECL_EXPR); | |
6001 | data.combiner_p = false; | |
6002 | if (cp_walk_tree (&data.stmts[5], cp_check_omp_declare_reduction_r, | |
6003 | &data, NULL) | |
6004 | || cp_walk_tree (&DECL_INITIAL (DECL_EXPR_DECL (data.stmts[3])), | |
6005 | cp_check_omp_declare_reduction_r, &data, NULL)) | |
65870e75 | 6006 | suppress_warning (DECL_EXPR_DECL (data.stmts[0]) /* Wat warning? */); |
acf0174b JJ |
6007 | if (i == 7) |
6008 | gcc_assert (TREE_CODE (data.stmts[6]) == DECL_EXPR); | |
6009 | } | |
8155316c | 6010 | return true; |
acf0174b JJ |
6011 | } |
6012 | ||
6013 | /* Helper function of finish_omp_clauses. Clone STMT as if we were making | |
6014 | an inline call. But, remap | |
6015 | the OMP_DECL1 VAR_DECL (omp_out resp. omp_orig) to PLACEHOLDER | |
6016 | and OMP_DECL2 VAR_DECL (omp_in resp. omp_priv) to DECL. */ | |
6017 | ||
6018 | static tree | |
6019 | clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2, | |
6020 | tree decl, tree placeholder) | |
6021 | { | |
6022 | copy_body_data id; | |
b787e7a2 | 6023 | hash_map<tree, tree> decl_map; |
acf0174b | 6024 | |
b787e7a2 TS |
6025 | decl_map.put (omp_decl1, placeholder); |
6026 | decl_map.put (omp_decl2, decl); | |
acf0174b JJ |
6027 | memset (&id, 0, sizeof (id)); |
6028 | id.src_fn = DECL_CONTEXT (omp_decl1); | |
6029 | id.dst_fn = current_function_decl; | |
6030 | id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn); | |
b787e7a2 | 6031 | id.decl_map = &decl_map; |
acf0174b JJ |
6032 | |
6033 | id.copy_decl = copy_decl_no_change; | |
6034 | id.transform_call_graph_edges = CB_CGE_DUPLICATE; | |
6035 | id.transform_new_cfg = true; | |
6036 | id.transform_return_to_modify = false; | |
6037 | id.transform_lang_insert_block = NULL; | |
6038 | id.eh_lp_nr = 0; | |
6039 | walk_tree (&stmt, copy_tree_body_r, &id, NULL); | |
acf0174b JJ |
6040 | return stmt; |
6041 | } | |
6042 | ||
6043 | /* Helper function of finish_omp_clauses, called via cp_walk_tree. | |
6044 | Find OMP_CLAUSE_PLACEHOLDER (passed in DATA) in *TP. */ | |
6045 | ||
6046 | static tree | |
6047 | find_omp_placeholder_r (tree *tp, int *, void *data) | |
6048 | { | |
6049 | if (*tp == (tree) data) | |
6050 | return *tp; | |
6051 | return NULL_TREE; | |
6052 | } | |
6053 | ||
6054 | /* Helper function of finish_omp_clauses. Handle OMP_CLAUSE_REDUCTION C. | |
6055 | Return true if there is some error and the clause should be removed. */ | |
6056 | ||
6057 | static bool | |
6058 | finish_omp_reduction_clause (tree c, bool *need_default_ctor, bool *need_dtor) | |
6059 | { | |
6060 | tree t = OMP_CLAUSE_DECL (c); | |
6061 | bool predefined = false; | |
d9a6bd32 JJ |
6062 | if (TREE_CODE (t) == TREE_LIST) |
6063 | { | |
6064 | gcc_assert (processing_template_decl); | |
6065 | return false; | |
6066 | } | |
acf0174b | 6067 | tree type = TREE_TYPE (t); |
d9a6bd32 JJ |
6068 | if (TREE_CODE (t) == MEM_REF) |
6069 | type = TREE_TYPE (type); | |
9f613f06 | 6070 | if (TYPE_REF_P (type)) |
acf0174b | 6071 | type = TREE_TYPE (type); |
d9a6bd32 JJ |
6072 | if (TREE_CODE (type) == ARRAY_TYPE) |
6073 | { | |
6074 | tree oatype = type; | |
6075 | gcc_assert (TREE_CODE (t) != MEM_REF); | |
6076 | while (TREE_CODE (type) == ARRAY_TYPE) | |
6077 | type = TREE_TYPE (type); | |
6078 | if (!processing_template_decl) | |
6079 | { | |
6080 | t = require_complete_type (t); | |
aea199f9 JJ |
6081 | if (t == error_mark_node |
6082 | || !complete_type_or_else (oatype, NULL_TREE)) | |
d9a6bd32 JJ |
6083 | return true; |
6084 | tree size = size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (oatype), | |
6085 | TYPE_SIZE_UNIT (type)); | |
6086 | if (integer_zerop (size)) | |
6087 | { | |
28567c40 JJ |
6088 | error_at (OMP_CLAUSE_LOCATION (c), |
6089 | "%qE in %<reduction%> clause is a zero size array", | |
6090 | omp_clause_printable_decl (t)); | |
d9a6bd32 JJ |
6091 | return true; |
6092 | } | |
6093 | size = size_binop (MINUS_EXPR, size, size_one_node); | |
28567c40 | 6094 | size = save_expr (size); |
d9a6bd32 JJ |
6095 | tree index_type = build_index_type (size); |
6096 | tree atype = build_array_type (type, index_type); | |
6097 | tree ptype = build_pointer_type (type); | |
6098 | if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) | |
6099 | t = build_fold_addr_expr (t); | |
6100 | t = build2 (MEM_REF, atype, t, build_int_cst (ptype, 0)); | |
6101 | OMP_CLAUSE_DECL (c) = t; | |
6102 | } | |
6103 | } | |
4ca56230 PC |
6104 | if (type == error_mark_node) |
6105 | return true; | |
6106 | else if (ARITHMETIC_TYPE_P (type)) | |
acf0174b JJ |
6107 | switch (OMP_CLAUSE_REDUCTION_CODE (c)) |
6108 | { | |
6109 | case PLUS_EXPR: | |
6110 | case MULT_EXPR: | |
6111 | case MINUS_EXPR: | |
1580fc76 TB |
6112 | case TRUTH_ANDIF_EXPR: |
6113 | case TRUTH_ORIF_EXPR: | |
acf0174b JJ |
6114 | predefined = true; |
6115 | break; | |
6116 | case MIN_EXPR: | |
6117 | case MAX_EXPR: | |
6118 | if (TREE_CODE (type) == COMPLEX_TYPE) | |
6119 | break; | |
6120 | predefined = true; | |
6121 | break; | |
6122 | case BIT_AND_EXPR: | |
6123 | case BIT_IOR_EXPR: | |
6124 | case BIT_XOR_EXPR: | |
652fea39 JJ |
6125 | if (FLOAT_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE) |
6126 | break; | |
6127 | predefined = true; | |
6128 | break; | |
acf0174b JJ |
6129 | default: |
6130 | break; | |
6131 | } | |
d9a6bd32 | 6132 | else if (TYPE_READONLY (type)) |
acf0174b | 6133 | { |
28567c40 JJ |
6134 | error_at (OMP_CLAUSE_LOCATION (c), |
6135 | "%qE has const type for %<reduction%>", | |
6136 | omp_clause_printable_decl (t)); | |
acf0174b JJ |
6137 | return true; |
6138 | } | |
6139 | else if (!processing_template_decl) | |
6140 | { | |
6141 | t = require_complete_type (t); | |
6142 | if (t == error_mark_node) | |
6143 | return true; | |
6144 | OMP_CLAUSE_DECL (c) = t; | |
6145 | } | |
6146 | ||
6147 | if (predefined) | |
6148 | { | |
6149 | OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE; | |
6150 | return false; | |
6151 | } | |
6152 | else if (processing_template_decl) | |
9d620422 JJ |
6153 | { |
6154 | if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) == error_mark_node) | |
6155 | return true; | |
6156 | return false; | |
6157 | } | |
acf0174b JJ |
6158 | |
6159 | tree id = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c); | |
6160 | ||
d9a6bd32 | 6161 | type = TYPE_MAIN_VARIANT (type); |
acf0174b JJ |
6162 | OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL_TREE; |
6163 | if (id == NULL_TREE) | |
6164 | id = omp_reduction_id (OMP_CLAUSE_REDUCTION_CODE (c), | |
6165 | NULL_TREE, NULL_TREE); | |
6166 | id = omp_reduction_lookup (OMP_CLAUSE_LOCATION (c), id, type, NULL, NULL); | |
6167 | if (id) | |
6168 | { | |
6169 | if (id == error_mark_node) | |
6170 | return true; | |
acf0174b JJ |
6171 | mark_used (id); |
6172 | tree body = DECL_SAVED_TREE (id); | |
88957d5e PC |
6173 | if (!body) |
6174 | return true; | |
acf0174b JJ |
6175 | if (TREE_CODE (body) == STATEMENT_LIST) |
6176 | { | |
6177 | tree_stmt_iterator tsi; | |
d9a6bd32 | 6178 | tree placeholder = NULL_TREE, decl_placeholder = NULL_TREE; |
acf0174b JJ |
6179 | int i; |
6180 | tree stmts[7]; | |
6181 | tree atype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (id))); | |
6182 | atype = TREE_TYPE (atype); | |
6183 | bool need_static_cast = !same_type_p (type, atype); | |
6184 | memset (stmts, 0, sizeof stmts); | |
6185 | for (i = 0, tsi = tsi_start (body); | |
6186 | i < 7 && !tsi_end_p (tsi); | |
6187 | i++, tsi_next (&tsi)) | |
6188 | stmts[i] = tsi_stmt (tsi); | |
6189 | gcc_assert (tsi_end_p (tsi)); | |
6190 | ||
6191 | if (i >= 3) | |
6192 | { | |
6193 | gcc_assert (TREE_CODE (stmts[0]) == DECL_EXPR | |
6194 | && TREE_CODE (stmts[1]) == DECL_EXPR); | |
6195 | placeholder = build_lang_decl (VAR_DECL, NULL_TREE, type); | |
6196 | DECL_ARTIFICIAL (placeholder) = 1; | |
6197 | DECL_IGNORED_P (placeholder) = 1; | |
6198 | OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = placeholder; | |
d9a6bd32 JJ |
6199 | if (TREE_CODE (t) == MEM_REF) |
6200 | { | |
6201 | decl_placeholder = build_lang_decl (VAR_DECL, NULL_TREE, | |
6202 | type); | |
6203 | DECL_ARTIFICIAL (decl_placeholder) = 1; | |
6204 | DECL_IGNORED_P (decl_placeholder) = 1; | |
6205 | OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c) = decl_placeholder; | |
6206 | } | |
acf0174b JJ |
6207 | if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[0]))) |
6208 | cxx_mark_addressable (placeholder); | |
6209 | if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[1])) | |
28567c40 JJ |
6210 | && (decl_placeholder |
6211 | || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c))))) | |
d9a6bd32 JJ |
6212 | cxx_mark_addressable (decl_placeholder ? decl_placeholder |
6213 | : OMP_CLAUSE_DECL (c)); | |
acf0174b | 6214 | tree omp_out = placeholder; |
d9a6bd32 JJ |
6215 | tree omp_in = decl_placeholder ? decl_placeholder |
6216 | : convert_from_reference (OMP_CLAUSE_DECL (c)); | |
acf0174b JJ |
6217 | if (need_static_cast) |
6218 | { | |
6219 | tree rtype = build_reference_type (atype); | |
ca6932ad PC |
6220 | omp_out = build_static_cast (input_location, |
6221 | rtype, omp_out, | |
acf0174b | 6222 | tf_warning_or_error); |
ca6932ad PC |
6223 | omp_in = build_static_cast (input_location, |
6224 | rtype, omp_in, | |
acf0174b JJ |
6225 | tf_warning_or_error); |
6226 | if (omp_out == error_mark_node || omp_in == error_mark_node) | |
6227 | return true; | |
6228 | omp_out = convert_from_reference (omp_out); | |
6229 | omp_in = convert_from_reference (omp_in); | |
6230 | } | |
6231 | OMP_CLAUSE_REDUCTION_MERGE (c) | |
6232 | = clone_omp_udr (stmts[2], DECL_EXPR_DECL (stmts[0]), | |
6233 | DECL_EXPR_DECL (stmts[1]), omp_in, omp_out); | |
6234 | } | |
6235 | if (i >= 6) | |
6236 | { | |
6237 | gcc_assert (TREE_CODE (stmts[3]) == DECL_EXPR | |
6238 | && TREE_CODE (stmts[4]) == DECL_EXPR); | |
28567c40 JJ |
6239 | if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[3])) |
6240 | && (decl_placeholder | |
6241 | || !TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c))))) | |
d9a6bd32 JJ |
6242 | cxx_mark_addressable (decl_placeholder ? decl_placeholder |
6243 | : OMP_CLAUSE_DECL (c)); | |
acf0174b JJ |
6244 | if (TREE_ADDRESSABLE (DECL_EXPR_DECL (stmts[4]))) |
6245 | cxx_mark_addressable (placeholder); | |
d9a6bd32 JJ |
6246 | tree omp_priv = decl_placeholder ? decl_placeholder |
6247 | : convert_from_reference (OMP_CLAUSE_DECL (c)); | |
acf0174b JJ |
6248 | tree omp_orig = placeholder; |
6249 | if (need_static_cast) | |
6250 | { | |
6251 | if (i == 7) | |
6252 | { | |
6253 | error_at (OMP_CLAUSE_LOCATION (c), | |
6254 | "user defined reduction with constructor " | |
6255 | "initializer for base class %qT", atype); | |
6256 | return true; | |
6257 | } | |
6258 | tree rtype = build_reference_type (atype); | |
ca6932ad PC |
6259 | omp_priv = build_static_cast (input_location, |
6260 | rtype, omp_priv, | |
acf0174b | 6261 | tf_warning_or_error); |
ca6932ad PC |
6262 | omp_orig = build_static_cast (input_location, |
6263 | rtype, omp_orig, | |
acf0174b JJ |
6264 | tf_warning_or_error); |
6265 | if (omp_priv == error_mark_node | |
6266 | || omp_orig == error_mark_node) | |
6267 | return true; | |
6268 | omp_priv = convert_from_reference (omp_priv); | |
6269 | omp_orig = convert_from_reference (omp_orig); | |
6270 | } | |
6271 | if (i == 6) | |
6272 | *need_default_ctor = true; | |
6273 | OMP_CLAUSE_REDUCTION_INIT (c) | |
6274 | = clone_omp_udr (stmts[5], DECL_EXPR_DECL (stmts[4]), | |
6275 | DECL_EXPR_DECL (stmts[3]), | |
6276 | omp_priv, omp_orig); | |
6277 | if (cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (c), | |
6278 | find_omp_placeholder_r, placeholder, NULL)) | |
6279 | OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c) = 1; | |
6280 | } | |
6281 | else if (i >= 3) | |
6282 | { | |
6283 | if (CLASS_TYPE_P (type) && !pod_type_p (type)) | |
6284 | *need_default_ctor = true; | |
6285 | else | |
6286 | { | |
6287 | tree init; | |
d9a6bd32 JJ |
6288 | tree v = decl_placeholder ? decl_placeholder |
6289 | : convert_from_reference (t); | |
acf0174b JJ |
6290 | if (AGGREGATE_TYPE_P (TREE_TYPE (v))) |
6291 | init = build_constructor (TREE_TYPE (v), NULL); | |
6292 | else | |
6293 | init = fold_convert (TREE_TYPE (v), integer_zero_node); | |
6294 | OMP_CLAUSE_REDUCTION_INIT (c) | |
6295 | = build2 (INIT_EXPR, TREE_TYPE (v), v, init); | |
6296 | } | |
6297 | } | |
6298 | } | |
6299 | } | |
6300 | if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)) | |
6301 | *need_dtor = true; | |
6302 | else | |
6303 | { | |
28567c40 JJ |
6304 | error_at (OMP_CLAUSE_LOCATION (c), |
6305 | "user defined reduction not found for %qE", | |
6306 | omp_clause_printable_decl (t)); | |
acf0174b JJ |
6307 | return true; |
6308 | } | |
d9a6bd32 JJ |
6309 | if (TREE_CODE (OMP_CLAUSE_DECL (c)) == MEM_REF) |
6310 | gcc_assert (TYPE_SIZE_UNIT (type) | |
6311 | && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST); | |
6312 | return false; | |
6313 | } | |
6314 | ||
6315 | /* Called from finish_struct_1. linear(this) or linear(this:step) | |
6316 | clauses might not be finalized yet because the class has been incomplete | |
6317 | when parsing #pragma omp declare simd methods. Fix those up now. */ | |
6318 | ||
6319 | void | |
6320 | finish_omp_declare_simd_methods (tree t) | |
6321 | { | |
6322 | if (processing_template_decl) | |
6323 | return; | |
6324 | ||
5aaa8fb4 | 6325 | for (tree x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x)) |
d9a6bd32 | 6326 | { |
10839133 AO |
6327 | if (TREE_CODE (x) == USING_DECL |
6328 | || !DECL_NONSTATIC_MEMBER_FUNCTION_P (x)) | |
d9a6bd32 JJ |
6329 | continue; |
6330 | tree ods = lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (x)); | |
6331 | if (!ods || !TREE_VALUE (ods)) | |
6332 | continue; | |
6333 | for (tree c = TREE_VALUE (TREE_VALUE (ods)); c; c = OMP_CLAUSE_CHAIN (c)) | |
6334 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR | |
6335 | && integer_zerop (OMP_CLAUSE_DECL (c)) | |
6336 | && OMP_CLAUSE_LINEAR_STEP (c) | |
9f613f06 | 6337 | && TYPE_PTR_P (TREE_TYPE (OMP_CLAUSE_LINEAR_STEP (c)))) |
d9a6bd32 JJ |
6338 | { |
6339 | tree s = OMP_CLAUSE_LINEAR_STEP (c); | |
6340 | s = fold_convert_loc (OMP_CLAUSE_LOCATION (c), sizetype, s); | |
6341 | s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MULT_EXPR, | |
6342 | sizetype, s, TYPE_SIZE_UNIT (t)); | |
6343 | OMP_CLAUSE_LINEAR_STEP (c) = s; | |
6344 | } | |
6345 | } | |
6346 | } | |
6347 | ||
6348 | /* Adjust sink depend clause to take into account pointer offsets. | |
6349 | ||
6350 | Return TRUE if there was a problem processing the offset, and the | |
6351 | whole clause should be removed. */ | |
6352 | ||
6353 | static bool | |
6354 | cp_finish_omp_clause_depend_sink (tree sink_clause) | |
6355 | { | |
6356 | tree t = OMP_CLAUSE_DECL (sink_clause); | |
6357 | gcc_assert (TREE_CODE (t) == TREE_LIST); | |
6358 | ||
6359 | /* Make sure we don't adjust things twice for templates. */ | |
6360 | if (processing_template_decl) | |
6361 | return false; | |
6362 | ||
6363 | for (; t; t = TREE_CHAIN (t)) | |
6364 | { | |
6365 | tree decl = TREE_VALUE (t); | |
9f613f06 | 6366 | if (TYPE_PTR_P (TREE_TYPE (decl))) |
d9a6bd32 JJ |
6367 | { |
6368 | tree offset = TREE_PURPOSE (t); | |
8e6cdc90 | 6369 | bool neg = wi::neg_p (wi::to_wide (offset)); |
d9a6bd32 JJ |
6370 | offset = fold_unary (ABS_EXPR, TREE_TYPE (offset), offset); |
6371 | decl = mark_rvalue_use (decl); | |
6372 | decl = convert_from_reference (decl); | |
6373 | tree t2 = pointer_int_sum (OMP_CLAUSE_LOCATION (sink_clause), | |
6374 | neg ? MINUS_EXPR : PLUS_EXPR, | |
6375 | decl, offset); | |
6376 | t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause), | |
a8fc2579 RB |
6377 | MINUS_EXPR, sizetype, |
6378 | fold_convert (sizetype, t2), | |
6379 | fold_convert (sizetype, decl)); | |
d9a6bd32 JJ |
6380 | if (t2 == error_mark_node) |
6381 | return true; | |
6382 | TREE_PURPOSE (t) = t2; | |
6383 | } | |
6384 | } | |
acf0174b JJ |
6385 | return false; |
6386 | } | |
6387 | ||
28567c40 JJ |
6388 | /* Finish OpenMP iterators ITER. Return true if they are errorneous |
6389 | and clauses containing them should be removed. */ | |
6390 | ||
6391 | static bool | |
6392 | cp_omp_finish_iterators (tree iter) | |
6393 | { | |
6394 | bool ret = false; | |
6395 | for (tree it = iter; it; it = TREE_CHAIN (it)) | |
6396 | { | |
6397 | tree var = TREE_VEC_ELT (it, 0); | |
6398 | tree begin = TREE_VEC_ELT (it, 1); | |
6399 | tree end = TREE_VEC_ELT (it, 2); | |
6400 | tree step = TREE_VEC_ELT (it, 3); | |
6401 | tree orig_step; | |
6402 | tree type = TREE_TYPE (var); | |
6403 | location_t loc = DECL_SOURCE_LOCATION (var); | |
6404 | if (type == error_mark_node) | |
6405 | { | |
6406 | ret = true; | |
6407 | continue; | |
6408 | } | |
6409 | if (type_dependent_expression_p (var)) | |
6410 | continue; | |
6411 | if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type)) | |
6412 | { | |
6413 | error_at (loc, "iterator %qD has neither integral nor pointer type", | |
6414 | var); | |
6415 | ret = true; | |
6416 | continue; | |
6417 | } | |
6418 | else if (TYPE_READONLY (type)) | |
6419 | { | |
6420 | error_at (loc, "iterator %qD has const qualified type", var); | |
6421 | ret = true; | |
6422 | continue; | |
6423 | } | |
6424 | if (type_dependent_expression_p (begin) | |
6425 | || type_dependent_expression_p (end) | |
6426 | || type_dependent_expression_p (step)) | |
6427 | continue; | |
6428 | else if (error_operand_p (step)) | |
6429 | { | |
6430 | ret = true; | |
6431 | continue; | |
6432 | } | |
6433 | else if (!INTEGRAL_TYPE_P (TREE_TYPE (step))) | |
6434 | { | |
6435 | error_at (EXPR_LOC_OR_LOC (step, loc), | |
6436 | "iterator step with non-integral type"); | |
6437 | ret = true; | |
6438 | continue; | |
6439 | } | |
6440 | ||
6441 | begin = mark_rvalue_use (begin); | |
6442 | end = mark_rvalue_use (end); | |
6443 | step = mark_rvalue_use (step); | |
ca6932ad PC |
6444 | begin = cp_build_c_cast (input_location, type, begin, |
6445 | tf_warning_or_error); | |
6446 | end = cp_build_c_cast (input_location, type, end, | |
6447 | tf_warning_or_error); | |
28567c40 JJ |
6448 | orig_step = step; |
6449 | if (!processing_template_decl) | |
6450 | step = orig_step = save_expr (step); | |
6451 | tree stype = POINTER_TYPE_P (type) ? sizetype : type; | |
ca6932ad PC |
6452 | step = cp_build_c_cast (input_location, stype, step, |
6453 | tf_warning_or_error); | |
28567c40 JJ |
6454 | if (POINTER_TYPE_P (type) && !processing_template_decl) |
6455 | { | |
6456 | begin = save_expr (begin); | |
6457 | step = pointer_int_sum (loc, PLUS_EXPR, begin, step); | |
6458 | step = fold_build2_loc (loc, MINUS_EXPR, sizetype, | |
6459 | fold_convert (sizetype, step), | |
6460 | fold_convert (sizetype, begin)); | |
6461 | step = fold_convert (ssizetype, step); | |
6462 | } | |
6463 | if (!processing_template_decl) | |
6464 | { | |
6465 | begin = maybe_constant_value (begin); | |
6466 | end = maybe_constant_value (end); | |
6467 | step = maybe_constant_value (step); | |
6468 | orig_step = maybe_constant_value (orig_step); | |
6469 | } | |
6470 | if (integer_zerop (step)) | |
6471 | { | |
6472 | error_at (loc, "iterator %qD has zero step", var); | |
6473 | ret = true; | |
6474 | continue; | |
6475 | } | |
6476 | ||
6477 | if (begin == error_mark_node | |
6478 | || end == error_mark_node | |
6479 | || step == error_mark_node | |
6480 | || orig_step == error_mark_node) | |
6481 | { | |
6482 | ret = true; | |
6483 | continue; | |
6484 | } | |
6485 | ||
6486 | if (!processing_template_decl) | |
6487 | { | |
6488 | begin = fold_build_cleanup_point_expr (TREE_TYPE (begin), begin); | |
6489 | end = fold_build_cleanup_point_expr (TREE_TYPE (end), end); | |
6490 | step = fold_build_cleanup_point_expr (TREE_TYPE (step), step); | |
6491 | orig_step = fold_build_cleanup_point_expr (TREE_TYPE (orig_step), | |
6492 | orig_step); | |
6493 | } | |
6494 | hash_set<tree> pset; | |
6495 | tree it2; | |
6496 | for (it2 = TREE_CHAIN (it); it2; it2 = TREE_CHAIN (it2)) | |
6497 | { | |
6498 | tree var2 = TREE_VEC_ELT (it2, 0); | |
6499 | tree begin2 = TREE_VEC_ELT (it2, 1); | |
6500 | tree end2 = TREE_VEC_ELT (it2, 2); | |
6501 | tree step2 = TREE_VEC_ELT (it2, 3); | |
6502 | location_t loc2 = DECL_SOURCE_LOCATION (var2); | |
6503 | if (cp_walk_tree (&begin2, find_omp_placeholder_r, var, &pset)) | |
6504 | { | |
6505 | error_at (EXPR_LOC_OR_LOC (begin2, loc2), | |
6506 | "begin expression refers to outer iterator %qD", var); | |
6507 | break; | |
6508 | } | |
6509 | else if (cp_walk_tree (&end2, find_omp_placeholder_r, var, &pset)) | |
6510 | { | |
6511 | error_at (EXPR_LOC_OR_LOC (end2, loc2), | |
6512 | "end expression refers to outer iterator %qD", var); | |
6513 | break; | |
6514 | } | |
6515 | else if (cp_walk_tree (&step2, find_omp_placeholder_r, var, &pset)) | |
6516 | { | |
6517 | error_at (EXPR_LOC_OR_LOC (step2, loc2), | |
6518 | "step expression refers to outer iterator %qD", var); | |
6519 | break; | |
6520 | } | |
6521 | } | |
6522 | if (it2) | |
6523 | { | |
6524 | ret = true; | |
6525 | continue; | |
6526 | } | |
6527 | TREE_VEC_ELT (it, 1) = begin; | |
6528 | TREE_VEC_ELT (it, 2) = end; | |
6529 | if (processing_template_decl) | |
6530 | TREE_VEC_ELT (it, 3) = orig_step; | |
6531 | else | |
6532 | { | |
6533 | TREE_VEC_ELT (it, 3) = step; | |
6534 | TREE_VEC_ELT (it, 4) = orig_step; | |
6535 | } | |
6536 | } | |
6537 | return ret; | |
6538 | } | |
6539 | ||
519d7496 JB |
6540 | /* Ensure that pointers are used in OpenACC attach and detach clauses. |
6541 | Return true if an error has been detected. */ | |
6542 | ||
6543 | static bool | |
6544 | cp_oacc_check_attachments (tree c) | |
6545 | { | |
6546 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) | |
6547 | return false; | |
6548 | ||
6549 | /* OpenACC attach / detach clauses must be pointers. */ | |
6550 | if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH | |
6551 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH) | |
6552 | { | |
6553 | tree t = OMP_CLAUSE_DECL (c); | |
6554 | tree type; | |
6555 | ||
6556 | while (TREE_CODE (t) == TREE_LIST) | |
6557 | t = TREE_CHAIN (t); | |
6558 | ||
6559 | type = TREE_TYPE (t); | |
6560 | ||
6561 | if (TREE_CODE (type) == REFERENCE_TYPE) | |
6562 | type = TREE_TYPE (type); | |
6563 | ||
6564 | if (TREE_CODE (type) != POINTER_TYPE) | |
6565 | { | |
6566 | error_at (OMP_CLAUSE_LOCATION (c), "expected pointer in %qs clause", | |
6567 | c_omp_map_clause_name (c, true)); | |
6568 | return true; | |
6569 | } | |
6570 | } | |
6571 | ||
6572 | return false; | |
6573 | } | |
6574 | ||
1799e5d5 RH |
6575 | /* For all elements of CLAUSES, validate them vs OpenMP constraints. |
6576 | Remove any elements from the list that are invalid. */ | |
6577 | ||
6578 | tree | |
77886428 | 6579 | finish_omp_clauses (tree clauses, enum c_omp_region_type ort) |
1799e5d5 RH |
6580 | { |
6581 | bitmap_head generic_head, firstprivate_head, lastprivate_head; | |
c94424b0 JJ |
6582 | bitmap_head aligned_head, map_head, map_field_head, map_firstprivate_head; |
6583 | bitmap_head oacc_reduction_head; | |
f3316c6d | 6584 | tree c, t, *pc; |
d9a6bd32 | 6585 | tree safelen = NULL_TREE; |
acf0174b JJ |
6586 | bool branch_seen = false; |
6587 | bool copyprivate_seen = false; | |
e01d41e5 | 6588 | bool ordered_seen = false; |
1fdd6f04 | 6589 | bool order_seen = false; |
bf38f7e9 | 6590 | bool schedule_seen = false; |
b605f663 | 6591 | bool oacc_async = false; |
28567c40 JJ |
6592 | tree last_iterators = NULL_TREE; |
6593 | bool last_iterators_remove = false; | |
bf38f7e9 JJ |
6594 | /* 1 if normal/task reduction has been seen, -1 if inscan reduction |
6595 | has been seen, -2 if mixed inscan/normal reduction diagnosed. */ | |
6596 | int reduction_seen = 0; | |
3a8b2094 | 6597 | bool allocate_seen = false; |
1b462dea | 6598 | tree detach_seen = NULL_TREE; |
a6d22fb2 | 6599 | bool mergeable_seen = false; |
c94424b0 | 6600 | bool implicit_moved = false; |
7619d334 | 6601 | bool target_in_reduction_seen = false; |
1799e5d5 RH |
6602 | |
6603 | bitmap_obstack_initialize (NULL); | |
6604 | bitmap_initialize (&generic_head, &bitmap_default_obstack); | |
6605 | bitmap_initialize (&firstprivate_head, &bitmap_default_obstack); | |
6606 | bitmap_initialize (&lastprivate_head, &bitmap_default_obstack); | |
acf0174b | 6607 | bitmap_initialize (&aligned_head, &bitmap_default_obstack); |
28567c40 | 6608 | /* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */ |
d9a6bd32 JJ |
6609 | bitmap_initialize (&map_head, &bitmap_default_obstack); |
6610 | bitmap_initialize (&map_field_head, &bitmap_default_obstack); | |
c94424b0 | 6611 | bitmap_initialize (&map_firstprivate_head, &bitmap_default_obstack); |
8860d270 | 6612 | /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head |
7619d334 | 6613 | instead and for ort == C_ORT_OMP_TARGET used as in_reduction_head. */ |
e46c7770 | 6614 | bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack); |
1799e5d5 | 6615 | |
b605f663 CLT |
6616 | if (ort & C_ORT_ACC) |
6617 | for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) | |
6618 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ASYNC) | |
6619 | { | |
6620 | oacc_async = true; | |
6621 | break; | |
6622 | } | |
6623 | ||
1799e5d5 RH |
6624 | for (pc = &clauses, c = clauses; c ; c = *pc) |
6625 | { | |
6626 | bool remove = false; | |
d9a6bd32 | 6627 | bool field_ok = false; |
1799e5d5 RH |
6628 | |
6629 | switch (OMP_CLAUSE_CODE (c)) | |
6630 | { | |
6631 | case OMP_CLAUSE_SHARED: | |
77886428 | 6632 | field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); |
1799e5d5 RH |
6633 | goto check_dup_generic; |
6634 | case OMP_CLAUSE_PRIVATE: | |
77886428 | 6635 | field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); |
1799e5d5 RH |
6636 | goto check_dup_generic; |
6637 | case OMP_CLAUSE_REDUCTION: | |
bf38f7e9 JJ |
6638 | if (reduction_seen == 0) |
6639 | reduction_seen = OMP_CLAUSE_REDUCTION_INSCAN (c) ? -1 : 1; | |
6640 | else if (reduction_seen != -2 | |
6641 | && reduction_seen != (OMP_CLAUSE_REDUCTION_INSCAN (c) | |
6642 | ? -1 : 1)) | |
6643 | { | |
6644 | error_at (OMP_CLAUSE_LOCATION (c), | |
6645 | "%<inscan%> and non-%<inscan%> %<reduction%> clauses " | |
6646 | "on the same construct"); | |
6647 | reduction_seen = -2; | |
6648 | } | |
28567c40 JJ |
6649 | /* FALLTHRU */ |
6650 | case OMP_CLAUSE_IN_REDUCTION: | |
6651 | case OMP_CLAUSE_TASK_REDUCTION: | |
77886428 | 6652 | field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); |
d9a6bd32 JJ |
6653 | t = OMP_CLAUSE_DECL (c); |
6654 | if (TREE_CODE (t) == TREE_LIST) | |
6655 | { | |
e46c7770 | 6656 | if (handle_omp_array_sections (c, ort)) |
d9a6bd32 JJ |
6657 | { |
6658 | remove = true; | |
6659 | break; | |
6660 | } | |
bf38f7e9 JJ |
6661 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
6662 | && OMP_CLAUSE_REDUCTION_INSCAN (c)) | |
6663 | { | |
6664 | error_at (OMP_CLAUSE_LOCATION (c), | |
6665 | "%<inscan%> %<reduction%> clause with array " | |
6666 | "section"); | |
6667 | remove = true; | |
6668 | break; | |
6669 | } | |
d9a6bd32 JJ |
6670 | if (TREE_CODE (t) == TREE_LIST) |
6671 | { | |
6672 | while (TREE_CODE (t) == TREE_LIST) | |
6673 | t = TREE_CHAIN (t); | |
6674 | } | |
6675 | else | |
6676 | { | |
6677 | gcc_assert (TREE_CODE (t) == MEM_REF); | |
6678 | t = TREE_OPERAND (t, 0); | |
e01d41e5 JJ |
6679 | if (TREE_CODE (t) == POINTER_PLUS_EXPR) |
6680 | t = TREE_OPERAND (t, 0); | |
d9a6bd32 | 6681 | if (TREE_CODE (t) == ADDR_EXPR |
a7f8415c | 6682 | || INDIRECT_REF_P (t)) |
d9a6bd32 JJ |
6683 | t = TREE_OPERAND (t, 0); |
6684 | } | |
6685 | tree n = omp_clause_decl_field (t); | |
6686 | if (n) | |
6687 | t = n; | |
6688 | goto check_dup_generic_t; | |
6689 | } | |
b605f663 CLT |
6690 | if (oacc_async) |
6691 | cxx_mark_addressable (t); | |
1799e5d5 RH |
6692 | goto check_dup_generic; |
6693 | case OMP_CLAUSE_COPYPRIVATE: | |
acf0174b | 6694 | copyprivate_seen = true; |
77886428 | 6695 | field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); |
1799e5d5 RH |
6696 | goto check_dup_generic; |
6697 | case OMP_CLAUSE_COPYIN: | |
acf0174b JJ |
6698 | goto check_dup_generic; |
6699 | case OMP_CLAUSE_LINEAR: | |
77886428 | 6700 | field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP); |
acf0174b | 6701 | t = OMP_CLAUSE_DECL (c); |
77886428 | 6702 | if (ort != C_ORT_OMP_DECLARE_SIMD |
d9a6bd32 JJ |
6703 | && OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT) |
6704 | { | |
6705 | error_at (OMP_CLAUSE_LOCATION (c), | |
6706 | "modifier should not be specified in %<linear%> " | |
6707 | "clause on %<simd%> or %<for%> constructs"); | |
6708 | OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT; | |
6709 | } | |
7da8534d | 6710 | if ((VAR_P (t) || TREE_CODE (t) == PARM_DECL) |
d9a6bd32 | 6711 | && !type_dependent_expression_p (t)) |
acf0174b | 6712 | { |
d9a6bd32 JJ |
6713 | tree type = TREE_TYPE (t); |
6714 | if ((OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF | |
6715 | || OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_UVAL) | |
9f613f06 | 6716 | && !TYPE_REF_P (type)) |
d9a6bd32 | 6717 | { |
28567c40 JJ |
6718 | error_at (OMP_CLAUSE_LOCATION (c), |
6719 | "linear clause with %qs modifier applied to " | |
6720 | "non-reference variable with %qT type", | |
6721 | OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF | |
6722 | ? "ref" : "uval", TREE_TYPE (t)); | |
d9a6bd32 JJ |
6723 | remove = true; |
6724 | break; | |
6725 | } | |
9f613f06 | 6726 | if (TYPE_REF_P (type)) |
d9a6bd32 | 6727 | type = TREE_TYPE (type); |
5e9d6aa4 | 6728 | if (OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_REF) |
477d4906 IV |
6729 | { |
6730 | if (!INTEGRAL_TYPE_P (type) | |
9f613f06 | 6731 | && !TYPE_PTR_P (type)) |
477d4906 | 6732 | { |
28567c40 JJ |
6733 | error_at (OMP_CLAUSE_LOCATION (c), |
6734 | "linear clause applied to non-integral " | |
6735 | "non-pointer variable with %qT type", | |
6736 | TREE_TYPE (t)); | |
477d4906 IV |
6737 | remove = true; |
6738 | break; | |
6739 | } | |
d9a6bd32 | 6740 | } |
acf0174b JJ |
6741 | } |
6742 | t = OMP_CLAUSE_LINEAR_STEP (c); | |
6743 | if (t == NULL_TREE) | |
6744 | t = integer_one_node; | |
6745 | if (t == error_mark_node) | |
ee1d5a02 JJ |
6746 | { |
6747 | remove = true; | |
6748 | break; | |
6749 | } | |
acf0174b | 6750 | else if (!type_dependent_expression_p (t) |
e01d41e5 | 6751 | && !INTEGRAL_TYPE_P (TREE_TYPE (t)) |
77886428 | 6752 | && (ort != C_ORT_OMP_DECLARE_SIMD |
e01d41e5 | 6753 | || TREE_CODE (t) != PARM_DECL |
9f613f06 | 6754 | || !TYPE_REF_P (TREE_TYPE (t)) |
e01d41e5 | 6755 | || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t))))) |
acf0174b | 6756 | { |
28567c40 JJ |
6757 | error_at (OMP_CLAUSE_LOCATION (c), |
6758 | "linear step expression must be integral"); | |
acf0174b | 6759 | remove = true; |
ee1d5a02 | 6760 | break; |
acf0174b JJ |
6761 | } |
6762 | else | |
6763 | { | |
6764 | t = mark_rvalue_use (t); | |
77886428 | 6765 | if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL) |
e01d41e5 JJ |
6766 | { |
6767 | OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1; | |
6768 | goto check_dup_generic; | |
6769 | } | |
7da8534d JJ |
6770 | if (!processing_template_decl |
6771 | && (VAR_P (OMP_CLAUSE_DECL (c)) | |
6772 | || TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL)) | |
acf0174b | 6773 | { |
77886428 | 6774 | if (ort == C_ORT_OMP_DECLARE_SIMD) |
e01d41e5 JJ |
6775 | { |
6776 | t = maybe_constant_value (t); | |
6777 | if (TREE_CODE (t) != INTEGER_CST) | |
6778 | { | |
6779 | error_at (OMP_CLAUSE_LOCATION (c), | |
6780 | "%<linear%> clause step %qE is neither " | |
6781 | "constant nor a parameter", t); | |
6782 | remove = true; | |
6783 | break; | |
6784 | } | |
6785 | } | |
acf0174b | 6786 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); |
d9a6bd32 | 6787 | tree type = TREE_TYPE (OMP_CLAUSE_DECL (c)); |
9f613f06 | 6788 | if (TYPE_REF_P (type)) |
d9a6bd32 JJ |
6789 | type = TREE_TYPE (type); |
6790 | if (OMP_CLAUSE_LINEAR_KIND (c) == OMP_CLAUSE_LINEAR_REF) | |
6791 | { | |
6792 | type = build_pointer_type (type); | |
6793 | tree d = fold_convert (type, OMP_CLAUSE_DECL (c)); | |
6794 | t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR, | |
6795 | d, t); | |
6796 | t = fold_build2_loc (OMP_CLAUSE_LOCATION (c), | |
a8fc2579 RB |
6797 | MINUS_EXPR, sizetype, |
6798 | fold_convert (sizetype, t), | |
6799 | fold_convert (sizetype, d)); | |
d9a6bd32 JJ |
6800 | if (t == error_mark_node) |
6801 | { | |
6802 | remove = true; | |
6803 | break; | |
6804 | } | |
6805 | } | |
9f613f06 | 6806 | else if (TYPE_PTR_P (type) |
d9a6bd32 JJ |
6807 | /* Can't multiply the step yet if *this |
6808 | is still incomplete type. */ | |
77886428 | 6809 | && (ort != C_ORT_OMP_DECLARE_SIMD |
d9a6bd32 JJ |
6810 | || TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL |
6811 | || !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c)) | |
6812 | || DECL_NAME (OMP_CLAUSE_DECL (c)) | |
6813 | != this_identifier | |
6814 | || !TYPE_BEING_DEFINED (TREE_TYPE (type)))) | |
acf0174b | 6815 | { |
d9a6bd32 | 6816 | tree d = convert_from_reference (OMP_CLAUSE_DECL (c)); |
acf0174b | 6817 | t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR, |
d9a6bd32 | 6818 | d, t); |
acf0174b | 6819 | t = fold_build2_loc (OMP_CLAUSE_LOCATION (c), |
a8fc2579 RB |
6820 | MINUS_EXPR, sizetype, |
6821 | fold_convert (sizetype, t), | |
6822 | fold_convert (sizetype, d)); | |
acf0174b | 6823 | if (t == error_mark_node) |
ee1d5a02 JJ |
6824 | { |
6825 | remove = true; | |
6826 | break; | |
6827 | } | |
acf0174b | 6828 | } |
da6f124d | 6829 | else |
d9a6bd32 | 6830 | t = fold_convert (type, t); |
acf0174b JJ |
6831 | } |
6832 | OMP_CLAUSE_LINEAR_STEP (c) = t; | |
6833 | } | |
1799e5d5 RH |
6834 | goto check_dup_generic; |
6835 | check_dup_generic: | |
d9a6bd32 JJ |
6836 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); |
6837 | if (t) | |
6838 | { | |
e01d41e5 | 6839 | if (!remove && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED) |
d9a6bd32 JJ |
6840 | omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); |
6841 | } | |
6842 | else | |
6843 | t = OMP_CLAUSE_DECL (c); | |
6844 | check_dup_generic_t: | |
6845 | if (t == current_class_ptr | |
519d7496 | 6846 | && ((ort != C_ORT_OMP_DECLARE_SIMD && ort != C_ORT_ACC) |
d9a6bd32 JJ |
6847 | || (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR |
6848 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM))) | |
6849 | { | |
28567c40 JJ |
6850 | error_at (OMP_CLAUSE_LOCATION (c), |
6851 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
6852 | " clauses"); | |
d9a6bd32 JJ |
6853 | remove = true; |
6854 | break; | |
6855 | } | |
6856 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL | |
6857 | && (!field_ok || TREE_CODE (t) != FIELD_DECL)) | |
1799e5d5 | 6858 | { |
cb8d1b01 | 6859 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
1799e5d5 | 6860 | break; |
76dc15d4 | 6861 | if (DECL_P (t)) |
28567c40 JJ |
6862 | error_at (OMP_CLAUSE_LOCATION (c), |
6863 | "%qD is not a variable in clause %qs", t, | |
6864 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
76dc15d4 | 6865 | else |
28567c40 JJ |
6866 | error_at (OMP_CLAUSE_LOCATION (c), |
6867 | "%qE is not a variable in clause %qs", t, | |
6868 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
1799e5d5 RH |
6869 | remove = true; |
6870 | } | |
8860d270 JJ |
6871 | else if ((ort == C_ORT_ACC |
6872 | && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) | |
6873 | || (ort == C_ORT_OMP | |
6874 | && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR | |
6875 | || (OMP_CLAUSE_CODE (c) | |
7619d334 JJ |
6876 | == OMP_CLAUSE_USE_DEVICE_ADDR))) |
6877 | || (ort == C_ORT_OMP_TARGET | |
6878 | && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)) | |
e46c7770 | 6879 | { |
7619d334 JJ |
6880 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION |
6881 | && (bitmap_bit_p (&generic_head, DECL_UID (t)) | |
6882 | || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))) | |
6883 | { | |
6884 | error_at (OMP_CLAUSE_LOCATION (c), | |
6885 | "%qD appears more than once in data-sharing " | |
6886 | "clauses", t); | |
6887 | remove = true; | |
6888 | break; | |
6889 | } | |
6890 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION) | |
6891 | target_in_reduction_seen = true; | |
e46c7770 CP |
6892 | if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t))) |
6893 | { | |
28567c40 | 6894 | error_at (OMP_CLAUSE_LOCATION (c), |
8860d270 JJ |
6895 | ort == C_ORT_ACC |
6896 | ? "%qD appears more than once in reduction clauses" | |
6897 | : "%qD appears more than once in data clauses", | |
28567c40 | 6898 | t); |
e46c7770 CP |
6899 | remove = true; |
6900 | } | |
6901 | else | |
6902 | bitmap_set_bit (&oacc_reduction_head, DECL_UID (t)); | |
6903 | } | |
1799e5d5 RH |
6904 | else if (bitmap_bit_p (&generic_head, DECL_UID (t)) |
6905 | || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) | |
7619d334 JJ |
6906 | || bitmap_bit_p (&lastprivate_head, DECL_UID (t)) |
6907 | || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) | |
1799e5d5 | 6908 | { |
28567c40 JJ |
6909 | error_at (OMP_CLAUSE_LOCATION (c), |
6910 | "%qD appears more than once in data clauses", t); | |
1799e5d5 RH |
6911 | remove = true; |
6912 | } | |
e01d41e5 JJ |
6913 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE |
6914 | && bitmap_bit_p (&map_head, DECL_UID (t))) | |
6915 | { | |
e46c7770 | 6916 | if (ort == C_ORT_ACC) |
28567c40 JJ |
6917 | error_at (OMP_CLAUSE_LOCATION (c), |
6918 | "%qD appears more than once in data clauses", t); | |
e46c7770 | 6919 | else |
28567c40 JJ |
6920 | error_at (OMP_CLAUSE_LOCATION (c), |
6921 | "%qD appears both in data and map clauses", t); | |
e01d41e5 JJ |
6922 | remove = true; |
6923 | } | |
1799e5d5 RH |
6924 | else |
6925 | bitmap_set_bit (&generic_head, DECL_UID (t)); | |
d9a6bd32 JJ |
6926 | if (!field_ok) |
6927 | break; | |
6928 | handle_field_decl: | |
6929 | if (!remove | |
6930 | && TREE_CODE (t) == FIELD_DECL | |
519d7496 | 6931 | && t == OMP_CLAUSE_DECL (c)) |
d9a6bd32 | 6932 | { |
e01d41e5 JJ |
6933 | OMP_CLAUSE_DECL (c) |
6934 | = omp_privatize_field (t, (OMP_CLAUSE_CODE (c) | |
6935 | == OMP_CLAUSE_SHARED)); | |
d9a6bd32 JJ |
6936 | if (OMP_CLAUSE_DECL (c) == error_mark_node) |
6937 | remove = true; | |
6938 | } | |
1799e5d5 RH |
6939 | break; |
6940 | ||
6941 | case OMP_CLAUSE_FIRSTPRIVATE: | |
c94424b0 | 6942 | if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) && !implicit_moved) |
b5c1c7a9 | 6943 | { |
c94424b0 JJ |
6944 | move_implicit: |
6945 | implicit_moved = true; | |
6946 | /* Move firstprivate and map clauses with | |
6947 | OMP_CLAUSE_{FIRSTPRIVATE,MAP}_IMPLICIT set to the end of | |
b5c1c7a9 | 6948 | clauses chain. */ |
c94424b0 JJ |
6949 | tree cl1 = NULL_TREE, cl2 = NULL_TREE; |
6950 | tree *pc1 = pc, *pc2 = &cl1, *pc3 = &cl2; | |
b5c1c7a9 JJ |
6951 | while (*pc1) |
6952 | if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_FIRSTPRIVATE | |
6953 | && OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (*pc1)) | |
c94424b0 JJ |
6954 | { |
6955 | *pc3 = *pc1; | |
6956 | pc3 = &OMP_CLAUSE_CHAIN (*pc3); | |
6957 | *pc1 = OMP_CLAUSE_CHAIN (*pc1); | |
6958 | } | |
6959 | else if (OMP_CLAUSE_CODE (*pc1) == OMP_CLAUSE_MAP | |
6960 | && OMP_CLAUSE_MAP_IMPLICIT (*pc1)) | |
b5c1c7a9 JJ |
6961 | { |
6962 | *pc2 = *pc1; | |
6963 | pc2 = &OMP_CLAUSE_CHAIN (*pc2); | |
6964 | *pc1 = OMP_CLAUSE_CHAIN (*pc1); | |
6965 | } | |
6966 | else | |
6967 | pc1 = &OMP_CLAUSE_CHAIN (*pc1); | |
c94424b0 JJ |
6968 | *pc3 = NULL; |
6969 | *pc2 = cl2; | |
6970 | *pc1 = cl1; | |
6971 | continue; | |
b5c1c7a9 | 6972 | } |
d9a6bd32 JJ |
6973 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); |
6974 | if (t) | |
6975 | omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); | |
6976 | else | |
6977 | t = OMP_CLAUSE_DECL (c); | |
e46c7770 | 6978 | if (ort != C_ORT_ACC && t == current_class_ptr) |
d9a6bd32 | 6979 | { |
28567c40 JJ |
6980 | error_at (OMP_CLAUSE_LOCATION (c), |
6981 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
6982 | " clauses"); | |
d9a6bd32 JJ |
6983 | remove = true; |
6984 | break; | |
6985 | } | |
6986 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL | |
77886428 CP |
6987 | && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP |
6988 | || TREE_CODE (t) != FIELD_DECL)) | |
1799e5d5 | 6989 | { |
cb8d1b01 | 6990 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
1799e5d5 | 6991 | break; |
85b20612 | 6992 | if (DECL_P (t)) |
28567c40 JJ |
6993 | error_at (OMP_CLAUSE_LOCATION (c), |
6994 | "%qD is not a variable in clause %<firstprivate%>", | |
6995 | t); | |
85b20612 | 6996 | else |
28567c40 JJ |
6997 | error_at (OMP_CLAUSE_LOCATION (c), |
6998 | "%qE is not a variable in clause %<firstprivate%>", | |
6999 | t); | |
1799e5d5 RH |
7000 | remove = true; |
7001 | } | |
c94424b0 JJ |
7002 | else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) |
7003 | && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c) | |
7004 | && bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) | |
7005 | remove = true; | |
1799e5d5 | 7006 | else if (bitmap_bit_p (&generic_head, DECL_UID (t)) |
7619d334 JJ |
7007 | || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) |
7008 | || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) | |
1799e5d5 | 7009 | { |
28567c40 JJ |
7010 | error_at (OMP_CLAUSE_LOCATION (c), |
7011 | "%qD appears more than once in data clauses", t); | |
1799e5d5 RH |
7012 | remove = true; |
7013 | } | |
e01d41e5 JJ |
7014 | else if (bitmap_bit_p (&map_head, DECL_UID (t))) |
7015 | { | |
e46c7770 | 7016 | if (ort == C_ORT_ACC) |
28567c40 JJ |
7017 | error_at (OMP_CLAUSE_LOCATION (c), |
7018 | "%qD appears more than once in data clauses", t); | |
b5c1c7a9 JJ |
7019 | else if (OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c) |
7020 | && !OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT_TARGET (c)) | |
7021 | /* Silently drop the clause. */; | |
e46c7770 | 7022 | else |
28567c40 JJ |
7023 | error_at (OMP_CLAUSE_LOCATION (c), |
7024 | "%qD appears both in data and map clauses", t); | |
e01d41e5 JJ |
7025 | remove = true; |
7026 | } | |
1799e5d5 RH |
7027 | else |
7028 | bitmap_set_bit (&firstprivate_head, DECL_UID (t)); | |
d9a6bd32 | 7029 | goto handle_field_decl; |
1799e5d5 RH |
7030 | |
7031 | case OMP_CLAUSE_LASTPRIVATE: | |
d9a6bd32 JJ |
7032 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); |
7033 | if (t) | |
7034 | omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); | |
7035 | else | |
7036 | t = OMP_CLAUSE_DECL (c); | |
519d7496 | 7037 | if (ort != C_ORT_ACC && t == current_class_ptr) |
d9a6bd32 | 7038 | { |
28567c40 JJ |
7039 | error_at (OMP_CLAUSE_LOCATION (c), |
7040 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
7041 | " clauses"); | |
d9a6bd32 JJ |
7042 | remove = true; |
7043 | break; | |
7044 | } | |
7045 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL | |
77886428 CP |
7046 | && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP |
7047 | || TREE_CODE (t) != FIELD_DECL)) | |
1799e5d5 | 7048 | { |
cb8d1b01 | 7049 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
1799e5d5 | 7050 | break; |
85b20612 | 7051 | if (DECL_P (t)) |
28567c40 JJ |
7052 | error_at (OMP_CLAUSE_LOCATION (c), |
7053 | "%qD is not a variable in clause %<lastprivate%>", | |
7054 | t); | |
85b20612 | 7055 | else |
28567c40 JJ |
7056 | error_at (OMP_CLAUSE_LOCATION (c), |
7057 | "%qE is not a variable in clause %<lastprivate%>", | |
7058 | t); | |
1799e5d5 RH |
7059 | remove = true; |
7060 | } | |
7061 | else if (bitmap_bit_p (&generic_head, DECL_UID (t)) | |
7062 | || bitmap_bit_p (&lastprivate_head, DECL_UID (t))) | |
7063 | { | |
28567c40 JJ |
7064 | error_at (OMP_CLAUSE_LOCATION (c), |
7065 | "%qD appears more than once in data clauses", t); | |
1799e5d5 RH |
7066 | remove = true; |
7067 | } | |
7068 | else | |
7069 | bitmap_set_bit (&lastprivate_head, DECL_UID (t)); | |
d9a6bd32 | 7070 | goto handle_field_decl; |
1799e5d5 RH |
7071 | |
7072 | case OMP_CLAUSE_IF: | |
7073 | t = OMP_CLAUSE_IF_EXPR (c); | |
7074 | t = maybe_convert_cond (t); | |
7075 | if (t == error_mark_node) | |
7076 | remove = true; | |
b848354b JJ |
7077 | else if (!processing_template_decl) |
7078 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
1799e5d5 RH |
7079 | OMP_CLAUSE_IF_EXPR (c) = t; |
7080 | break; | |
7081 | ||
20906c66 JJ |
7082 | case OMP_CLAUSE_FINAL: |
7083 | t = OMP_CLAUSE_FINAL_EXPR (c); | |
7084 | t = maybe_convert_cond (t); | |
7085 | if (t == error_mark_node) | |
7086 | remove = true; | |
b848354b JJ |
7087 | else if (!processing_template_decl) |
7088 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
20906c66 JJ |
7089 | OMP_CLAUSE_FINAL_EXPR (c) = t; |
7090 | break; | |
7091 | ||
0d077441 NS |
7092 | case OMP_CLAUSE_GANG: |
7093 | /* Operand 1 is the gang static: argument. */ | |
7094 | t = OMP_CLAUSE_OPERAND (c, 1); | |
7095 | if (t != NULL_TREE) | |
7096 | { | |
7097 | if (t == error_mark_node) | |
7098 | remove = true; | |
7099 | else if (!type_dependent_expression_p (t) | |
7100 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7101 | { | |
28567c40 JJ |
7102 | error_at (OMP_CLAUSE_LOCATION (c), |
7103 | "%<gang%> static expression must be integral"); | |
0d077441 NS |
7104 | remove = true; |
7105 | } | |
7106 | else | |
7107 | { | |
7108 | t = mark_rvalue_use (t); | |
7109 | if (!processing_template_decl) | |
7110 | { | |
7111 | t = maybe_constant_value (t); | |
7112 | if (TREE_CODE (t) == INTEGER_CST | |
7113 | && tree_int_cst_sgn (t) != 1 | |
7114 | && t != integer_minus_one_node) | |
7115 | { | |
7116 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
bd2c6270 | 7117 | "%<gang%> static value must be " |
0d077441 NS |
7118 | "positive"); |
7119 | t = integer_one_node; | |
7120 | } | |
e1bea341 | 7121 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); |
0d077441 | 7122 | } |
0d077441 NS |
7123 | } |
7124 | OMP_CLAUSE_OPERAND (c, 1) = t; | |
7125 | } | |
7126 | /* Check operand 0, the num argument. */ | |
191816a3 | 7127 | /* FALLTHRU */ |
0d077441 NS |
7128 | |
7129 | case OMP_CLAUSE_WORKER: | |
7130 | case OMP_CLAUSE_VECTOR: | |
7131 | if (OMP_CLAUSE_OPERAND (c, 0) == NULL_TREE) | |
7132 | break; | |
191816a3 | 7133 | /* FALLTHRU */ |
0d077441 NS |
7134 | |
7135 | case OMP_CLAUSE_NUM_TASKS: | |
7136 | case OMP_CLAUSE_NUM_TEAMS: | |
1799e5d5 | 7137 | case OMP_CLAUSE_NUM_THREADS: |
0d077441 NS |
7138 | case OMP_CLAUSE_NUM_GANGS: |
7139 | case OMP_CLAUSE_NUM_WORKERS: | |
7140 | case OMP_CLAUSE_VECTOR_LENGTH: | |
7141 | t = OMP_CLAUSE_OPERAND (c, 0); | |
1799e5d5 RH |
7142 | if (t == error_mark_node) |
7143 | remove = true; | |
6e684eee JJ |
7144 | else if (!type_dependent_expression_p (t) |
7145 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
1799e5d5 | 7146 | { |
0d077441 NS |
7147 | switch (OMP_CLAUSE_CODE (c)) |
7148 | { | |
7149 | case OMP_CLAUSE_GANG: | |
7150 | error_at (OMP_CLAUSE_LOCATION (c), | |
7151 | "%<gang%> num expression must be integral"); break; | |
7152 | case OMP_CLAUSE_VECTOR: | |
7153 | error_at (OMP_CLAUSE_LOCATION (c), | |
7154 | "%<vector%> length expression must be integral"); | |
7155 | break; | |
7156 | case OMP_CLAUSE_WORKER: | |
7157 | error_at (OMP_CLAUSE_LOCATION (c), | |
7158 | "%<worker%> num expression must be integral"); | |
7159 | break; | |
7160 | default: | |
7161 | error_at (OMP_CLAUSE_LOCATION (c), | |
7162 | "%qs expression must be integral", | |
7163 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
7164 | } | |
1799e5d5 RH |
7165 | remove = true; |
7166 | } | |
7d1362bc | 7167 | else |
b848354b JJ |
7168 | { |
7169 | t = mark_rvalue_use (t); | |
7170 | if (!processing_template_decl) | |
d9a6bd32 JJ |
7171 | { |
7172 | t = maybe_constant_value (t); | |
7173 | if (TREE_CODE (t) == INTEGER_CST | |
7174 | && tree_int_cst_sgn (t) != 1) | |
7175 | { | |
0d077441 NS |
7176 | switch (OMP_CLAUSE_CODE (c)) |
7177 | { | |
7178 | case OMP_CLAUSE_GANG: | |
7179 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
7180 | "%<gang%> num value must be positive"); | |
7181 | break; | |
7182 | case OMP_CLAUSE_VECTOR: | |
7183 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
bd2c6270 | 7184 | "%<vector%> length value must be " |
0d077441 NS |
7185 | "positive"); |
7186 | break; | |
7187 | case OMP_CLAUSE_WORKER: | |
7188 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
bd2c6270 | 7189 | "%<worker%> num value must be " |
0d077441 NS |
7190 | "positive"); |
7191 | break; | |
7192 | default: | |
7193 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
7194 | "%qs value must be positive", | |
7195 | omp_clause_code_name | |
7196 | [OMP_CLAUSE_CODE (c)]); | |
7197 | } | |
d9a6bd32 JJ |
7198 | t = integer_one_node; |
7199 | } | |
7200 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
7201 | } | |
0d077441 | 7202 | OMP_CLAUSE_OPERAND (c, 0) = t; |
b848354b | 7203 | } |
1799e5d5 RH |
7204 | break; |
7205 | ||
7206 | case OMP_CLAUSE_SCHEDULE: | |
7207 | t = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c); | |
7208 | if (t == NULL) | |
7209 | ; | |
7210 | else if (t == error_mark_node) | |
7211 | remove = true; | |
6e684eee JJ |
7212 | else if (!type_dependent_expression_p (t) |
7213 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
1799e5d5 | 7214 | { |
28567c40 JJ |
7215 | error_at (OMP_CLAUSE_LOCATION (c), |
7216 | "schedule chunk size expression must be integral"); | |
1799e5d5 RH |
7217 | remove = true; |
7218 | } | |
7d1362bc | 7219 | else |
b848354b JJ |
7220 | { |
7221 | t = mark_rvalue_use (t); | |
7222 | if (!processing_template_decl) | |
9a771876 | 7223 | { |
5e9d6aa4 JK |
7224 | t = maybe_constant_value (t); |
7225 | if (TREE_CODE (t) == INTEGER_CST | |
7226 | && tree_int_cst_sgn (t) != 1) | |
7227 | { | |
7228 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
7229 | "chunk size value must be positive"); | |
7230 | t = integer_one_node; | |
7231 | } | |
9a771876 JJ |
7232 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); |
7233 | } | |
b848354b JJ |
7234 | OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; |
7235 | } | |
bf38f7e9 JJ |
7236 | if (!remove) |
7237 | schedule_seen = true; | |
1799e5d5 RH |
7238 | break; |
7239 | ||
acf0174b JJ |
7240 | case OMP_CLAUSE_SIMDLEN: |
7241 | case OMP_CLAUSE_SAFELEN: | |
7242 | t = OMP_CLAUSE_OPERAND (c, 0); | |
7243 | if (t == error_mark_node) | |
7244 | remove = true; | |
7245 | else if (!type_dependent_expression_p (t) | |
7246 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7247 | { | |
28567c40 JJ |
7248 | error_at (OMP_CLAUSE_LOCATION (c), |
7249 | "%qs length expression must be integral", | |
7250 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
7251 | remove = true; |
7252 | } | |
7253 | else | |
7254 | { | |
7255 | t = mark_rvalue_use (t); | |
acf0174b JJ |
7256 | if (!processing_template_decl) |
7257 | { | |
f13e9cd5 | 7258 | t = maybe_constant_value (t); |
acf0174b JJ |
7259 | if (TREE_CODE (t) != INTEGER_CST |
7260 | || tree_int_cst_sgn (t) != 1) | |
7261 | { | |
28567c40 JJ |
7262 | error_at (OMP_CLAUSE_LOCATION (c), |
7263 | "%qs length expression must be positive " | |
7264 | "constant integer expression", | |
7265 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
7266 | remove = true; |
7267 | } | |
7268 | } | |
7269 | OMP_CLAUSE_OPERAND (c, 0) = t; | |
d9a6bd32 JJ |
7270 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SAFELEN) |
7271 | safelen = c; | |
acf0174b JJ |
7272 | } |
7273 | break; | |
7274 | ||
41dbbb37 TS |
7275 | case OMP_CLAUSE_ASYNC: |
7276 | t = OMP_CLAUSE_ASYNC_EXPR (c); | |
7277 | if (t == error_mark_node) | |
7278 | remove = true; | |
7279 | else if (!type_dependent_expression_p (t) | |
7280 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7281 | { | |
28567c40 JJ |
7282 | error_at (OMP_CLAUSE_LOCATION (c), |
7283 | "%<async%> expression must be integral"); | |
41dbbb37 TS |
7284 | remove = true; |
7285 | } | |
7286 | else | |
7287 | { | |
7288 | t = mark_rvalue_use (t); | |
7289 | if (!processing_template_decl) | |
7290 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
7291 | OMP_CLAUSE_ASYNC_EXPR (c) = t; | |
7292 | } | |
7293 | break; | |
7294 | ||
41dbbb37 TS |
7295 | case OMP_CLAUSE_WAIT: |
7296 | t = OMP_CLAUSE_WAIT_EXPR (c); | |
7297 | if (t == error_mark_node) | |
7298 | remove = true; | |
7299 | else if (!processing_template_decl) | |
7300 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
7301 | OMP_CLAUSE_WAIT_EXPR (c) = t; | |
7302 | break; | |
7303 | ||
acf0174b JJ |
7304 | case OMP_CLAUSE_THREAD_LIMIT: |
7305 | t = OMP_CLAUSE_THREAD_LIMIT_EXPR (c); | |
7306 | if (t == error_mark_node) | |
7307 | remove = true; | |
7308 | else if (!type_dependent_expression_p (t) | |
7309 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7310 | { | |
28567c40 JJ |
7311 | error_at (OMP_CLAUSE_LOCATION (c), |
7312 | "%<thread_limit%> expression must be integral"); | |
acf0174b JJ |
7313 | remove = true; |
7314 | } | |
7315 | else | |
7316 | { | |
7317 | t = mark_rvalue_use (t); | |
7318 | if (!processing_template_decl) | |
d9a6bd32 JJ |
7319 | { |
7320 | t = maybe_constant_value (t); | |
7321 | if (TREE_CODE (t) == INTEGER_CST | |
7322 | && tree_int_cst_sgn (t) != 1) | |
7323 | { | |
7324 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
7325 | "%<thread_limit%> value must be positive"); | |
7326 | t = integer_one_node; | |
7327 | } | |
7328 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
7329 | } | |
acf0174b JJ |
7330 | OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t; |
7331 | } | |
7332 | break; | |
7333 | ||
7334 | case OMP_CLAUSE_DEVICE: | |
7335 | t = OMP_CLAUSE_DEVICE_ID (c); | |
7336 | if (t == error_mark_node) | |
7337 | remove = true; | |
7338 | else if (!type_dependent_expression_p (t) | |
7339 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7340 | { | |
28567c40 JJ |
7341 | error_at (OMP_CLAUSE_LOCATION (c), |
7342 | "%<device%> id must be integral"); | |
acf0174b JJ |
7343 | remove = true; |
7344 | } | |
03be3cfe MV |
7345 | else if (OMP_CLAUSE_DEVICE_ANCESTOR (c) |
7346 | && TREE_CODE (t) == INTEGER_CST | |
7347 | && !integer_onep (t)) | |
7348 | { | |
7349 | error_at (OMP_CLAUSE_LOCATION (c), | |
7350 | "the %<device%> clause expression must evaluate to " | |
7351 | "%<1%>"); | |
7352 | remove = true; | |
7353 | } | |
acf0174b JJ |
7354 | else |
7355 | { | |
7356 | t = mark_rvalue_use (t); | |
7357 | if (!processing_template_decl) | |
7358 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
7359 | OMP_CLAUSE_DEVICE_ID (c) = t; | |
7360 | } | |
7361 | break; | |
7362 | ||
7363 | case OMP_CLAUSE_DIST_SCHEDULE: | |
7364 | t = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c); | |
7365 | if (t == NULL) | |
7366 | ; | |
7367 | else if (t == error_mark_node) | |
7368 | remove = true; | |
7369 | else if (!type_dependent_expression_p (t) | |
7370 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7371 | { | |
28567c40 JJ |
7372 | error_at (OMP_CLAUSE_LOCATION (c), |
7373 | "%<dist_schedule%> chunk size expression must be " | |
7374 | "integral"); | |
acf0174b JJ |
7375 | remove = true; |
7376 | } | |
7377 | else | |
7378 | { | |
7379 | t = mark_rvalue_use (t); | |
28567c40 | 7380 | if (!processing_template_decl) |
acf0174b JJ |
7381 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); |
7382 | OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; | |
7383 | } | |
7384 | break; | |
7385 | ||
7386 | case OMP_CLAUSE_ALIGNED: | |
7387 | t = OMP_CLAUSE_DECL (c); | |
77886428 | 7388 | if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD) |
d9a6bd32 | 7389 | { |
28567c40 JJ |
7390 | error_at (OMP_CLAUSE_LOCATION (c), |
7391 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
7392 | " clauses"); | |
d9a6bd32 JJ |
7393 | remove = true; |
7394 | break; | |
7395 | } | |
56a6f1d3 | 7396 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) |
acf0174b | 7397 | { |
cb8d1b01 | 7398 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
acf0174b JJ |
7399 | break; |
7400 | if (DECL_P (t)) | |
28567c40 JJ |
7401 | error_at (OMP_CLAUSE_LOCATION (c), |
7402 | "%qD is not a variable in %<aligned%> clause", t); | |
acf0174b | 7403 | else |
28567c40 JJ |
7404 | error_at (OMP_CLAUSE_LOCATION (c), |
7405 | "%qE is not a variable in %<aligned%> clause", t); | |
acf0174b JJ |
7406 | remove = true; |
7407 | } | |
5a9785fb | 7408 | else if (!type_dependent_expression_p (t) |
9f613f06 | 7409 | && !TYPE_PTR_P (TREE_TYPE (t)) |
5a9785fb | 7410 | && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE |
9f613f06 | 7411 | && (!TYPE_REF_P (TREE_TYPE (t)) |
71a93b08 | 7412 | || (!INDIRECT_TYPE_P (TREE_TYPE (TREE_TYPE (t))) |
5a9785fb JJ |
7413 | && (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) |
7414 | != ARRAY_TYPE)))) | |
7415 | { | |
7416 | error_at (OMP_CLAUSE_LOCATION (c), | |
7417 | "%qE in %<aligned%> clause is neither a pointer nor " | |
7418 | "an array nor a reference to pointer or array", t); | |
7419 | remove = true; | |
7420 | } | |
acf0174b JJ |
7421 | else if (bitmap_bit_p (&aligned_head, DECL_UID (t))) |
7422 | { | |
28567c40 JJ |
7423 | error_at (OMP_CLAUSE_LOCATION (c), |
7424 | "%qD appears more than once in %<aligned%> clauses", | |
7425 | t); | |
acf0174b JJ |
7426 | remove = true; |
7427 | } | |
7428 | else | |
7429 | bitmap_set_bit (&aligned_head, DECL_UID (t)); | |
7430 | t = OMP_CLAUSE_ALIGNED_ALIGNMENT (c); | |
7431 | if (t == error_mark_node) | |
7432 | remove = true; | |
7433 | else if (t == NULL_TREE) | |
7434 | break; | |
7435 | else if (!type_dependent_expression_p (t) | |
7436 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
7437 | { | |
28567c40 JJ |
7438 | error_at (OMP_CLAUSE_LOCATION (c), |
7439 | "%<aligned%> clause alignment expression must " | |
7440 | "be integral"); | |
acf0174b JJ |
7441 | remove = true; |
7442 | } | |
7443 | else | |
7444 | { | |
7445 | t = mark_rvalue_use (t); | |
acf0174b JJ |
7446 | if (!processing_template_decl) |
7447 | { | |
f13e9cd5 | 7448 | t = maybe_constant_value (t); |
acf0174b JJ |
7449 | if (TREE_CODE (t) != INTEGER_CST |
7450 | || tree_int_cst_sgn (t) != 1) | |
7451 | { | |
28567c40 JJ |
7452 | error_at (OMP_CLAUSE_LOCATION (c), |
7453 | "%<aligned%> clause alignment expression must " | |
7454 | "be positive constant integer expression"); | |
acf0174b JJ |
7455 | remove = true; |
7456 | } | |
28567c40 JJ |
7457 | else |
7458 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
acf0174b JJ |
7459 | } |
7460 | OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = t; | |
7461 | } | |
7462 | break; | |
7463 | ||
28567c40 JJ |
7464 | case OMP_CLAUSE_NONTEMPORAL: |
7465 | t = OMP_CLAUSE_DECL (c); | |
7466 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
7467 | { | |
7468 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) | |
7469 | break; | |
7470 | if (DECL_P (t)) | |
7471 | error_at (OMP_CLAUSE_LOCATION (c), | |
7472 | "%qD is not a variable in %<nontemporal%> clause", | |
7473 | t); | |
7474 | else | |
7475 | error_at (OMP_CLAUSE_LOCATION (c), | |
7476 | "%qE is not a variable in %<nontemporal%> clause", | |
7477 | t); | |
7478 | remove = true; | |
7479 | } | |
7480 | else if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t))) | |
7481 | { | |
7482 | error_at (OMP_CLAUSE_LOCATION (c), | |
7483 | "%qD appears more than once in %<nontemporal%> " | |
7484 | "clauses", t); | |
7485 | remove = true; | |
7486 | } | |
7487 | else | |
7488 | bitmap_set_bit (&oacc_reduction_head, DECL_UID (t)); | |
7489 | break; | |
7490 | ||
3a8b2094 | 7491 | case OMP_CLAUSE_ALLOCATE: |
5a6b1d8e JJ |
7492 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); |
7493 | if (t) | |
7494 | omp_note_field_privatization (t, OMP_CLAUSE_DECL (c)); | |
7495 | else | |
7496 | t = OMP_CLAUSE_DECL (c); | |
3a8b2094 JJ |
7497 | if (t == current_class_ptr) |
7498 | { | |
7499 | error_at (OMP_CLAUSE_LOCATION (c), | |
7500 | "%<this%> not allowed in %<allocate%> clause"); | |
7501 | remove = true; | |
7502 | break; | |
7503 | } | |
5a6b1d8e JJ |
7504 | if (!VAR_P (t) |
7505 | && TREE_CODE (t) != PARM_DECL | |
7506 | && TREE_CODE (t) != FIELD_DECL) | |
3a8b2094 JJ |
7507 | { |
7508 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) | |
7509 | break; | |
7510 | if (DECL_P (t)) | |
7511 | error_at (OMP_CLAUSE_LOCATION (c), | |
7512 | "%qD is not a variable in %<allocate%> clause", t); | |
7513 | else | |
7514 | error_at (OMP_CLAUSE_LOCATION (c), | |
7515 | "%qE is not a variable in %<allocate%> clause", t); | |
7516 | remove = true; | |
7517 | } | |
7518 | else if (bitmap_bit_p (&aligned_head, DECL_UID (t))) | |
7519 | { | |
7520 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
7521 | "%qD appears more than once in %<allocate%> clauses", | |
7522 | t); | |
7523 | remove = true; | |
7524 | } | |
7525 | else | |
7526 | { | |
7527 | bitmap_set_bit (&aligned_head, DECL_UID (t)); | |
7528 | allocate_seen = true; | |
7529 | } | |
5a6b1d8e JJ |
7530 | tree allocator; |
7531 | allocator = OMP_CLAUSE_ALLOCATE_ALLOCATOR (c); | |
7532 | if (error_operand_p (allocator)) | |
3a8b2094 JJ |
7533 | { |
7534 | remove = true; | |
7535 | break; | |
7536 | } | |
5a6b1d8e JJ |
7537 | if (allocator == NULL_TREE) |
7538 | goto handle_field_decl; | |
3a8b2094 | 7539 | tree allocatort; |
5a6b1d8e JJ |
7540 | allocatort = TYPE_MAIN_VARIANT (TREE_TYPE (allocator)); |
7541 | if (!type_dependent_expression_p (allocator) | |
3a8b2094 JJ |
7542 | && (TREE_CODE (allocatort) != ENUMERAL_TYPE |
7543 | || TYPE_NAME (allocatort) == NULL_TREE | |
7544 | || TREE_CODE (TYPE_NAME (allocatort)) != TYPE_DECL | |
7545 | || (DECL_NAME (TYPE_NAME (allocatort)) | |
7546 | != get_identifier ("omp_allocator_handle_t")) | |
7547 | || (TYPE_CONTEXT (allocatort) | |
7548 | != DECL_CONTEXT (global_namespace)))) | |
7549 | { | |
7550 | error_at (OMP_CLAUSE_LOCATION (c), | |
7551 | "%<allocate%> clause allocator expression has " | |
7552 | "type %qT rather than %<omp_allocator_handle_t%>", | |
5a6b1d8e | 7553 | TREE_TYPE (allocator)); |
3a8b2094 JJ |
7554 | remove = true; |
7555 | } | |
7556 | else | |
7557 | { | |
5a6b1d8e | 7558 | allocator = mark_rvalue_use (allocator); |
3a8b2094 | 7559 | if (!processing_template_decl) |
5a6b1d8e JJ |
7560 | allocator = maybe_constant_value (allocator); |
7561 | OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator; | |
3a8b2094 | 7562 | } |
5a6b1d8e | 7563 | goto handle_field_decl; |
3a8b2094 | 7564 | |
acf0174b JJ |
7565 | case OMP_CLAUSE_DEPEND: |
7566 | t = OMP_CLAUSE_DECL (c); | |
d9a6bd32 JJ |
7567 | if (t == NULL_TREE) |
7568 | { | |
7569 | gcc_assert (OMP_CLAUSE_DEPEND_KIND (c) | |
7570 | == OMP_CLAUSE_DEPEND_SOURCE); | |
7571 | break; | |
7572 | } | |
098f4e98 | 7573 | if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK) |
d9a6bd32 JJ |
7574 | { |
7575 | if (cp_finish_omp_clause_depend_sink (c)) | |
7576 | remove = true; | |
7577 | break; | |
7578 | } | |
098f4e98 JJ |
7579 | /* FALLTHRU */ |
7580 | case OMP_CLAUSE_AFFINITY: | |
7581 | t = OMP_CLAUSE_DECL (c); | |
28567c40 JJ |
7582 | if (TREE_CODE (t) == TREE_LIST |
7583 | && TREE_PURPOSE (t) | |
7584 | && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) | |
7585 | { | |
7586 | if (TREE_PURPOSE (t) != last_iterators) | |
7587 | last_iterators_remove | |
7588 | = cp_omp_finish_iterators (TREE_PURPOSE (t)); | |
7589 | last_iterators = TREE_PURPOSE (t); | |
7590 | t = TREE_VALUE (t); | |
7591 | if (last_iterators_remove) | |
7592 | t = error_mark_node; | |
7593 | } | |
7594 | else | |
7595 | last_iterators = NULL_TREE; | |
7596 | ||
acf0174b JJ |
7597 | if (TREE_CODE (t) == TREE_LIST) |
7598 | { | |
e46c7770 | 7599 | if (handle_omp_array_sections (c, ort)) |
acf0174b | 7600 | remove = true; |
9a5de4d5 TB |
7601 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND |
7602 | && (OMP_CLAUSE_DEPEND_KIND (c) | |
7603 | == OMP_CLAUSE_DEPEND_DEPOBJ)) | |
28567c40 JJ |
7604 | { |
7605 | error_at (OMP_CLAUSE_LOCATION (c), | |
7606 | "%<depend%> clause with %<depobj%> dependence " | |
7607 | "type on array section"); | |
7608 | remove = true; | |
7609 | } | |
acf0174b JJ |
7610 | break; |
7611 | } | |
7612 | if (t == error_mark_node) | |
7613 | remove = true; | |
28567c40 JJ |
7614 | else if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
7615 | break; | |
7616 | else if (!lvalue_p (t)) | |
acf0174b | 7617 | { |
acf0174b | 7618 | if (DECL_P (t)) |
28567c40 JJ |
7619 | error_at (OMP_CLAUSE_LOCATION (c), |
7620 | "%qD is not lvalue expression nor array section " | |
9a5de4d5 TB |
7621 | "in %qs clause", t, |
7622 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b | 7623 | else |
28567c40 JJ |
7624 | error_at (OMP_CLAUSE_LOCATION (c), |
7625 | "%qE is not lvalue expression nor array section " | |
9a5de4d5 TB |
7626 | "in %qs clause", t, |
7627 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
7628 | remove = true; |
7629 | } | |
28567c40 JJ |
7630 | else if (TREE_CODE (t) == COMPONENT_REF |
7631 | && TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL | |
7632 | && DECL_BIT_FIELD (TREE_OPERAND (t, 1))) | |
d9a6bd32 | 7633 | { |
28567c40 | 7634 | error_at (OMP_CLAUSE_LOCATION (c), |
9a5de4d5 | 7635 | "bit-field %qE in %qs clause", t, |
098f4e98 | 7636 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); |
d9a6bd32 JJ |
7637 | remove = true; |
7638 | } | |
9a5de4d5 TB |
7639 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND |
7640 | && OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_DEPOBJ) | |
28567c40 JJ |
7641 | { |
7642 | if (!c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t)) | |
7643 | ? TREE_TYPE (TREE_TYPE (t)) | |
7644 | : TREE_TYPE (t))) | |
7645 | { | |
7646 | error_at (OMP_CLAUSE_LOCATION (c), | |
7647 | "%qE does not have %<omp_depend_t%> type in " | |
7648 | "%<depend%> clause with %<depobj%> dependence " | |
7649 | "type", t); | |
7650 | remove = true; | |
7651 | } | |
7652 | } | |
9a5de4d5 TB |
7653 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND |
7654 | && c_omp_depend_t_p (TYPE_REF_P (TREE_TYPE (t)) | |
7655 | ? TREE_TYPE (TREE_TYPE (t)) | |
7656 | : TREE_TYPE (t))) | |
28567c40 JJ |
7657 | { |
7658 | error_at (OMP_CLAUSE_LOCATION (c), | |
7659 | "%qE should not have %<omp_depend_t%> type in " | |
7660 | "%<depend%> clause with dependence type other than " | |
7661 | "%<depobj%>", t); | |
7662 | remove = true; | |
7663 | } | |
7664 | if (!remove) | |
7665 | { | |
7666 | tree addr = cp_build_addr_expr (t, tf_warning_or_error); | |
7667 | if (addr == error_mark_node) | |
7668 | remove = true; | |
7669 | else | |
7670 | { | |
3554d8ff PC |
7671 | t = cp_build_indirect_ref (OMP_CLAUSE_LOCATION (c), |
7672 | addr, RO_UNARY_STAR, | |
28567c40 JJ |
7673 | tf_warning_or_error); |
7674 | if (t == error_mark_node) | |
7675 | remove = true; | |
7676 | else if (TREE_CODE (OMP_CLAUSE_DECL (c)) == TREE_LIST | |
7677 | && TREE_PURPOSE (OMP_CLAUSE_DECL (c)) | |
7678 | && (TREE_CODE (TREE_PURPOSE (OMP_CLAUSE_DECL (c))) | |
7679 | == TREE_VEC)) | |
7680 | TREE_VALUE (OMP_CLAUSE_DECL (c)) = t; | |
7681 | else | |
7682 | OMP_CLAUSE_DECL (c) = t; | |
7683 | } | |
7684 | } | |
acf0174b | 7685 | break; |
a6d22fb2 KCY |
7686 | case OMP_CLAUSE_DETACH: |
7687 | t = OMP_CLAUSE_DECL (c); | |
7688 | if (detach_seen) | |
7689 | { | |
7690 | error_at (OMP_CLAUSE_LOCATION (c), | |
7691 | "too many %qs clauses on a task construct", | |
7692 | "detach"); | |
7693 | remove = true; | |
7694 | break; | |
7695 | } | |
7ab1abf3 JJ |
7696 | else if (error_operand_p (t)) |
7697 | { | |
7698 | remove = true; | |
7699 | break; | |
7700 | } | |
a6d22fb2 KCY |
7701 | else |
7702 | { | |
7703 | tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t)); | |
7704 | if (!type_dependent_expression_p (t) | |
7705 | && (!INTEGRAL_TYPE_P (type) | |
7706 | || TREE_CODE (type) != ENUMERAL_TYPE | |
7ab1abf3 | 7707 | || TYPE_NAME (type) == NULL_TREE |
a6d22fb2 KCY |
7708 | || (DECL_NAME (TYPE_NAME (type)) |
7709 | != get_identifier ("omp_event_handle_t")))) | |
7710 | { | |
7711 | error_at (OMP_CLAUSE_LOCATION (c), | |
7712 | "%<detach%> clause event handle " | |
7713 | "has type %qT rather than " | |
7714 | "%<omp_event_handle_t%>", | |
7715 | type); | |
7716 | remove = true; | |
7717 | } | |
1b462dea | 7718 | detach_seen = c; |
a6d22fb2 KCY |
7719 | cxx_mark_addressable (t); |
7720 | } | |
7721 | break; | |
acf0174b JJ |
7722 | |
7723 | case OMP_CLAUSE_MAP: | |
c94424b0 JJ |
7724 | if (OMP_CLAUSE_MAP_IMPLICIT (c) && !implicit_moved) |
7725 | goto move_implicit; | |
7726 | /* FALLTHRU */ | |
acf0174b JJ |
7727 | case OMP_CLAUSE_TO: |
7728 | case OMP_CLAUSE_FROM: | |
41dbbb37 | 7729 | case OMP_CLAUSE__CACHE_: |
acf0174b JJ |
7730 | t = OMP_CLAUSE_DECL (c); |
7731 | if (TREE_CODE (t) == TREE_LIST) | |
7732 | { | |
e46c7770 | 7733 | if (handle_omp_array_sections (c, ort)) |
acf0174b JJ |
7734 | remove = true; |
7735 | else | |
7736 | { | |
7737 | t = OMP_CLAUSE_DECL (c); | |
bce16b88 JJ |
7738 | if (TREE_CODE (t) != TREE_LIST |
7739 | && !type_dependent_expression_p (t) | |
7740 | && !cp_omp_mappable_type (TREE_TYPE (t))) | |
acf0174b JJ |
7741 | { |
7742 | error_at (OMP_CLAUSE_LOCATION (c), | |
7743 | "array section does not have mappable type " | |
7744 | "in %qs clause", | |
7745 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8862ed13 | 7746 | cp_omp_emit_unmappable_type_notes (TREE_TYPE (t)); |
acf0174b JJ |
7747 | remove = true; |
7748 | } | |
d9a6bd32 JJ |
7749 | while (TREE_CODE (t) == ARRAY_REF) |
7750 | t = TREE_OPERAND (t, 0); | |
7751 | if (TREE_CODE (t) == COMPONENT_REF | |
7752 | && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) | |
7753 | { | |
7754 | while (TREE_CODE (t) == COMPONENT_REF) | |
7755 | t = TREE_OPERAND (t, 0); | |
9b6a8d0f JJ |
7756 | if (REFERENCE_REF_P (t)) |
7757 | t = TREE_OPERAND (t, 0); | |
c94424b0 JJ |
7758 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
7759 | && OMP_CLAUSE_MAP_IMPLICIT (c) | |
7760 | && (bitmap_bit_p (&map_head, DECL_UID (t)) | |
7761 | || bitmap_bit_p (&map_field_head, DECL_UID (t)) | |
7762 | || bitmap_bit_p (&map_firstprivate_head, | |
7763 | DECL_UID (t)))) | |
7764 | { | |
7765 | remove = true; | |
7766 | break; | |
7767 | } | |
d9a6bd32 JJ |
7768 | if (bitmap_bit_p (&map_field_head, DECL_UID (t))) |
7769 | break; | |
7770 | if (bitmap_bit_p (&map_head, DECL_UID (t))) | |
7771 | { | |
7772 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) | |
28567c40 JJ |
7773 | error_at (OMP_CLAUSE_LOCATION (c), |
7774 | "%qD appears more than once in motion" | |
7775 | " clauses", t); | |
e46c7770 | 7776 | else if (ort == C_ORT_ACC) |
28567c40 JJ |
7777 | error_at (OMP_CLAUSE_LOCATION (c), |
7778 | "%qD appears more than once in data" | |
7779 | " clauses", t); | |
d9a6bd32 | 7780 | else |
28567c40 JJ |
7781 | error_at (OMP_CLAUSE_LOCATION (c), |
7782 | "%qD appears more than once in map" | |
7783 | " clauses", t); | |
d9a6bd32 JJ |
7784 | remove = true; |
7785 | } | |
7786 | else | |
7787 | { | |
7788 | bitmap_set_bit (&map_head, DECL_UID (t)); | |
7789 | bitmap_set_bit (&map_field_head, DECL_UID (t)); | |
7790 | } | |
7791 | } | |
acf0174b | 7792 | } |
519d7496 JB |
7793 | if (cp_oacc_check_attachments (c)) |
7794 | remove = true; | |
0d00fe40 JB |
7795 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
7796 | && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH | |
7797 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)) | |
7798 | /* In this case, we have a single array element which is a | |
7799 | pointer, and we already set OMP_CLAUSE_SIZE in | |
7800 | handle_omp_array_sections above. For attach/detach clauses, | |
7801 | reset the OMP_CLAUSE_SIZE (representing a bias) to zero | |
7802 | here. */ | |
7803 | OMP_CLAUSE_SIZE (c) = size_zero_node; | |
acf0174b JJ |
7804 | break; |
7805 | } | |
7806 | if (t == error_mark_node) | |
d9a6bd32 JJ |
7807 | { |
7808 | remove = true; | |
7809 | break; | |
7810 | } | |
519d7496 JB |
7811 | /* OpenACC attach / detach clauses must be pointers. */ |
7812 | if (cp_oacc_check_attachments (c)) | |
7813 | { | |
7814 | remove = true; | |
7815 | break; | |
7816 | } | |
0d00fe40 JB |
7817 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
7818 | && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH | |
7819 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_DETACH)) | |
7820 | /* For attach/detach clauses, set OMP_CLAUSE_SIZE (representing a | |
7821 | bias) to zero here, so it is not set erroneously to the pointer | |
7822 | size later on in gimplify.c. */ | |
7823 | OMP_CLAUSE_SIZE (c) = size_zero_node; | |
d9a6bd32 JJ |
7824 | if (REFERENCE_REF_P (t) |
7825 | && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF) | |
e01d41e5 JJ |
7826 | { |
7827 | t = TREE_OPERAND (t, 0); | |
7828 | OMP_CLAUSE_DECL (c) = t; | |
7829 | } | |
7619d334 | 7830 | if (TREE_CODE (t) == COMPONENT_REF |
519d7496 JB |
7831 | && TREE_CODE (TREE_OPERAND (t, 0)) == INDIRECT_REF) |
7832 | t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); | |
d9a6bd32 | 7833 | if (TREE_CODE (t) == COMPONENT_REF |
d9a6bd32 JJ |
7834 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_) |
7835 | { | |
7836 | if (type_dependent_expression_p (t)) | |
7837 | break; | |
283635f9 JJ |
7838 | if (TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL |
7839 | && DECL_BIT_FIELD (TREE_OPERAND (t, 1))) | |
d9a6bd32 JJ |
7840 | { |
7841 | error_at (OMP_CLAUSE_LOCATION (c), | |
7842 | "bit-field %qE in %qs clause", | |
7843 | t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
7844 | remove = true; | |
7845 | } | |
7846 | else if (!cp_omp_mappable_type (TREE_TYPE (t))) | |
7847 | { | |
7848 | error_at (OMP_CLAUSE_LOCATION (c), | |
7849 | "%qE does not have a mappable type in %qs clause", | |
7850 | t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8862ed13 | 7851 | cp_omp_emit_unmappable_type_notes (TREE_TYPE (t)); |
d9a6bd32 JJ |
7852 | remove = true; |
7853 | } | |
7854 | while (TREE_CODE (t) == COMPONENT_REF) | |
7855 | { | |
283635f9 JJ |
7856 | if (TREE_TYPE (TREE_OPERAND (t, 0)) |
7857 | && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) | |
7858 | == UNION_TYPE)) | |
d9a6bd32 JJ |
7859 | { |
7860 | error_at (OMP_CLAUSE_LOCATION (c), | |
7861 | "%qE is a member of a union", t); | |
7862 | remove = true; | |
7863 | break; | |
7864 | } | |
7865 | t = TREE_OPERAND (t, 0); | |
7866 | } | |
7867 | if (remove) | |
7868 | break; | |
283635f9 JJ |
7869 | if (REFERENCE_REF_P (t)) |
7870 | t = TREE_OPERAND (t, 0); | |
d9a6bd32 JJ |
7871 | if (VAR_P (t) || TREE_CODE (t) == PARM_DECL) |
7872 | { | |
9e628024 | 7873 | if (bitmap_bit_p (&map_field_head, DECL_UID (t)) |
7619d334 | 7874 | || (ort != C_ORT_ACC |
9e628024 | 7875 | && bitmap_bit_p (&map_head, DECL_UID (t)))) |
e01d41e5 | 7876 | goto handle_map_references; |
d9a6bd32 JJ |
7877 | } |
7878 | } | |
7879 | if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
acf0174b | 7880 | { |
cb8d1b01 | 7881 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) |
acf0174b JJ |
7882 | break; |
7883 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP | |
e01d41e5 | 7884 | && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER |
519d7496 JB |
7885 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ALWAYS_POINTER |
7886 | || OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_ATTACH_DETACH)) | |
acf0174b JJ |
7887 | break; |
7888 | if (DECL_P (t)) | |
28567c40 JJ |
7889 | error_at (OMP_CLAUSE_LOCATION (c), |
7890 | "%qD is not a variable in %qs clause", t, | |
7891 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b | 7892 | else |
28567c40 JJ |
7893 | error_at (OMP_CLAUSE_LOCATION (c), |
7894 | "%qE is not a variable in %qs clause", t, | |
7895 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
7896 | remove = true; |
7897 | } | |
3048c0c7 | 7898 | else if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) |
acf0174b | 7899 | { |
28567c40 JJ |
7900 | error_at (OMP_CLAUSE_LOCATION (c), |
7901 | "%qD is threadprivate variable in %qs clause", t, | |
7902 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
acf0174b JJ |
7903 | remove = true; |
7904 | } | |
e46c7770 | 7905 | else if (ort != C_ORT_ACC && t == current_class_ptr) |
d9a6bd32 | 7906 | { |
28567c40 JJ |
7907 | error_at (OMP_CLAUSE_LOCATION (c), |
7908 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
7909 | " clauses"); | |
d9a6bd32 JJ |
7910 | remove = true; |
7911 | break; | |
7912 | } | |
acf0174b | 7913 | else if (!processing_template_decl |
9f613f06 | 7914 | && !TYPE_REF_P (TREE_TYPE (t)) |
e4606348 JJ |
7915 | && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP |
7916 | || (OMP_CLAUSE_MAP_KIND (c) | |
7917 | != GOMP_MAP_FIRSTPRIVATE_POINTER)) | |
acf0174b JJ |
7918 | && !cxx_mark_addressable (t)) |
7919 | remove = true; | |
7920 | else if (!(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP | |
d9a6bd32 JJ |
7921 | && (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER |
7922 | || (OMP_CLAUSE_MAP_KIND (c) | |
7923 | == GOMP_MAP_FIRSTPRIVATE_POINTER))) | |
7924 | && t == OMP_CLAUSE_DECL (c) | |
bce16b88 | 7925 | && !type_dependent_expression_p (t) |
9f613f06 | 7926 | && !cp_omp_mappable_type (TYPE_REF_P (TREE_TYPE (t)) |
acf0174b JJ |
7927 | ? TREE_TYPE (TREE_TYPE (t)) |
7928 | : TREE_TYPE (t))) | |
7929 | { | |
7930 | error_at (OMP_CLAUSE_LOCATION (c), | |
7931 | "%qD does not have a mappable type in %qs clause", t, | |
7932 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8862ed13 | 7933 | cp_omp_emit_unmappable_type_notes (TREE_TYPE (t)); |
acf0174b JJ |
7934 | remove = true; |
7935 | } | |
d9a6bd32 | 7936 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
ba539195 JN |
7937 | && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_DEVICEPTR |
7938 | && !type_dependent_expression_p (t) | |
71a93b08 | 7939 | && !INDIRECT_TYPE_P (TREE_TYPE (t))) |
ba539195 | 7940 | { |
28567c40 JJ |
7941 | error_at (OMP_CLAUSE_LOCATION (c), |
7942 | "%qD is not a pointer variable", t); | |
ba539195 JN |
7943 | remove = true; |
7944 | } | |
c94424b0 JJ |
7945 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
7946 | && OMP_CLAUSE_MAP_IMPLICIT (c) | |
7947 | && (bitmap_bit_p (&map_head, DECL_UID (t)) | |
7948 | || bitmap_bit_p (&map_field_head, DECL_UID (t)) | |
7949 | || bitmap_bit_p (&map_firstprivate_head, | |
7950 | DECL_UID (t)))) | |
7951 | remove = true; | |
ba539195 | 7952 | else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP |
d9a6bd32 JJ |
7953 | && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FIRSTPRIVATE_POINTER) |
7954 | { | |
7955 | if (bitmap_bit_p (&generic_head, DECL_UID (t)) | |
7619d334 JJ |
7956 | || bitmap_bit_p (&firstprivate_head, DECL_UID (t)) |
7957 | || bitmap_bit_p (&map_firstprivate_head, DECL_UID (t))) | |
d9a6bd32 | 7958 | { |
28567c40 JJ |
7959 | error_at (OMP_CLAUSE_LOCATION (c), |
7960 | "%qD appears more than once in data clauses", t); | |
d9a6bd32 JJ |
7961 | remove = true; |
7962 | } | |
e01d41e5 | 7963 | else if (bitmap_bit_p (&map_head, DECL_UID (t))) |
d9a6bd32 | 7964 | { |
e46c7770 | 7965 | if (ort == C_ORT_ACC) |
28567c40 JJ |
7966 | error_at (OMP_CLAUSE_LOCATION (c), |
7967 | "%qD appears more than once in data clauses", t); | |
e46c7770 | 7968 | else |
28567c40 JJ |
7969 | error_at (OMP_CLAUSE_LOCATION (c), |
7970 | "%qD appears both in data and map clauses", t); | |
e01d41e5 | 7971 | remove = true; |
d9a6bd32 | 7972 | } |
e01d41e5 | 7973 | else |
7619d334 | 7974 | bitmap_set_bit (&map_firstprivate_head, DECL_UID (t)); |
d9a6bd32 | 7975 | } |
519d7496 | 7976 | else if (bitmap_bit_p (&map_head, DECL_UID (t)) |
9e628024 | 7977 | && !bitmap_bit_p (&map_field_head, DECL_UID (t))) |
acf0174b JJ |
7978 | { |
7979 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) | |
28567c40 JJ |
7980 | error_at (OMP_CLAUSE_LOCATION (c), |
7981 | "%qD appears more than once in motion clauses", t); | |
9e628024 | 7982 | else if (ort == C_ORT_ACC) |
28567c40 JJ |
7983 | error_at (OMP_CLAUSE_LOCATION (c), |
7984 | "%qD appears more than once in data clauses", t); | |
acf0174b | 7985 | else |
28567c40 JJ |
7986 | error_at (OMP_CLAUSE_LOCATION (c), |
7987 | "%qD appears more than once in map clauses", t); | |
acf0174b JJ |
7988 | remove = true; |
7989 | } | |
7619d334 JJ |
7990 | else if (ort == C_ORT_ACC |
7991 | && bitmap_bit_p (&generic_head, DECL_UID (t))) | |
9e628024 CLT |
7992 | { |
7993 | error_at (OMP_CLAUSE_LOCATION (c), | |
7994 | "%qD appears more than once in data clauses", t); | |
7995 | remove = true; | |
7996 | } | |
7997 | else if (bitmap_bit_p (&firstprivate_head, DECL_UID (t))) | |
e01d41e5 | 7998 | { |
e46c7770 | 7999 | if (ort == C_ORT_ACC) |
28567c40 JJ |
8000 | error_at (OMP_CLAUSE_LOCATION (c), |
8001 | "%qD appears more than once in data clauses", t); | |
e46c7770 | 8002 | else |
28567c40 JJ |
8003 | error_at (OMP_CLAUSE_LOCATION (c), |
8004 | "%qD appears both in data and map clauses", t); | |
e01d41e5 JJ |
8005 | remove = true; |
8006 | } | |
acf0174b | 8007 | else |
d9a6bd32 JJ |
8008 | { |
8009 | bitmap_set_bit (&map_head, DECL_UID (t)); | |
8010 | if (t != OMP_CLAUSE_DECL (c) | |
8011 | && TREE_CODE (OMP_CLAUSE_DECL (c)) == COMPONENT_REF) | |
8012 | bitmap_set_bit (&map_field_head, DECL_UID (t)); | |
8013 | } | |
e01d41e5 JJ |
8014 | handle_map_references: |
8015 | if (!remove | |
8016 | && !processing_template_decl | |
8e36332c | 8017 | && ort != C_ORT_DECLARE_SIMD |
9f613f06 | 8018 | && TYPE_REF_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))) |
e01d41e5 JJ |
8019 | { |
8020 | t = OMP_CLAUSE_DECL (c); | |
8021 | if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_MAP) | |
8022 | { | |
8023 | OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t); | |
8024 | if (OMP_CLAUSE_SIZE (c) == NULL_TREE) | |
8025 | OMP_CLAUSE_SIZE (c) | |
8026 | = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))); | |
8027 | } | |
8028 | else if (OMP_CLAUSE_MAP_KIND (c) | |
8029 | != GOMP_MAP_FIRSTPRIVATE_POINTER | |
8030 | && (OMP_CLAUSE_MAP_KIND (c) | |
8031 | != GOMP_MAP_FIRSTPRIVATE_REFERENCE) | |
8032 | && (OMP_CLAUSE_MAP_KIND (c) | |
9e628024 CLT |
8033 | != GOMP_MAP_ALWAYS_POINTER) |
8034 | && (OMP_CLAUSE_MAP_KIND (c) | |
8035 | != GOMP_MAP_ATTACH_DETACH)) | |
e01d41e5 JJ |
8036 | { |
8037 | tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), | |
8038 | OMP_CLAUSE_MAP); | |
8039 | if (TREE_CODE (t) == COMPONENT_REF) | |
9e628024 | 8040 | OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH); |
e01d41e5 JJ |
8041 | else |
8042 | OMP_CLAUSE_SET_MAP_KIND (c2, | |
8043 | GOMP_MAP_FIRSTPRIVATE_REFERENCE); | |
8044 | OMP_CLAUSE_DECL (c2) = t; | |
8045 | OMP_CLAUSE_SIZE (c2) = size_zero_node; | |
8046 | OMP_CLAUSE_CHAIN (c2) = OMP_CLAUSE_CHAIN (c); | |
8047 | OMP_CLAUSE_CHAIN (c) = c2; | |
8048 | OMP_CLAUSE_DECL (c) = build_simple_mem_ref (t); | |
8049 | if (OMP_CLAUSE_SIZE (c) == NULL_TREE) | |
8050 | OMP_CLAUSE_SIZE (c) | |
8051 | = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))); | |
8052 | c = c2; | |
8053 | } | |
8054 | } | |
d9a6bd32 JJ |
8055 | break; |
8056 | ||
8057 | case OMP_CLAUSE_TO_DECLARE: | |
d9a6bd32 JJ |
8058 | case OMP_CLAUSE_LINK: |
8059 | t = OMP_CLAUSE_DECL (c); | |
e01d41e5 JJ |
8060 | if (TREE_CODE (t) == FUNCTION_DECL |
8061 | && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) | |
8062 | ; | |
8063 | else if (!VAR_P (t)) | |
d9a6bd32 | 8064 | { |
e01d41e5 JJ |
8065 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TO_DECLARE) |
8066 | { | |
1f0ed17c | 8067 | if (TREE_CODE (t) == TEMPLATE_ID_EXPR) |
e01d41e5 | 8068 | error_at (OMP_CLAUSE_LOCATION (c), |
1f0ed17c | 8069 | "template %qE in clause %qs", t, |
e01d41e5 | 8070 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); |
1f0ed17c | 8071 | else if (really_overloaded_fn (t)) |
e01d41e5 | 8072 | error_at (OMP_CLAUSE_LOCATION (c), |
1f0ed17c | 8073 | "overloaded function name %qE in clause %qs", t, |
e01d41e5 JJ |
8074 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); |
8075 | else | |
8076 | error_at (OMP_CLAUSE_LOCATION (c), | |
8077 | "%qE is neither a variable nor a function name " | |
8078 | "in clause %qs", t, | |
8079 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8080 | } | |
8081 | else | |
8082 | error_at (OMP_CLAUSE_LOCATION (c), | |
8083 | "%qE is not a variable in clause %qs", t, | |
8084 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
d9a6bd32 JJ |
8085 | remove = true; |
8086 | } | |
8087 | else if (DECL_THREAD_LOCAL_P (t)) | |
8088 | { | |
8089 | error_at (OMP_CLAUSE_LOCATION (c), | |
8090 | "%qD is threadprivate variable in %qs clause", t, | |
8091 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8092 | remove = true; | |
8093 | } | |
8094 | else if (!cp_omp_mappable_type (TREE_TYPE (t))) | |
8095 | { | |
8096 | error_at (OMP_CLAUSE_LOCATION (c), | |
8097 | "%qD does not have a mappable type in %qs clause", t, | |
8098 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8862ed13 | 8099 | cp_omp_emit_unmappable_type_notes (TREE_TYPE (t)); |
d9a6bd32 JJ |
8100 | remove = true; |
8101 | } | |
e01d41e5 JJ |
8102 | if (remove) |
8103 | break; | |
8104 | if (bitmap_bit_p (&generic_head, DECL_UID (t))) | |
8105 | { | |
8106 | error_at (OMP_CLAUSE_LOCATION (c), | |
8107 | "%qE appears more than once on the same " | |
8108 | "%<declare target%> directive", t); | |
8109 | remove = true; | |
8110 | } | |
8111 | else | |
8112 | bitmap_set_bit (&generic_head, DECL_UID (t)); | |
acf0174b JJ |
8113 | break; |
8114 | ||
8115 | case OMP_CLAUSE_UNIFORM: | |
8116 | t = OMP_CLAUSE_DECL (c); | |
8117 | if (TREE_CODE (t) != PARM_DECL) | |
8118 | { | |
8119 | if (processing_template_decl) | |
8120 | break; | |
8121 | if (DECL_P (t)) | |
28567c40 JJ |
8122 | error_at (OMP_CLAUSE_LOCATION (c), |
8123 | "%qD is not an argument in %<uniform%> clause", t); | |
acf0174b | 8124 | else |
28567c40 JJ |
8125 | error_at (OMP_CLAUSE_LOCATION (c), |
8126 | "%qE is not an argument in %<uniform%> clause", t); | |
acf0174b | 8127 | remove = true; |
ee1d5a02 | 8128 | break; |
acf0174b | 8129 | } |
e01d41e5 JJ |
8130 | /* map_head bitmap is used as uniform_head if declare_simd. */ |
8131 | bitmap_set_bit (&map_head, DECL_UID (t)); | |
ee1d5a02 | 8132 | goto check_dup_generic; |
acf0174b | 8133 | |
d9a6bd32 JJ |
8134 | case OMP_CLAUSE_GRAINSIZE: |
8135 | t = OMP_CLAUSE_GRAINSIZE_EXPR (c); | |
8136 | if (t == error_mark_node) | |
8137 | remove = true; | |
8138 | else if (!type_dependent_expression_p (t) | |
8139 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
8140 | { | |
28567c40 JJ |
8141 | error_at (OMP_CLAUSE_LOCATION (c), |
8142 | "%<grainsize%> expression must be integral"); | |
d9a6bd32 JJ |
8143 | remove = true; |
8144 | } | |
8145 | else | |
8146 | { | |
8147 | t = mark_rvalue_use (t); | |
8148 | if (!processing_template_decl) | |
8149 | { | |
8150 | t = maybe_constant_value (t); | |
8151 | if (TREE_CODE (t) == INTEGER_CST | |
8152 | && tree_int_cst_sgn (t) != 1) | |
8153 | { | |
8154 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
8155 | "%<grainsize%> value must be positive"); | |
8156 | t = integer_one_node; | |
8157 | } | |
8158 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
8159 | } | |
8160 | OMP_CLAUSE_GRAINSIZE_EXPR (c) = t; | |
8161 | } | |
8162 | break; | |
8163 | ||
8164 | case OMP_CLAUSE_PRIORITY: | |
8165 | t = OMP_CLAUSE_PRIORITY_EXPR (c); | |
8166 | if (t == error_mark_node) | |
8167 | remove = true; | |
8168 | else if (!type_dependent_expression_p (t) | |
8169 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
8170 | { | |
28567c40 JJ |
8171 | error_at (OMP_CLAUSE_LOCATION (c), |
8172 | "%<priority%> expression must be integral"); | |
d9a6bd32 JJ |
8173 | remove = true; |
8174 | } | |
8175 | else | |
8176 | { | |
8177 | t = mark_rvalue_use (t); | |
8178 | if (!processing_template_decl) | |
8179 | { | |
8180 | t = maybe_constant_value (t); | |
8181 | if (TREE_CODE (t) == INTEGER_CST | |
8182 | && tree_int_cst_sgn (t) == -1) | |
8183 | { | |
8184 | warning_at (OMP_CLAUSE_LOCATION (c), 0, | |
8185 | "%<priority%> value must be non-negative"); | |
8186 | t = integer_one_node; | |
8187 | } | |
8188 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
8189 | } | |
8190 | OMP_CLAUSE_PRIORITY_EXPR (c) = t; | |
8191 | } | |
8192 | break; | |
8193 | ||
8194 | case OMP_CLAUSE_HINT: | |
8195 | t = OMP_CLAUSE_HINT_EXPR (c); | |
8196 | if (t == error_mark_node) | |
8197 | remove = true; | |
8198 | else if (!type_dependent_expression_p (t) | |
8199 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
8200 | { | |
28567c40 JJ |
8201 | error_at (OMP_CLAUSE_LOCATION (c), |
8202 | "%<hint%> expression must be integral"); | |
d9a6bd32 JJ |
8203 | remove = true; |
8204 | } | |
8205 | else | |
8206 | { | |
8207 | t = mark_rvalue_use (t); | |
8208 | if (!processing_template_decl) | |
8209 | { | |
8210 | t = maybe_constant_value (t); | |
8211 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
28567c40 JJ |
8212 | if (TREE_CODE (t) != INTEGER_CST) |
8213 | { | |
8214 | error_at (OMP_CLAUSE_LOCATION (c), | |
8215 | "%<hint%> expression must be constant integer " | |
8216 | "expression"); | |
8217 | remove = true; | |
8218 | } | |
d9a6bd32 JJ |
8219 | } |
8220 | OMP_CLAUSE_HINT_EXPR (c) = t; | |
8221 | } | |
8222 | break; | |
d0befed7 JJ |
8223 | |
8224 | case OMP_CLAUSE_FILTER: | |
8225 | t = OMP_CLAUSE_FILTER_EXPR (c); | |
8226 | if (t == error_mark_node) | |
8227 | remove = true; | |
8228 | else if (!type_dependent_expression_p (t) | |
8229 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
8230 | { | |
8231 | error_at (OMP_CLAUSE_LOCATION (c), | |
8232 | "%<filter%> expression must be integral"); | |
8233 | remove = true; | |
8234 | } | |
8235 | else | |
8236 | { | |
8237 | t = mark_rvalue_use (t); | |
8238 | if (!processing_template_decl) | |
8239 | { | |
8240 | t = maybe_constant_value (t); | |
8241 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
8242 | } | |
8243 | OMP_CLAUSE_FILTER_EXPR (c) = t; | |
8244 | } | |
8245 | break; | |
d9a6bd32 JJ |
8246 | |
8247 | case OMP_CLAUSE_IS_DEVICE_PTR: | |
8248 | case OMP_CLAUSE_USE_DEVICE_PTR: | |
77886428 | 8249 | field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP; |
d9a6bd32 JJ |
8250 | t = OMP_CLAUSE_DECL (c); |
8251 | if (!type_dependent_expression_p (t)) | |
8252 | { | |
8253 | tree type = TREE_TYPE (t); | |
9f613f06 | 8254 | if (!TYPE_PTR_P (type) |
398e3feb | 8255 | && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type)))) |
d9a6bd32 | 8256 | { |
398e3feb JJ |
8257 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR |
8258 | && ort == C_ORT_OMP) | |
8259 | { | |
8260 | error_at (OMP_CLAUSE_LOCATION (c), | |
8261 | "%qs variable is neither a pointer " | |
8262 | "nor reference to pointer", | |
8263 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8264 | remove = true; | |
8265 | } | |
8266 | else if (TREE_CODE (type) != ARRAY_TYPE | |
8267 | && (!TYPE_REF_P (type) | |
8268 | || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)) | |
8269 | { | |
8270 | error_at (OMP_CLAUSE_LOCATION (c), | |
8271 | "%qs variable is neither a pointer, nor an " | |
8272 | "array nor reference to pointer or array", | |
8273 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8274 | remove = true; | |
8275 | } | |
d9a6bd32 JJ |
8276 | } |
8277 | } | |
8278 | goto check_dup_generic; | |
8279 | ||
398e3feb JJ |
8280 | case OMP_CLAUSE_USE_DEVICE_ADDR: |
8281 | field_ok = true; | |
8282 | t = OMP_CLAUSE_DECL (c); | |
8283 | if (!processing_template_decl | |
8284 | && (VAR_P (t) || TREE_CODE (t) == PARM_DECL) | |
8285 | && !TYPE_REF_P (TREE_TYPE (t)) | |
8286 | && !cxx_mark_addressable (t)) | |
8287 | remove = true; | |
8288 | goto check_dup_generic; | |
8289 | ||
1799e5d5 | 8290 | case OMP_CLAUSE_NOWAIT: |
1799e5d5 | 8291 | case OMP_CLAUSE_DEFAULT: |
a68ab351 JJ |
8292 | case OMP_CLAUSE_UNTIED: |
8293 | case OMP_CLAUSE_COLLAPSE: | |
acf0174b JJ |
8294 | case OMP_CLAUSE_PARALLEL: |
8295 | case OMP_CLAUSE_FOR: | |
8296 | case OMP_CLAUSE_SECTIONS: | |
8297 | case OMP_CLAUSE_TASKGROUP: | |
8298 | case OMP_CLAUSE_PROC_BIND: | |
77eb117f | 8299 | case OMP_CLAUSE_DEVICE_TYPE: |
d9a6bd32 JJ |
8300 | case OMP_CLAUSE_NOGROUP: |
8301 | case OMP_CLAUSE_THREADS: | |
8302 | case OMP_CLAUSE_SIMD: | |
8303 | case OMP_CLAUSE_DEFAULTMAP: | |
554a530f | 8304 | case OMP_CLAUSE_BIND: |
0d077441 | 8305 | case OMP_CLAUSE_AUTO: |
7a5e4956 | 8306 | case OMP_CLAUSE_INDEPENDENT: |
0d077441 | 8307 | case OMP_CLAUSE_SEQ: |
829c6349 CLT |
8308 | case OMP_CLAUSE_IF_PRESENT: |
8309 | case OMP_CLAUSE_FINALIZE: | |
a61f6afb | 8310 | case OMP_CLAUSE_NOHOST: |
acf0174b JJ |
8311 | break; |
8312 | ||
a6d22fb2 KCY |
8313 | case OMP_CLAUSE_MERGEABLE: |
8314 | mergeable_seen = true; | |
8315 | break; | |
8316 | ||
7a5e4956 CP |
8317 | case OMP_CLAUSE_TILE: |
8318 | for (tree list = OMP_CLAUSE_TILE_LIST (c); !remove && list; | |
8319 | list = TREE_CHAIN (list)) | |
8320 | { | |
8321 | t = TREE_VALUE (list); | |
8322 | ||
8323 | if (t == error_mark_node) | |
8324 | remove = true; | |
8325 | else if (!type_dependent_expression_p (t) | |
8326 | && !INTEGRAL_TYPE_P (TREE_TYPE (t))) | |
8327 | { | |
02889d23 CLT |
8328 | error_at (OMP_CLAUSE_LOCATION (c), |
8329 | "%<tile%> argument needs integral type"); | |
7a5e4956 CP |
8330 | remove = true; |
8331 | } | |
8332 | else | |
8333 | { | |
8334 | t = mark_rvalue_use (t); | |
8335 | if (!processing_template_decl) | |
8336 | { | |
02889d23 CLT |
8337 | /* Zero is used to indicate '*', we permit you |
8338 | to get there via an ICE of value zero. */ | |
7a5e4956 | 8339 | t = maybe_constant_value (t); |
02889d23 CLT |
8340 | if (!tree_fits_shwi_p (t) |
8341 | || tree_to_shwi (t) < 0) | |
7a5e4956 | 8342 | { |
02889d23 CLT |
8343 | error_at (OMP_CLAUSE_LOCATION (c), |
8344 | "%<tile%> argument needs positive " | |
8345 | "integral constant"); | |
8346 | remove = true; | |
7a5e4956 | 8347 | } |
e1bea341 | 8348 | t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); |
7a5e4956 | 8349 | } |
7a5e4956 CP |
8350 | } |
8351 | ||
8352 | /* Update list item. */ | |
8353 | TREE_VALUE (list) = t; | |
8354 | } | |
8355 | break; | |
8356 | ||
e01d41e5 JJ |
8357 | case OMP_CLAUSE_ORDERED: |
8358 | ordered_seen = true; | |
8359 | break; | |
8360 | ||
1fdd6f04 JJ |
8361 | case OMP_CLAUSE_ORDER: |
8362 | if (order_seen) | |
8363 | remove = true; | |
8364 | else | |
8365 | order_seen = true; | |
8366 | break; | |
8367 | ||
acf0174b JJ |
8368 | case OMP_CLAUSE_INBRANCH: |
8369 | case OMP_CLAUSE_NOTINBRANCH: | |
8370 | if (branch_seen) | |
8371 | { | |
28567c40 JJ |
8372 | error_at (OMP_CLAUSE_LOCATION (c), |
8373 | "%<inbranch%> clause is incompatible with " | |
8374 | "%<notinbranch%>"); | |
acf0174b JJ |
8375 | remove = true; |
8376 | } | |
8377 | branch_seen = true; | |
1799e5d5 RH |
8378 | break; |
8379 | ||
bf38f7e9 JJ |
8380 | case OMP_CLAUSE_INCLUSIVE: |
8381 | case OMP_CLAUSE_EXCLUSIVE: | |
8382 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); | |
8383 | if (!t) | |
8384 | t = OMP_CLAUSE_DECL (c); | |
8385 | if (t == current_class_ptr) | |
8386 | { | |
8387 | error_at (OMP_CLAUSE_LOCATION (c), | |
8388 | "%<this%> allowed in OpenMP only in %<declare simd%>" | |
8389 | " clauses"); | |
8390 | remove = true; | |
8391 | break; | |
8392 | } | |
8393 | if (!VAR_P (t) | |
8394 | && TREE_CODE (t) != PARM_DECL | |
8395 | && TREE_CODE (t) != FIELD_DECL) | |
8396 | { | |
8397 | if (processing_template_decl && TREE_CODE (t) != OVERLOAD) | |
8398 | break; | |
8399 | if (DECL_P (t)) | |
8400 | error_at (OMP_CLAUSE_LOCATION (c), | |
8401 | "%qD is not a variable in clause %qs", t, | |
8402 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8403 | else | |
8404 | error_at (OMP_CLAUSE_LOCATION (c), | |
8405 | "%qE is not a variable in clause %qs", t, | |
8406 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8407 | remove = true; | |
8408 | } | |
8409 | break; | |
8410 | ||
1799e5d5 RH |
8411 | default: |
8412 | gcc_unreachable (); | |
8413 | } | |
8414 | ||
8415 | if (remove) | |
8416 | *pc = OMP_CLAUSE_CHAIN (c); | |
8417 | else | |
8418 | pc = &OMP_CLAUSE_CHAIN (c); | |
8419 | } | |
8420 | ||
bf38f7e9 JJ |
8421 | if (reduction_seen < 0 && (ordered_seen || schedule_seen)) |
8422 | reduction_seen = -2; | |
8423 | ||
1799e5d5 RH |
8424 | for (pc = &clauses, c = clauses; c ; c = *pc) |
8425 | { | |
81f40b79 | 8426 | enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c); |
1799e5d5 | 8427 | bool remove = false; |
d9a6bd32 | 8428 | bool need_complete_type = false; |
1799e5d5 RH |
8429 | bool need_default_ctor = false; |
8430 | bool need_copy_ctor = false; | |
8431 | bool need_copy_assignment = false; | |
8432 | bool need_implicitly_determined = false; | |
acf0174b | 8433 | bool need_dtor = false; |
1799e5d5 RH |
8434 | tree type, inner_type; |
8435 | ||
8436 | switch (c_kind) | |
8437 | { | |
8438 | case OMP_CLAUSE_SHARED: | |
1799e5d5 RH |
8439 | need_implicitly_determined = true; |
8440 | break; | |
8441 | case OMP_CLAUSE_PRIVATE: | |
d9a6bd32 | 8442 | need_complete_type = true; |
1799e5d5 | 8443 | need_default_ctor = true; |
acf0174b | 8444 | need_dtor = true; |
1799e5d5 RH |
8445 | need_implicitly_determined = true; |
8446 | break; | |
8447 | case OMP_CLAUSE_FIRSTPRIVATE: | |
d9a6bd32 | 8448 | need_complete_type = true; |
1799e5d5 | 8449 | need_copy_ctor = true; |
acf0174b | 8450 | need_dtor = true; |
1799e5d5 RH |
8451 | need_implicitly_determined = true; |
8452 | break; | |
8453 | case OMP_CLAUSE_LASTPRIVATE: | |
d9a6bd32 | 8454 | need_complete_type = true; |
1799e5d5 RH |
8455 | need_copy_assignment = true; |
8456 | need_implicitly_determined = true; | |
8457 | break; | |
8458 | case OMP_CLAUSE_REDUCTION: | |
bf38f7e9 JJ |
8459 | if (reduction_seen == -2) |
8460 | OMP_CLAUSE_REDUCTION_INSCAN (c) = 0; | |
0356aab8 JJ |
8461 | if (OMP_CLAUSE_REDUCTION_INSCAN (c)) |
8462 | need_copy_assignment = true; | |
bf38f7e9 JJ |
8463 | need_implicitly_determined = true; |
8464 | break; | |
28567c40 JJ |
8465 | case OMP_CLAUSE_IN_REDUCTION: |
8466 | case OMP_CLAUSE_TASK_REDUCTION: | |
bf38f7e9 JJ |
8467 | case OMP_CLAUSE_INCLUSIVE: |
8468 | case OMP_CLAUSE_EXCLUSIVE: | |
1799e5d5 RH |
8469 | need_implicitly_determined = true; |
8470 | break; | |
d9a6bd32 | 8471 | case OMP_CLAUSE_LINEAR: |
77886428 | 8472 | if (ort != C_ORT_OMP_DECLARE_SIMD) |
d9a6bd32 | 8473 | need_implicitly_determined = true; |
e01d41e5 JJ |
8474 | else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) |
8475 | && !bitmap_bit_p (&map_head, | |
8476 | DECL_UID (OMP_CLAUSE_LINEAR_STEP (c)))) | |
8477 | { | |
8478 | error_at (OMP_CLAUSE_LOCATION (c), | |
8479 | "%<linear%> clause step is a parameter %qD not " | |
8480 | "specified in %<uniform%> clause", | |
8481 | OMP_CLAUSE_LINEAR_STEP (c)); | |
8482 | *pc = OMP_CLAUSE_CHAIN (c); | |
8483 | continue; | |
8484 | } | |
d9a6bd32 | 8485 | break; |
1799e5d5 | 8486 | case OMP_CLAUSE_COPYPRIVATE: |
1799e5d5 RH |
8487 | need_copy_assignment = true; |
8488 | break; | |
8489 | case OMP_CLAUSE_COPYIN: | |
1799e5d5 RH |
8490 | need_copy_assignment = true; |
8491 | break; | |
d9a6bd32 JJ |
8492 | case OMP_CLAUSE_SIMDLEN: |
8493 | if (safelen | |
8494 | && !processing_template_decl | |
8495 | && tree_int_cst_lt (OMP_CLAUSE_SAFELEN_EXPR (safelen), | |
8496 | OMP_CLAUSE_SIMDLEN_EXPR (c))) | |
8497 | { | |
8498 | error_at (OMP_CLAUSE_LOCATION (c), | |
8499 | "%<simdlen%> clause value is bigger than " | |
8500 | "%<safelen%> clause value"); | |
8501 | OMP_CLAUSE_SIMDLEN_EXPR (c) | |
8502 | = OMP_CLAUSE_SAFELEN_EXPR (safelen); | |
8503 | } | |
8504 | pc = &OMP_CLAUSE_CHAIN (c); | |
8505 | continue; | |
e01d41e5 JJ |
8506 | case OMP_CLAUSE_SCHEDULE: |
8507 | if (ordered_seen | |
8508 | && (OMP_CLAUSE_SCHEDULE_KIND (c) | |
8509 | & OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) | |
8510 | { | |
8511 | error_at (OMP_CLAUSE_LOCATION (c), | |
8512 | "%<nonmonotonic%> schedule modifier specified " | |
8513 | "together with %<ordered%> clause"); | |
8514 | OMP_CLAUSE_SCHEDULE_KIND (c) | |
8515 | = (enum omp_clause_schedule_kind) | |
8516 | (OMP_CLAUSE_SCHEDULE_KIND (c) | |
8517 | & ~OMP_CLAUSE_SCHEDULE_NONMONOTONIC); | |
8518 | } | |
bf38f7e9 JJ |
8519 | if (reduction_seen == -2) |
8520 | error_at (OMP_CLAUSE_LOCATION (c), | |
8521 | "%qs clause specified together with %<inscan%> " | |
8522 | "%<reduction%> clause", "schedule"); | |
e01d41e5 JJ |
8523 | pc = &OMP_CLAUSE_CHAIN (c); |
8524 | continue; | |
28567c40 JJ |
8525 | case OMP_CLAUSE_NOGROUP: |
8526 | if (reduction_seen) | |
8527 | { | |
8528 | error_at (OMP_CLAUSE_LOCATION (c), | |
8529 | "%<nogroup%> clause must not be used together with " | |
8530 | "%<reduction%> clause"); | |
8531 | *pc = OMP_CLAUSE_CHAIN (c); | |
8532 | continue; | |
8533 | } | |
8534 | pc = &OMP_CLAUSE_CHAIN (c); | |
8535 | continue; | |
bf38f7e9 JJ |
8536 | case OMP_CLAUSE_ORDERED: |
8537 | if (reduction_seen == -2) | |
8538 | error_at (OMP_CLAUSE_LOCATION (c), | |
8539 | "%qs clause specified together with %<inscan%> " | |
8540 | "%<reduction%> clause", "ordered"); | |
8541 | pc = &OMP_CLAUSE_CHAIN (c); | |
8542 | continue; | |
1fdd6f04 JJ |
8543 | case OMP_CLAUSE_ORDER: |
8544 | if (ordered_seen) | |
8545 | { | |
8546 | error_at (OMP_CLAUSE_LOCATION (c), | |
8547 | "%<order%> clause must not be used together " | |
8548 | "with %<ordered%>"); | |
8549 | *pc = OMP_CLAUSE_CHAIN (c); | |
8550 | continue; | |
8551 | } | |
8552 | pc = &OMP_CLAUSE_CHAIN (c); | |
8553 | continue; | |
a6d22fb2 KCY |
8554 | case OMP_CLAUSE_DETACH: |
8555 | if (mergeable_seen) | |
8556 | { | |
8557 | error_at (OMP_CLAUSE_LOCATION (c), | |
8558 | "%<detach%> clause must not be used together with " | |
8559 | "%<mergeable%> clause"); | |
8560 | *pc = OMP_CLAUSE_CHAIN (c); | |
8561 | continue; | |
8562 | } | |
8563 | pc = &OMP_CLAUSE_CHAIN (c); | |
8564 | continue; | |
7619d334 JJ |
8565 | case OMP_CLAUSE_MAP: |
8566 | if (target_in_reduction_seen && !processing_template_decl) | |
8567 | { | |
8568 | t = OMP_CLAUSE_DECL (c); | |
8569 | while (handled_component_p (t) | |
8570 | || TREE_CODE (t) == INDIRECT_REF | |
8571 | || TREE_CODE (t) == ADDR_EXPR | |
8572 | || TREE_CODE (t) == MEM_REF | |
8573 | || TREE_CODE (t) == NON_LVALUE_EXPR) | |
8574 | t = TREE_OPERAND (t, 0); | |
8575 | if (DECL_P (t) | |
8576 | && bitmap_bit_p (&oacc_reduction_head, DECL_UID (t))) | |
8577 | OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1; | |
8578 | } | |
8579 | pc = &OMP_CLAUSE_CHAIN (c); | |
8580 | continue; | |
acf0174b JJ |
8581 | case OMP_CLAUSE_NOWAIT: |
8582 | if (copyprivate_seen) | |
8583 | { | |
8584 | error_at (OMP_CLAUSE_LOCATION (c), | |
8585 | "%<nowait%> clause must not be used together " | |
8586 | "with %<copyprivate%>"); | |
8587 | *pc = OMP_CLAUSE_CHAIN (c); | |
8588 | continue; | |
8589 | } | |
8590 | /* FALLTHRU */ | |
1799e5d5 RH |
8591 | default: |
8592 | pc = &OMP_CLAUSE_CHAIN (c); | |
8593 | continue; | |
8594 | } | |
8595 | ||
8596 | t = OMP_CLAUSE_DECL (c); | |
1799e5d5 RH |
8597 | switch (c_kind) |
8598 | { | |
8599 | case OMP_CLAUSE_LASTPRIVATE: | |
96490315 JJ |
8600 | if (DECL_P (t) |
8601 | && !bitmap_bit_p (&firstprivate_head, DECL_UID (t))) | |
acf0174b JJ |
8602 | { |
8603 | need_default_ctor = true; | |
8604 | need_dtor = true; | |
8605 | } | |
1799e5d5 RH |
8606 | break; |
8607 | ||
8608 | case OMP_CLAUSE_REDUCTION: | |
28567c40 JJ |
8609 | case OMP_CLAUSE_IN_REDUCTION: |
8610 | case OMP_CLAUSE_TASK_REDUCTION: | |
96490315 JJ |
8611 | if (allocate_seen) |
8612 | { | |
8613 | if (TREE_CODE (t) == MEM_REF) | |
8614 | { | |
8615 | t = TREE_OPERAND (t, 0); | |
8616 | if (TREE_CODE (t) == POINTER_PLUS_EXPR) | |
8617 | t = TREE_OPERAND (t, 0); | |
8618 | if (TREE_CODE (t) == ADDR_EXPR | |
8619 | || TREE_CODE (t) == INDIRECT_REF) | |
8620 | t = TREE_OPERAND (t, 0); | |
8621 | if (DECL_P (t)) | |
8622 | bitmap_clear_bit (&aligned_head, DECL_UID (t)); | |
8623 | } | |
8624 | else if (TREE_CODE (t) == TREE_LIST) | |
8625 | { | |
8626 | while (TREE_CODE (t) == TREE_LIST) | |
8627 | t = TREE_CHAIN (t); | |
8628 | if (DECL_P (t)) | |
8629 | bitmap_clear_bit (&aligned_head, DECL_UID (t)); | |
8630 | t = OMP_CLAUSE_DECL (c); | |
8631 | } | |
8632 | else if (DECL_P (t)) | |
8633 | bitmap_clear_bit (&aligned_head, DECL_UID (t)); | |
8634 | t = OMP_CLAUSE_DECL (c); | |
8635 | } | |
8636 | if (processing_template_decl | |
8637 | && !VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
8638 | break; | |
acf0174b JJ |
8639 | if (finish_omp_reduction_clause (c, &need_default_ctor, |
8640 | &need_dtor)) | |
8641 | remove = true; | |
8642 | else | |
8643 | t = OMP_CLAUSE_DECL (c); | |
1799e5d5 RH |
8644 | break; |
8645 | ||
8646 | case OMP_CLAUSE_COPYIN: | |
96490315 JJ |
8647 | if (processing_template_decl |
8648 | && !VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
8649 | break; | |
3048c0c7 | 8650 | if (!VAR_P (t) || !CP_DECL_THREAD_LOCAL_P (t)) |
1799e5d5 | 8651 | { |
28567c40 JJ |
8652 | error_at (OMP_CLAUSE_LOCATION (c), |
8653 | "%qE must be %<threadprivate%> for %<copyin%>", t); | |
1799e5d5 RH |
8654 | remove = true; |
8655 | } | |
8656 | break; | |
8657 | ||
8658 | default: | |
8659 | break; | |
8660 | } | |
8661 | ||
96490315 JJ |
8662 | if (processing_template_decl |
8663 | && !VAR_P (t) && TREE_CODE (t) != PARM_DECL) | |
8664 | { | |
8665 | pc = &OMP_CLAUSE_CHAIN (c); | |
8666 | continue; | |
8667 | } | |
8668 | ||
d9a6bd32 | 8669 | if (need_complete_type || need_copy_assignment) |
1799e5d5 RH |
8670 | { |
8671 | t = require_complete_type (t); | |
8672 | if (t == error_mark_node) | |
8673 | remove = true; | |
e73fb06d JJ |
8674 | else if (!processing_template_decl |
8675 | && TYPE_REF_P (TREE_TYPE (t)) | |
d9a6bd32 JJ |
8676 | && !complete_type_or_else (TREE_TYPE (TREE_TYPE (t)), t)) |
8677 | remove = true; | |
1799e5d5 RH |
8678 | } |
8679 | if (need_implicitly_determined) | |
8680 | { | |
8681 | const char *share_name = NULL; | |
8682 | ||
3a8b2094 JJ |
8683 | if (allocate_seen |
8684 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED | |
8685 | && DECL_P (t)) | |
96490315 | 8686 | bitmap_clear_bit (&aligned_head, DECL_UID (t)); |
3a8b2094 | 8687 | |
3048c0c7 | 8688 | if (VAR_P (t) && CP_DECL_THREAD_LOCAL_P (t)) |
1799e5d5 | 8689 | share_name = "threadprivate"; |
1c9ee609 | 8690 | else switch (cxx_omp_predetermined_sharing_1 (t)) |
1799e5d5 RH |
8691 | { |
8692 | case OMP_CLAUSE_DEFAULT_UNSPECIFIED: | |
8693 | break; | |
8694 | case OMP_CLAUSE_DEFAULT_SHARED: | |
59bc434a JJ |
8695 | if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED |
8696 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE) | |
8697 | && c_omp_predefined_variable (t)) | |
8698 | /* The __func__ variable and similar function-local predefined | |
8699 | variables may be listed in a shared or firstprivate | |
8700 | clause. */ | |
8701 | break; | |
28567c40 JJ |
8702 | if (VAR_P (t) |
8703 | && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE | |
8704 | && TREE_STATIC (t) | |
20906c66 | 8705 | && cxx_omp_const_qual_no_mutable (t)) |
28567c40 JJ |
8706 | { |
8707 | tree ctx = CP_DECL_CONTEXT (t); | |
8708 | /* const qualified static data members without mutable | |
8709 | member may be specified in firstprivate clause. */ | |
8710 | if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx)) | |
8711 | break; | |
8712 | } | |
1799e5d5 RH |
8713 | share_name = "shared"; |
8714 | break; | |
8715 | case OMP_CLAUSE_DEFAULT_PRIVATE: | |
8716 | share_name = "private"; | |
8717 | break; | |
8718 | default: | |
8719 | gcc_unreachable (); | |
8720 | } | |
8721 | if (share_name) | |
8722 | { | |
28567c40 JJ |
8723 | error_at (OMP_CLAUSE_LOCATION (c), |
8724 | "%qE is predetermined %qs for %qs", | |
8725 | omp_clause_printable_decl (t), share_name, | |
8726 | omp_clause_code_name[OMP_CLAUSE_CODE (c)]); | |
8727 | remove = true; | |
8728 | } | |
8729 | else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED | |
8730 | && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE | |
8731 | && cxx_omp_const_qual_no_mutable (t)) | |
8732 | { | |
8733 | error_at (OMP_CLAUSE_LOCATION (c), | |
8734 | "%<const%> qualified %qE without %<mutable%> member " | |
8735 | "may appear only in %<shared%> or %<firstprivate%> " | |
8736 | "clauses", omp_clause_printable_decl (t)); | |
1799e5d5 RH |
8737 | remove = true; |
8738 | } | |
8739 | } | |
8740 | ||
a6d22fb2 KCY |
8741 | if (detach_seen |
8742 | && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED | |
8743 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE | |
8744 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE | |
8745 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE) | |
1b462dea | 8746 | && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen)) |
a6d22fb2 KCY |
8747 | { |
8748 | error_at (OMP_CLAUSE_LOCATION (c), | |
8749 | "the event handle of a %<detach%> clause " | |
8750 | "should not be in a data-sharing clause"); | |
8751 | remove = true; | |
8752 | } | |
8753 | ||
1799e5d5 RH |
8754 | /* We're interested in the base element, not arrays. */ |
8755 | inner_type = type = TREE_TYPE (t); | |
d9a6bd32 JJ |
8756 | if ((need_complete_type |
8757 | || need_copy_assignment | |
28567c40 JJ |
8758 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION |
8759 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION | |
8760 | || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_TASK_REDUCTION) | |
9f613f06 | 8761 | && TYPE_REF_P (inner_type)) |
acf0174b | 8762 | inner_type = TREE_TYPE (inner_type); |
d9a6bd32 JJ |
8763 | while (TREE_CODE (inner_type) == ARRAY_TYPE) |
8764 | inner_type = TREE_TYPE (inner_type); | |
acf0174b | 8765 | |
84dc00e8 | 8766 | /* Check for special function availability by building a call to one. |
1799e5d5 RH |
8767 | Save the results, because later we won't be in the right context |
8768 | for making these queries. */ | |
8769 | if (CLASS_TYPE_P (inner_type) | |
8a8c12a3 | 8770 | && COMPLETE_TYPE_P (inner_type) |
acf0174b JJ |
8771 | && (need_default_ctor || need_copy_ctor |
8772 | || need_copy_assignment || need_dtor) | |
a68ab351 JJ |
8773 | && !type_dependent_expression_p (t) |
8774 | && cxx_omp_create_clause_info (c, inner_type, need_default_ctor, | |
acf0174b JJ |
8775 | need_copy_ctor, need_copy_assignment, |
8776 | need_dtor)) | |
a68ab351 | 8777 | remove = true; |
1799e5d5 | 8778 | |
e01d41e5 JJ |
8779 | if (!remove |
8780 | && c_kind == OMP_CLAUSE_SHARED | |
8781 | && processing_template_decl) | |
8782 | { | |
8783 | t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); | |
8784 | if (t) | |
8785 | OMP_CLAUSE_DECL (c) = t; | |
8786 | } | |
8787 | ||
1799e5d5 RH |
8788 | if (remove) |
8789 | *pc = OMP_CLAUSE_CHAIN (c); | |
8790 | else | |
8791 | pc = &OMP_CLAUSE_CHAIN (c); | |
8792 | } | |
8793 | ||
3a8b2094 JJ |
8794 | if (allocate_seen) |
8795 | for (pc = &clauses, c = clauses; c ; c = *pc) | |
8796 | { | |
8797 | bool remove = false; | |
8798 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ALLOCATE | |
8799 | && !OMP_CLAUSE_ALLOCATE_COMBINED (c) | |
96490315 | 8800 | && DECL_P (OMP_CLAUSE_DECL (c)) |
3a8b2094 JJ |
8801 | && bitmap_bit_p (&aligned_head, DECL_UID (OMP_CLAUSE_DECL (c)))) |
8802 | { | |
8803 | error_at (OMP_CLAUSE_LOCATION (c), | |
8804 | "%qD specified in %<allocate%> clause but not in " | |
8805 | "an explicit privatization clause", OMP_CLAUSE_DECL (c)); | |
8806 | remove = true; | |
8807 | } | |
8808 | if (remove) | |
8809 | *pc = OMP_CLAUSE_CHAIN (c); | |
8810 | else | |
8811 | pc = &OMP_CLAUSE_CHAIN (c); | |
8812 | } | |
8813 | ||
1799e5d5 RH |
8814 | bitmap_obstack_release (NULL); |
8815 | return clauses; | |
8816 | } | |
8817 | ||
d9a6bd32 JJ |
8818 | /* Start processing OpenMP clauses that can include any |
8819 | privatization clauses for non-static data members. */ | |
8820 | ||
8821 | tree | |
8822 | push_omp_privatization_clauses (bool ignore_next) | |
8823 | { | |
8824 | if (omp_private_member_ignore_next) | |
8825 | { | |
8826 | omp_private_member_ignore_next = ignore_next; | |
8827 | return NULL_TREE; | |
8828 | } | |
8829 | omp_private_member_ignore_next = ignore_next; | |
8830 | if (omp_private_member_map) | |
8831 | omp_private_member_vec.safe_push (error_mark_node); | |
8832 | return push_stmt_list (); | |
8833 | } | |
8834 | ||
8835 | /* Revert remapping of any non-static data members since | |
8836 | the last push_omp_privatization_clauses () call. */ | |
8837 | ||
8838 | void | |
8839 | pop_omp_privatization_clauses (tree stmt) | |
8840 | { | |
8841 | if (stmt == NULL_TREE) | |
8842 | return; | |
8843 | stmt = pop_stmt_list (stmt); | |
8844 | if (omp_private_member_map) | |
8845 | { | |
8846 | while (!omp_private_member_vec.is_empty ()) | |
8847 | { | |
8848 | tree t = omp_private_member_vec.pop (); | |
8849 | if (t == error_mark_node) | |
8850 | { | |
8851 | add_stmt (stmt); | |
8852 | return; | |
8853 | } | |
8854 | bool no_decl_expr = t == integer_zero_node; | |
8855 | if (no_decl_expr) | |
8856 | t = omp_private_member_vec.pop (); | |
8857 | tree *v = omp_private_member_map->get (t); | |
8858 | gcc_assert (v); | |
8859 | if (!no_decl_expr) | |
8860 | add_decl_expr (*v); | |
8861 | omp_private_member_map->remove (t); | |
8862 | } | |
8863 | delete omp_private_member_map; | |
8864 | omp_private_member_map = NULL; | |
8865 | } | |
8866 | add_stmt (stmt); | |
8867 | } | |
8868 | ||
8869 | /* Remember OpenMP privatization clauses mapping and clear it. | |
8870 | Used for lambdas. */ | |
8871 | ||
8872 | void | |
8873 | save_omp_privatization_clauses (vec<tree> &save) | |
8874 | { | |
8875 | save = vNULL; | |
8876 | if (omp_private_member_ignore_next) | |
8877 | save.safe_push (integer_one_node); | |
8878 | omp_private_member_ignore_next = false; | |
8879 | if (!omp_private_member_map) | |
8880 | return; | |
8881 | ||
8882 | while (!omp_private_member_vec.is_empty ()) | |
8883 | { | |
8884 | tree t = omp_private_member_vec.pop (); | |
8885 | if (t == error_mark_node) | |
8886 | { | |
8887 | save.safe_push (t); | |
8888 | continue; | |
8889 | } | |
8890 | tree n = t; | |
8891 | if (t == integer_zero_node) | |
8892 | t = omp_private_member_vec.pop (); | |
8893 | tree *v = omp_private_member_map->get (t); | |
8894 | gcc_assert (v); | |
8895 | save.safe_push (*v); | |
8896 | save.safe_push (t); | |
8897 | if (n != t) | |
8898 | save.safe_push (n); | |
8899 | } | |
8900 | delete omp_private_member_map; | |
8901 | omp_private_member_map = NULL; | |
8902 | } | |
8903 | ||
8904 | /* Restore OpenMP privatization clauses mapping saved by the | |
8905 | above function. */ | |
8906 | ||
8907 | void | |
8908 | restore_omp_privatization_clauses (vec<tree> &save) | |
8909 | { | |
8910 | gcc_assert (omp_private_member_vec.is_empty ()); | |
8911 | omp_private_member_ignore_next = false; | |
8912 | if (save.is_empty ()) | |
8913 | return; | |
8914 | if (save.length () == 1 && save[0] == integer_one_node) | |
8915 | { | |
8916 | omp_private_member_ignore_next = true; | |
8917 | save.release (); | |
8918 | return; | |
8919 | } | |
43e1e8b5 | 8920 | |
d9a6bd32 JJ |
8921 | omp_private_member_map = new hash_map <tree, tree>; |
8922 | while (!save.is_empty ()) | |
8923 | { | |
8924 | tree t = save.pop (); | |
8925 | tree n = t; | |
8926 | if (t != error_mark_node) | |
8927 | { | |
8928 | if (t == integer_one_node) | |
8929 | { | |
8930 | omp_private_member_ignore_next = true; | |
8931 | gcc_assert (save.is_empty ()); | |
8932 | break; | |
8933 | } | |
8934 | if (t == integer_zero_node) | |
8935 | t = save.pop (); | |
8936 | tree &v = omp_private_member_map->get_or_insert (t); | |
8937 | v = save.pop (); | |
8938 | } | |
8939 | omp_private_member_vec.safe_push (t); | |
8940 | if (n != t) | |
8941 | omp_private_member_vec.safe_push (n); | |
8942 | } | |
8943 | save.release (); | |
8944 | } | |
8945 | ||
1799e5d5 RH |
8946 | /* For all variables in the tree_list VARS, mark them as thread local. */ |
8947 | ||
8948 | void | |
8949 | finish_omp_threadprivate (tree vars) | |
8950 | { | |
8951 | tree t; | |
8952 | ||
8953 | /* Mark every variable in VARS to be assigned thread local storage. */ | |
8954 | for (t = vars; t; t = TREE_CHAIN (t)) | |
8955 | { | |
8956 | tree v = TREE_PURPOSE (t); | |
8957 | ||
edb6000e JJ |
8958 | if (error_operand_p (v)) |
8959 | ; | |
5a6ccc94 | 8960 | else if (!VAR_P (v)) |
edb6000e JJ |
8961 | error ("%<threadprivate%> %qD is not file, namespace " |
8962 | "or block scope variable", v); | |
1799e5d5 RH |
8963 | /* If V had already been marked threadprivate, it doesn't matter |
8964 | whether it had been used prior to this point. */ | |
edb6000e | 8965 | else if (TREE_USED (v) |
1799e5d5 RH |
8966 | && (DECL_LANG_SPECIFIC (v) == NULL |
8967 | || !CP_DECL_THREADPRIVATE_P (v))) | |
8968 | error ("%qE declared %<threadprivate%> after first use", v); | |
8969 | else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v)) | |
8970 | error ("automatic variable %qE cannot be %<threadprivate%>", v); | |
57c3feb4 | 8971 | else if (! COMPLETE_TYPE_P (complete_type (TREE_TYPE (v)))) |
1799e5d5 | 8972 | error ("%<threadprivate%> %qE has incomplete type", v); |
a68ab351 JJ |
8973 | else if (TREE_STATIC (v) && TYPE_P (CP_DECL_CONTEXT (v)) |
8974 | && CP_DECL_CONTEXT (v) != current_class_type) | |
8975 | error ("%<threadprivate%> %qE directive not " | |
8976 | "in %qT definition", v, CP_DECL_CONTEXT (v)); | |
1799e5d5 RH |
8977 | else |
8978 | { | |
8979 | /* Allocate a LANG_SPECIFIC structure for V, if needed. */ | |
8980 | if (DECL_LANG_SPECIFIC (v) == NULL) | |
41f927f4 | 8981 | retrofit_lang_decl (v); |
1799e5d5 | 8982 | |
3048c0c7 | 8983 | if (! CP_DECL_THREAD_LOCAL_P (v)) |
1799e5d5 | 8984 | { |
3048c0c7 | 8985 | CP_DECL_THREAD_LOCAL_P (v) = true; |
56363ffd | 8986 | set_decl_tls_model (v, decl_default_tls_model (v)); |
1799e5d5 RH |
8987 | /* If rtl has been already set for this var, call |
8988 | make_decl_rtl once again, so that encode_section_info | |
8989 | has a chance to look at the new decl flags. */ | |
8990 | if (DECL_RTL_SET_P (v)) | |
8991 | make_decl_rtl (v); | |
8992 | } | |
8993 | CP_DECL_THREADPRIVATE_P (v) = 1; | |
8994 | } | |
8995 | } | |
8996 | } | |
8997 | ||
8998 | /* Build an OpenMP structured block. */ | |
8999 | ||
9000 | tree | |
9001 | begin_omp_structured_block (void) | |
9002 | { | |
9003 | return do_pushlevel (sk_omp); | |
9004 | } | |
9005 | ||
9006 | tree | |
9007 | finish_omp_structured_block (tree block) | |
9008 | { | |
9009 | return do_poplevel (block); | |
9010 | } | |
9011 | ||
88bae6f4 | 9012 | /* Similarly, except force the retention of the BLOCK. */ |
41dbbb37 TS |
9013 | |
9014 | tree | |
88bae6f4 | 9015 | begin_omp_parallel (void) |
41dbbb37 | 9016 | { |
88bae6f4 TS |
9017 | keep_next_level (true); |
9018 | return begin_omp_structured_block (); | |
41dbbb37 TS |
9019 | } |
9020 | ||
88bae6f4 TS |
9021 | /* Generate OACC_DATA, with CLAUSES and BLOCK as its compound |
9022 | statement. */ | |
41dbbb37 TS |
9023 | |
9024 | tree | |
88bae6f4 | 9025 | finish_oacc_data (tree clauses, tree block) |
41dbbb37 TS |
9026 | { |
9027 | tree stmt; | |
9028 | ||
9029 | block = finish_omp_structured_block (block); | |
9030 | ||
88bae6f4 | 9031 | stmt = make_node (OACC_DATA); |
41dbbb37 | 9032 | TREE_TYPE (stmt) = void_type_node; |
88bae6f4 TS |
9033 | OACC_DATA_CLAUSES (stmt) = clauses; |
9034 | OACC_DATA_BODY (stmt) = block; | |
41dbbb37 TS |
9035 | |
9036 | return add_stmt (stmt); | |
9037 | } | |
9038 | ||
37d5ad46 JB |
9039 | /* Generate OACC_HOST_DATA, with CLAUSES and BLOCK as its compound |
9040 | statement. */ | |
9041 | ||
9042 | tree | |
9043 | finish_oacc_host_data (tree clauses, tree block) | |
9044 | { | |
9045 | tree stmt; | |
9046 | ||
9047 | block = finish_omp_structured_block (block); | |
9048 | ||
9049 | stmt = make_node (OACC_HOST_DATA); | |
9050 | TREE_TYPE (stmt) = void_type_node; | |
9051 | OACC_HOST_DATA_CLAUSES (stmt) = clauses; | |
9052 | OACC_HOST_DATA_BODY (stmt) = block; | |
9053 | ||
9054 | return add_stmt (stmt); | |
9055 | } | |
9056 | ||
88bae6f4 TS |
9057 | /* Generate OMP construct CODE, with BODY and CLAUSES as its compound |
9058 | statement. */ | |
41dbbb37 TS |
9059 | |
9060 | tree | |
88bae6f4 | 9061 | finish_omp_construct (enum tree_code code, tree body, tree clauses) |
41dbbb37 | 9062 | { |
88bae6f4 | 9063 | body = finish_omp_structured_block (body); |
41dbbb37 | 9064 | |
88bae6f4 | 9065 | tree stmt = make_node (code); |
41dbbb37 | 9066 | TREE_TYPE (stmt) = void_type_node; |
88bae6f4 TS |
9067 | OMP_BODY (stmt) = body; |
9068 | OMP_CLAUSES (stmt) = clauses; | |
41dbbb37 TS |
9069 | |
9070 | return add_stmt (stmt); | |
9071 | } | |
9072 | ||
1799e5d5 RH |
9073 | tree |
9074 | finish_omp_parallel (tree clauses, tree body) | |
9075 | { | |
9076 | tree stmt; | |
9077 | ||
9078 | body = finish_omp_structured_block (body); | |
b850de4f | 9079 | |
1799e5d5 RH |
9080 | stmt = make_node (OMP_PARALLEL); |
9081 | TREE_TYPE (stmt) = void_type_node; | |
9082 | OMP_PARALLEL_CLAUSES (stmt) = clauses; | |
9083 | OMP_PARALLEL_BODY (stmt) = body; | |
54f7877c | 9084 | |
1799e5d5 RH |
9085 | return add_stmt (stmt); |
9086 | } | |
9087 | ||
a68ab351 JJ |
9088 | tree |
9089 | begin_omp_task (void) | |
9090 | { | |
9091 | keep_next_level (true); | |
9092 | return begin_omp_structured_block (); | |
9093 | } | |
9094 | ||
9095 | tree | |
9096 | finish_omp_task (tree clauses, tree body) | |
9097 | { | |
9098 | tree stmt; | |
9099 | ||
9100 | body = finish_omp_structured_block (body); | |
9101 | ||
9102 | stmt = make_node (OMP_TASK); | |
9103 | TREE_TYPE (stmt) = void_type_node; | |
9104 | OMP_TASK_CLAUSES (stmt) = clauses; | |
9105 | OMP_TASK_BODY (stmt) = body; | |
9106 | ||
9107 | return add_stmt (stmt); | |
9108 | } | |
9109 | ||
9110 | /* Helper function for finish_omp_for. Convert Ith random access iterator | |
9111 | into integral iterator. Return FALSE if successful. */ | |
9112 | ||
9113 | static bool | |
d9a6bd32 | 9114 | handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, |
e01d41e5 JJ |
9115 | tree declv, tree orig_declv, tree initv, |
9116 | tree condv, tree incrv, tree *body, | |
0b27c3ed | 9117 | tree *pre_body, tree &clauses, |
e01d41e5 | 9118 | int collapse, int ordered) |
a68ab351 JJ |
9119 | { |
9120 | tree diff, iter_init, iter_incr = NULL, last; | |
9121 | tree incr_var = NULL, orig_pre_body, orig_body, c; | |
9122 | tree decl = TREE_VEC_ELT (declv, i); | |
9123 | tree init = TREE_VEC_ELT (initv, i); | |
9124 | tree cond = TREE_VEC_ELT (condv, i); | |
9125 | tree incr = TREE_VEC_ELT (incrv, i); | |
9126 | tree iter = decl; | |
9127 | location_t elocus = locus; | |
9128 | ||
9129 | if (init && EXPR_HAS_LOCATION (init)) | |
9130 | elocus = EXPR_LOCATION (init); | |
9131 | ||
9132 | switch (TREE_CODE (cond)) | |
9133 | { | |
9134 | case GT_EXPR: | |
9135 | case GE_EXPR: | |
9136 | case LT_EXPR: | |
9137 | case LE_EXPR: | |
9a771876 | 9138 | case NE_EXPR: |
c5cdb03f JJ |
9139 | if (TREE_OPERAND (cond, 1) == iter) |
9140 | cond = build2 (swap_tree_comparison (TREE_CODE (cond)), | |
9141 | TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0)); | |
a68ab351 JJ |
9142 | if (TREE_OPERAND (cond, 0) != iter) |
9143 | cond = error_mark_node; | |
9144 | else | |
9145 | { | |
f330f599 PC |
9146 | tree tem = build_x_binary_op (EXPR_LOCATION (cond), |
9147 | TREE_CODE (cond), | |
4fe977f2 | 9148 | iter, ERROR_MARK, |
a68ab351 JJ |
9149 | TREE_OPERAND (cond, 1), ERROR_MARK, |
9150 | NULL, tf_warning_or_error); | |
9151 | if (error_operand_p (tem)) | |
9152 | return true; | |
9153 | } | |
9154 | break; | |
9155 | default: | |
9156 | cond = error_mark_node; | |
9157 | break; | |
9158 | } | |
9159 | if (cond == error_mark_node) | |
9160 | { | |
69bc6bff | 9161 | error_at (elocus, "invalid controlling predicate"); |
a68ab351 JJ |
9162 | return true; |
9163 | } | |
f330f599 | 9164 | diff = build_x_binary_op (elocus, MINUS_EXPR, TREE_OPERAND (cond, 1), |
a68ab351 JJ |
9165 | ERROR_MARK, iter, ERROR_MARK, NULL, |
9166 | tf_warning_or_error); | |
cda0a029 | 9167 | diff = cp_fully_fold (diff); |
a68ab351 JJ |
9168 | if (error_operand_p (diff)) |
9169 | return true; | |
9170 | if (TREE_CODE (TREE_TYPE (diff)) != INTEGER_TYPE) | |
9171 | { | |
69bc6bff MLI |
9172 | error_at (elocus, "difference between %qE and %qD does not have integer type", |
9173 | TREE_OPERAND (cond, 1), iter); | |
a68ab351 JJ |
9174 | return true; |
9175 | } | |
1160ec9a | 9176 | if (!c_omp_check_loop_iv_exprs (locus, orig_declv, i, |
e01d41e5 JJ |
9177 | TREE_VEC_ELT (declv, i), NULL_TREE, |
9178 | cond, cp_walk_subtrees)) | |
9179 | return true; | |
a68ab351 JJ |
9180 | |
9181 | switch (TREE_CODE (incr)) | |
9182 | { | |
9183 | case PREINCREMENT_EXPR: | |
9184 | case PREDECREMENT_EXPR: | |
9185 | case POSTINCREMENT_EXPR: | |
9186 | case POSTDECREMENT_EXPR: | |
9187 | if (TREE_OPERAND (incr, 0) != iter) | |
9188 | { | |
9189 | incr = error_mark_node; | |
9190 | break; | |
9191 | } | |
f330f599 PC |
9192 | iter_incr = build_x_unary_op (EXPR_LOCATION (incr), |
9193 | TREE_CODE (incr), iter, | |
a68ab351 JJ |
9194 | tf_warning_or_error); |
9195 | if (error_operand_p (iter_incr)) | |
9196 | return true; | |
9197 | else if (TREE_CODE (incr) == PREINCREMENT_EXPR | |
9198 | || TREE_CODE (incr) == POSTINCREMENT_EXPR) | |
9199 | incr = integer_one_node; | |
9200 | else | |
9201 | incr = integer_minus_one_node; | |
9202 | break; | |
9203 | case MODIFY_EXPR: | |
9204 | if (TREE_OPERAND (incr, 0) != iter) | |
9205 | incr = error_mark_node; | |
9206 | else if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR | |
9207 | || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR) | |
9208 | { | |
9209 | tree rhs = TREE_OPERAND (incr, 1); | |
9210 | if (TREE_OPERAND (rhs, 0) == iter) | |
9211 | { | |
9212 | if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 1))) | |
9213 | != INTEGER_TYPE) | |
9214 | incr = error_mark_node; | |
9215 | else | |
9216 | { | |
f330f599 PC |
9217 | iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs), |
9218 | iter, TREE_CODE (rhs), | |
a68ab351 JJ |
9219 | TREE_OPERAND (rhs, 1), |
9220 | tf_warning_or_error); | |
9221 | if (error_operand_p (iter_incr)) | |
9222 | return true; | |
9223 | incr = TREE_OPERAND (rhs, 1); | |
4b978f96 PC |
9224 | incr = cp_convert (TREE_TYPE (diff), incr, |
9225 | tf_warning_or_error); | |
a68ab351 JJ |
9226 | if (TREE_CODE (rhs) == MINUS_EXPR) |
9227 | { | |
9228 | incr = build1 (NEGATE_EXPR, TREE_TYPE (diff), incr); | |
cda0a029 | 9229 | incr = fold_simple (incr); |
a68ab351 JJ |
9230 | } |
9231 | if (TREE_CODE (incr) != INTEGER_CST | |
9232 | && (TREE_CODE (incr) != NOP_EXPR | |
9233 | || (TREE_CODE (TREE_OPERAND (incr, 0)) | |
9234 | != INTEGER_CST))) | |
9235 | iter_incr = NULL; | |
9236 | } | |
9237 | } | |
9238 | else if (TREE_OPERAND (rhs, 1) == iter) | |
9239 | { | |
9240 | if (TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs, 0))) != INTEGER_TYPE | |
9241 | || TREE_CODE (rhs) != PLUS_EXPR) | |
9242 | incr = error_mark_node; | |
9243 | else | |
9244 | { | |
f330f599 PC |
9245 | iter_incr = build_x_binary_op (EXPR_LOCATION (rhs), |
9246 | PLUS_EXPR, | |
a68ab351 JJ |
9247 | TREE_OPERAND (rhs, 0), |
9248 | ERROR_MARK, iter, | |
9249 | ERROR_MARK, NULL, | |
9250 | tf_warning_or_error); | |
9251 | if (error_operand_p (iter_incr)) | |
9252 | return true; | |
f330f599 PC |
9253 | iter_incr = build_x_modify_expr (EXPR_LOCATION (rhs), |
9254 | iter, NOP_EXPR, | |
a68ab351 JJ |
9255 | iter_incr, |
9256 | tf_warning_or_error); | |
9257 | if (error_operand_p (iter_incr)) | |
9258 | return true; | |
9259 | incr = TREE_OPERAND (rhs, 0); | |
9260 | iter_incr = NULL; | |
9261 | } | |
9262 | } | |
9263 | else | |
9264 | incr = error_mark_node; | |
9265 | } | |
9266 | else | |
9267 | incr = error_mark_node; | |
9268 | break; | |
9269 | default: | |
9270 | incr = error_mark_node; | |
9271 | break; | |
9272 | } | |
9273 | ||
9274 | if (incr == error_mark_node) | |
9275 | { | |
69bc6bff | 9276 | error_at (elocus, "invalid increment expression"); |
a68ab351 JJ |
9277 | return true; |
9278 | } | |
9279 | ||
4b978f96 | 9280 | incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error); |
28567c40 | 9281 | incr = cp_fully_fold (incr); |
d81ab49d | 9282 | tree loop_iv_seen = NULL_TREE; |
a68ab351 JJ |
9283 | for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) |
9284 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE | |
9285 | && OMP_CLAUSE_DECL (c) == iter) | |
d9a6bd32 | 9286 | { |
d81ab49d | 9287 | if (code == OMP_TASKLOOP || code == OMP_LOOP) |
d9a6bd32 | 9288 | { |
d81ab49d JJ |
9289 | loop_iv_seen = c; |
9290 | OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1; | |
d9a6bd32 JJ |
9291 | } |
9292 | break; | |
9293 | } | |
d81ab49d | 9294 | else if ((code == OMP_TASKLOOP || code == OMP_LOOP) |
d9a6bd32 JJ |
9295 | && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE |
9296 | && OMP_CLAUSE_DECL (c) == iter) | |
9297 | { | |
d81ab49d JJ |
9298 | loop_iv_seen = c; |
9299 | if (code == OMP_TASKLOOP) | |
9300 | OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1; | |
d9a6bd32 | 9301 | } |
a68ab351 JJ |
9302 | |
9303 | decl = create_temporary_var (TREE_TYPE (diff)); | |
9304 | pushdecl (decl); | |
9305 | add_decl_expr (decl); | |
9306 | last = create_temporary_var (TREE_TYPE (diff)); | |
9307 | pushdecl (last); | |
9308 | add_decl_expr (last); | |
d9a6bd32 JJ |
9309 | if (c && iter_incr == NULL && TREE_CODE (incr) != INTEGER_CST |
9310 | && (!ordered || (i < collapse && collapse > 1))) | |
a68ab351 JJ |
9311 | { |
9312 | incr_var = create_temporary_var (TREE_TYPE (diff)); | |
9313 | pushdecl (incr_var); | |
9314 | add_decl_expr (incr_var); | |
9315 | } | |
9316 | gcc_assert (stmts_are_full_exprs_p ()); | |
d9a6bd32 JJ |
9317 | tree diffvar = NULL_TREE; |
9318 | if (code == OMP_TASKLOOP) | |
9319 | { | |
d81ab49d | 9320 | if (!loop_iv_seen) |
d9a6bd32 JJ |
9321 | { |
9322 | tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); | |
9323 | OMP_CLAUSE_DECL (ivc) = iter; | |
972da557 | 9324 | cxx_omp_finish_clause (ivc, NULL, false); |
d9a6bd32 JJ |
9325 | OMP_CLAUSE_CHAIN (ivc) = clauses; |
9326 | clauses = ivc; | |
9327 | } | |
9328 | tree lvc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); | |
9329 | OMP_CLAUSE_DECL (lvc) = last; | |
9330 | OMP_CLAUSE_CHAIN (lvc) = clauses; | |
9331 | clauses = lvc; | |
9332 | diffvar = create_temporary_var (TREE_TYPE (diff)); | |
9333 | pushdecl (diffvar); | |
9334 | add_decl_expr (diffvar); | |
9335 | } | |
d81ab49d JJ |
9336 | else if (code == OMP_LOOP) |
9337 | { | |
9338 | if (!loop_iv_seen) | |
9339 | { | |
9340 | /* While iterators on the loop construct are predetermined | |
9341 | lastprivate, if the decl is not declared inside of the | |
9342 | loop, OMP_CLAUSE_LASTPRIVATE should have been added | |
9343 | already. */ | |
9344 | loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE); | |
9345 | OMP_CLAUSE_DECL (loop_iv_seen) = iter; | |
9346 | OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses; | |
9347 | clauses = loop_iv_seen; | |
9348 | } | |
9349 | else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE) | |
9350 | { | |
9351 | OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0; | |
9352 | OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0; | |
9353 | OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE; | |
9354 | } | |
9355 | if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE) | |
972da557 | 9356 | cxx_omp_finish_clause (loop_iv_seen, NULL, false); |
d81ab49d | 9357 | } |
a68ab351 JJ |
9358 | |
9359 | orig_pre_body = *pre_body; | |
9360 | *pre_body = push_stmt_list (); | |
9361 | if (orig_pre_body) | |
9362 | add_stmt (orig_pre_body); | |
9363 | if (init != NULL) | |
f330f599 PC |
9364 | finish_expr_stmt (build_x_modify_expr (elocus, |
9365 | iter, NOP_EXPR, init, | |
a68ab351 JJ |
9366 | tf_warning_or_error)); |
9367 | init = build_int_cst (TREE_TYPE (diff), 0); | |
d9a6bd32 JJ |
9368 | if (c && iter_incr == NULL |
9369 | && (!ordered || (i < collapse && collapse > 1))) | |
a68ab351 | 9370 | { |
d9a6bd32 JJ |
9371 | if (incr_var) |
9372 | { | |
9373 | finish_expr_stmt (build_x_modify_expr (elocus, | |
9374 | incr_var, NOP_EXPR, | |
9375 | incr, tf_warning_or_error)); | |
9376 | incr = incr_var; | |
9377 | } | |
f330f599 PC |
9378 | iter_incr = build_x_modify_expr (elocus, |
9379 | iter, PLUS_EXPR, incr, | |
a68ab351 JJ |
9380 | tf_warning_or_error); |
9381 | } | |
d9a6bd32 JJ |
9382 | if (c && ordered && i < collapse && collapse > 1) |
9383 | iter_incr = incr; | |
f330f599 PC |
9384 | finish_expr_stmt (build_x_modify_expr (elocus, |
9385 | last, NOP_EXPR, init, | |
a68ab351 | 9386 | tf_warning_or_error)); |
d9a6bd32 JJ |
9387 | if (diffvar) |
9388 | { | |
9389 | finish_expr_stmt (build_x_modify_expr (elocus, | |
9390 | diffvar, NOP_EXPR, | |
9391 | diff, tf_warning_or_error)); | |
9392 | diff = diffvar; | |
9393 | } | |
a68ab351 JJ |
9394 | *pre_body = pop_stmt_list (*pre_body); |
9395 | ||
ba47d38d AH |
9396 | cond = cp_build_binary_op (elocus, |
9397 | TREE_CODE (cond), decl, diff, | |
a68ab351 | 9398 | tf_warning_or_error); |
32e8bb8e | 9399 | incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR, |
c2255bc4 | 9400 | elocus, incr, NULL_TREE); |
a68ab351 JJ |
9401 | |
9402 | orig_body = *body; | |
9403 | *body = push_stmt_list (); | |
9404 | iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), decl, last); | |
f330f599 PC |
9405 | iter_init = build_x_modify_expr (elocus, |
9406 | iter, PLUS_EXPR, iter_init, | |
a68ab351 | 9407 | tf_warning_or_error); |
4e4d2c41 JJ |
9408 | if (iter_init != error_mark_node) |
9409 | iter_init = build1 (NOP_EXPR, void_type_node, iter_init); | |
a68ab351 | 9410 | finish_expr_stmt (iter_init); |
f330f599 PC |
9411 | finish_expr_stmt (build_x_modify_expr (elocus, |
9412 | last, NOP_EXPR, decl, | |
a68ab351 JJ |
9413 | tf_warning_or_error)); |
9414 | add_stmt (orig_body); | |
9415 | *body = pop_stmt_list (*body); | |
9416 | ||
9417 | if (c) | |
9418 | { | |
9419 | OMP_CLAUSE_LASTPRIVATE_STMT (c) = push_stmt_list (); | |
d9a6bd32 JJ |
9420 | if (!ordered) |
9421 | finish_expr_stmt (iter_incr); | |
9422 | else | |
9423 | { | |
9424 | iter_init = decl; | |
9425 | if (i < collapse && collapse > 1 && !error_operand_p (iter_incr)) | |
9426 | iter_init = build2 (PLUS_EXPR, TREE_TYPE (diff), | |
9427 | iter_init, iter_incr); | |
9428 | iter_init = build2 (MINUS_EXPR, TREE_TYPE (diff), iter_init, last); | |
9429 | iter_init = build_x_modify_expr (elocus, | |
9430 | iter, PLUS_EXPR, iter_init, | |
9431 | tf_warning_or_error); | |
9432 | if (iter_init != error_mark_node) | |
9433 | iter_init = build1 (NOP_EXPR, void_type_node, iter_init); | |
9434 | finish_expr_stmt (iter_init); | |
9435 | } | |
a68ab351 JJ |
9436 | OMP_CLAUSE_LASTPRIVATE_STMT (c) |
9437 | = pop_stmt_list (OMP_CLAUSE_LASTPRIVATE_STMT (c)); | |
9438 | } | |
9439 | ||
28567c40 JJ |
9440 | if (TREE_CODE (TREE_VEC_ELT (orig_declv, i)) == TREE_LIST) |
9441 | { | |
9442 | tree t = TREE_VEC_ELT (orig_declv, i); | |
9443 | gcc_assert (TREE_PURPOSE (t) == NULL_TREE | |
9444 | && TREE_VALUE (t) == NULL_TREE | |
9445 | && TREE_CODE (TREE_CHAIN (t)) == TREE_VEC); | |
9446 | TREE_PURPOSE (t) = TREE_VEC_ELT (declv, i); | |
9447 | TREE_VALUE (t) = last; | |
9448 | } | |
9449 | else | |
9450 | TREE_VEC_ELT (orig_declv, i) | |
9451 | = tree_cons (TREE_VEC_ELT (declv, i), last, NULL_TREE); | |
a68ab351 JJ |
9452 | TREE_VEC_ELT (declv, i) = decl; |
9453 | TREE_VEC_ELT (initv, i) = init; | |
9454 | TREE_VEC_ELT (condv, i) = cond; | |
9455 | TREE_VEC_ELT (incrv, i) = incr; | |
9456 | ||
9457 | return false; | |
9458 | } | |
9459 | ||
1799e5d5 RH |
9460 | /* Build and validate an OMP_FOR statement. CLAUSES, BODY, COND, INCR |
9461 | are directly for their associated operands in the statement. DECL | |
9462 | and INIT are a combo; if DECL is NULL then INIT ought to be a | |
9463 | MODIFY_EXPR, and the DECL should be extracted. PRE_BODY are | |
9464 | optional statements that need to go before the loop into its | |
9465 | sk_omp scope. */ | |
9466 | ||
9467 | tree | |
d9a6bd32 JJ |
9468 | finish_omp_for (location_t locus, enum tree_code code, tree declv, |
9469 | tree orig_declv, tree initv, tree condv, tree incrv, | |
e01d41e5 | 9470 | tree body, tree pre_body, vec<tree> *orig_inits, tree clauses) |
a68ab351 JJ |
9471 | { |
9472 | tree omp_for = NULL, orig_incr = NULL; | |
5e9d6aa4 | 9473 | tree decl = NULL, init, cond, incr; |
a68ab351 JJ |
9474 | location_t elocus; |
9475 | int i; | |
d9a6bd32 JJ |
9476 | int collapse = 1; |
9477 | int ordered = 0; | |
a68ab351 JJ |
9478 | |
9479 | gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv)); | |
9480 | gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv)); | |
9481 | gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv)); | |
d9a6bd32 JJ |
9482 | if (TREE_VEC_LENGTH (declv) > 1) |
9483 | { | |
02889d23 CLT |
9484 | tree c; |
9485 | ||
9486 | c = omp_find_clause (clauses, OMP_CLAUSE_TILE); | |
d9a6bd32 | 9487 | if (c) |
02889d23 CLT |
9488 | collapse = list_length (OMP_CLAUSE_TILE_LIST (c)); |
9489 | else | |
9490 | { | |
9491 | c = omp_find_clause (clauses, OMP_CLAUSE_COLLAPSE); | |
9492 | if (c) | |
9493 | collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c)); | |
9494 | if (collapse != TREE_VEC_LENGTH (declv)) | |
9495 | ordered = TREE_VEC_LENGTH (declv); | |
9496 | } | |
d9a6bd32 | 9497 | } |
a68ab351 JJ |
9498 | for (i = 0; i < TREE_VEC_LENGTH (declv); i++) |
9499 | { | |
9500 | decl = TREE_VEC_ELT (declv, i); | |
9501 | init = TREE_VEC_ELT (initv, i); | |
9502 | cond = TREE_VEC_ELT (condv, i); | |
9503 | incr = TREE_VEC_ELT (incrv, i); | |
9504 | elocus = locus; | |
9505 | ||
9506 | if (decl == NULL) | |
9507 | { | |
9508 | if (init != NULL) | |
9509 | switch (TREE_CODE (init)) | |
1799e5d5 | 9510 | { |
a68ab351 | 9511 | case MODIFY_EXPR: |
1799e5d5 | 9512 | decl = TREE_OPERAND (init, 0); |
a68ab351 JJ |
9513 | init = TREE_OPERAND (init, 1); |
9514 | break; | |
9515 | case MODOP_EXPR: | |
9516 | if (TREE_CODE (TREE_OPERAND (init, 1)) == NOP_EXPR) | |
9517 | { | |
9518 | decl = TREE_OPERAND (init, 0); | |
9519 | init = TREE_OPERAND (init, 2); | |
9520 | } | |
9521 | break; | |
9522 | default: | |
9523 | break; | |
1799e5d5 | 9524 | } |
1799e5d5 | 9525 | |
a68ab351 JJ |
9526 | if (decl == NULL) |
9527 | { | |
69bc6bff MLI |
9528 | error_at (locus, |
9529 | "expected iteration declaration or initialization"); | |
a68ab351 JJ |
9530 | return NULL; |
9531 | } | |
1799e5d5 | 9532 | } |
1799e5d5 | 9533 | |
a68ab351 JJ |
9534 | if (init && EXPR_HAS_LOCATION (init)) |
9535 | elocus = EXPR_LOCATION (init); | |
1799e5d5 | 9536 | |
28567c40 JJ |
9537 | if (cond == global_namespace) |
9538 | continue; | |
9539 | ||
1799e5d5 RH |
9540 | if (cond == NULL) |
9541 | { | |
69bc6bff | 9542 | error_at (elocus, "missing controlling predicate"); |
1799e5d5 RH |
9543 | return NULL; |
9544 | } | |
9545 | ||
9546 | if (incr == NULL) | |
9547 | { | |
69bc6bff | 9548 | error_at (elocus, "missing increment expression"); |
1799e5d5 RH |
9549 | return NULL; |
9550 | } | |
9551 | ||
a68ab351 JJ |
9552 | TREE_VEC_ELT (declv, i) = decl; |
9553 | TREE_VEC_ELT (initv, i) = init; | |
9554 | } | |
9555 | ||
e01d41e5 JJ |
9556 | if (orig_inits) |
9557 | { | |
9558 | bool fail = false; | |
9559 | tree orig_init; | |
9560 | FOR_EACH_VEC_ELT (*orig_inits, i, orig_init) | |
9561 | if (orig_init | |
1160ec9a JJ |
9562 | && !c_omp_check_loop_iv_exprs (locus, |
9563 | orig_declv ? orig_declv : declv, i, | |
e01d41e5 JJ |
9564 | TREE_VEC_ELT (declv, i), orig_init, |
9565 | NULL_TREE, cp_walk_subtrees)) | |
9566 | fail = true; | |
9567 | if (fail) | |
9568 | return NULL; | |
9569 | } | |
9570 | ||
a68ab351 JJ |
9571 | if (dependent_omp_for_p (declv, initv, condv, incrv)) |
9572 | { | |
9573 | tree stmt; | |
9574 | ||
acf0174b | 9575 | stmt = make_node (code); |
1799e5d5 | 9576 | |
a68ab351 JJ |
9577 | for (i = 0; i < TREE_VEC_LENGTH (declv); i++) |
9578 | { | |
9579 | /* This is really just a place-holder. We'll be decomposing this | |
9580 | again and going through the cp_build_modify_expr path below when | |
9581 | we instantiate the thing. */ | |
9582 | TREE_VEC_ELT (initv, i) | |
9583 | = build2 (MODIFY_EXPR, void_type_node, TREE_VEC_ELT (declv, i), | |
9584 | TREE_VEC_ELT (initv, i)); | |
9585 | } | |
1799e5d5 RH |
9586 | |
9587 | TREE_TYPE (stmt) = void_type_node; | |
a68ab351 JJ |
9588 | OMP_FOR_INIT (stmt) = initv; |
9589 | OMP_FOR_COND (stmt) = condv; | |
9590 | OMP_FOR_INCR (stmt) = incrv; | |
1799e5d5 RH |
9591 | OMP_FOR_BODY (stmt) = body; |
9592 | OMP_FOR_PRE_BODY (stmt) = pre_body; | |
a68ab351 | 9593 | OMP_FOR_CLAUSES (stmt) = clauses; |
1799e5d5 RH |
9594 | |
9595 | SET_EXPR_LOCATION (stmt, locus); | |
9596 | return add_stmt (stmt); | |
9597 | } | |
9598 | ||
d9a6bd32 JJ |
9599 | if (!orig_declv) |
9600 | orig_declv = copy_node (declv); | |
9601 | ||
a68ab351 JJ |
9602 | if (processing_template_decl) |
9603 | orig_incr = make_tree_vec (TREE_VEC_LENGTH (incrv)); | |
1799e5d5 | 9604 | |
a68ab351 | 9605 | for (i = 0; i < TREE_VEC_LENGTH (declv); ) |
dadb19e0 | 9606 | { |
a68ab351 JJ |
9607 | decl = TREE_VEC_ELT (declv, i); |
9608 | init = TREE_VEC_ELT (initv, i); | |
9609 | cond = TREE_VEC_ELT (condv, i); | |
9610 | incr = TREE_VEC_ELT (incrv, i); | |
9611 | if (orig_incr) | |
9612 | TREE_VEC_ELT (orig_incr, i) = incr; | |
9613 | elocus = locus; | |
9614 | ||
9615 | if (init && EXPR_HAS_LOCATION (init)) | |
dadb19e0 | 9616 | elocus = EXPR_LOCATION (init); |
dadb19e0 | 9617 | |
a68ab351 JJ |
9618 | if (!DECL_P (decl)) |
9619 | { | |
69bc6bff | 9620 | error_at (elocus, "expected iteration declaration or initialization"); |
a68ab351 JJ |
9621 | return NULL; |
9622 | } | |
969c111d | 9623 | |
a68ab351 JJ |
9624 | if (incr && TREE_CODE (incr) == MODOP_EXPR) |
9625 | { | |
9626 | if (orig_incr) | |
9627 | TREE_VEC_ELT (orig_incr, i) = incr; | |
4f2e1536 | 9628 | incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0), |
a68ab351 JJ |
9629 | TREE_CODE (TREE_OPERAND (incr, 1)), |
9630 | TREE_OPERAND (incr, 2), | |
9631 | tf_warning_or_error); | |
9632 | } | |
9633 | ||
9634 | if (CLASS_TYPE_P (TREE_TYPE (decl))) | |
9635 | { | |
acf0174b JJ |
9636 | if (code == OMP_SIMD) |
9637 | { | |
9638 | error_at (elocus, "%<#pragma omp simd%> used with class " | |
9639 | "iteration variable %qE", decl); | |
9640 | return NULL; | |
9641 | } | |
e01d41e5 JJ |
9642 | if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv, |
9643 | initv, condv, incrv, &body, | |
0b27c3ed | 9644 | &pre_body, clauses, |
e01d41e5 | 9645 | collapse, ordered)) |
a68ab351 JJ |
9646 | return NULL; |
9647 | continue; | |
9648 | } | |
9649 | ||
9650 | if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)) | |
50e10fa8 | 9651 | && !TYPE_PTR_P (TREE_TYPE (decl))) |
a68ab351 | 9652 | { |
69bc6bff | 9653 | error_at (elocus, "invalid type for iteration variable %qE", decl); |
a68ab351 JJ |
9654 | return NULL; |
9655 | } | |
969c111d | 9656 | |
1160ec9a JJ |
9657 | if (!processing_template_decl && TREE_CODE (init) != TREE_VEC) |
9658 | init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init, | |
9659 | tf_warning_or_error); | |
8569b2d0 JJ |
9660 | else |
9661 | init = build2 (MODIFY_EXPR, void_type_node, decl, init); | |
a68ab351 JJ |
9662 | if (decl == error_mark_node || init == error_mark_node) |
9663 | return NULL; | |
9664 | ||
9665 | TREE_VEC_ELT (declv, i) = decl; | |
9666 | TREE_VEC_ELT (initv, i) = init; | |
9667 | TREE_VEC_ELT (condv, i) = cond; | |
9668 | TREE_VEC_ELT (incrv, i) = incr; | |
9669 | i++; | |
969c111d | 9670 | } |
a68ab351 | 9671 | |
28567c40 | 9672 | if (pre_body && IS_EMPTY_STMT (pre_body)) |
a68ab351 JJ |
9673 | pre_body = NULL; |
9674 | ||
d9a6bd32 | 9675 | omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv, |
28567c40 JJ |
9676 | incrv, body, pre_body, |
9677 | !processing_template_decl); | |
a68ab351 | 9678 | |
e01d41e5 JJ |
9679 | /* Check for iterators appearing in lb, b or incr expressions. */ |
9680 | if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees)) | |
9681 | omp_for = NULL_TREE; | |
9682 | ||
a68ab351 | 9683 | if (omp_for == NULL) |
d81ab49d | 9684 | return NULL; |
a68ab351 | 9685 | |
e01d41e5 JJ |
9686 | add_stmt (omp_for); |
9687 | ||
a68ab351 | 9688 | for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++) |
969c111d | 9689 | { |
1160ec9a JJ |
9690 | init = TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i); |
9691 | decl = TREE_OPERAND (init, 0); | |
9692 | cond = TREE_VEC_ELT (OMP_FOR_COND (omp_for), i); | |
e4ebaef3 | 9693 | incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i); |
969c111d | 9694 | |
1160ec9a JJ |
9695 | if (!processing_template_decl) |
9696 | { | |
9697 | if (TREE_CODE (TREE_OPERAND (init, 1)) == TREE_VEC) | |
9698 | { | |
9699 | tree t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 1); | |
9700 | TREE_VEC_ELT (TREE_OPERAND (init, 1), 1) | |
9701 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9702 | t = TREE_VEC_ELT (TREE_OPERAND (init, 1), 2); | |
9703 | TREE_VEC_ELT (TREE_OPERAND (init, 1), 2) | |
9704 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9705 | } | |
9706 | else | |
9707 | { | |
9708 | tree t = TREE_OPERAND (init, 1); | |
9709 | TREE_OPERAND (init, 1) | |
9710 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9711 | } | |
9712 | if (TREE_CODE (TREE_OPERAND (cond, 1)) == TREE_VEC) | |
9713 | { | |
9714 | tree t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1); | |
9715 | TREE_VEC_ELT (TREE_OPERAND (cond, 1), 1) | |
9716 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9717 | t = TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2); | |
9718 | TREE_VEC_ELT (TREE_OPERAND (cond, 1), 2) | |
9719 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9720 | } | |
9721 | else | |
9722 | { | |
9723 | tree t = TREE_OPERAND (cond, 1); | |
9724 | TREE_OPERAND (cond, 1) | |
9725 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
9726 | } | |
9727 | } | |
9728 | ||
a68ab351 JJ |
9729 | if (TREE_CODE (incr) != MODIFY_EXPR) |
9730 | continue; | |
9731 | ||
9732 | if (TREE_SIDE_EFFECTS (TREE_OPERAND (incr, 1)) | |
e4ebaef3 JJ |
9733 | && BINARY_CLASS_P (TREE_OPERAND (incr, 1)) |
9734 | && !processing_template_decl) | |
a68ab351 | 9735 | { |
e4ebaef3 JJ |
9736 | tree t = TREE_OPERAND (TREE_OPERAND (incr, 1), 0); |
9737 | if (TREE_SIDE_EFFECTS (t) | |
9738 | && t != decl | |
9739 | && (TREE_CODE (t) != NOP_EXPR | |
9740 | || TREE_OPERAND (t, 0) != decl)) | |
9741 | TREE_OPERAND (TREE_OPERAND (incr, 1), 0) | |
9742 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
a68ab351 | 9743 | |
e4ebaef3 JJ |
9744 | t = TREE_OPERAND (TREE_OPERAND (incr, 1), 1); |
9745 | if (TREE_SIDE_EFFECTS (t) | |
9746 | && t != decl | |
9747 | && (TREE_CODE (t) != NOP_EXPR | |
9748 | || TREE_OPERAND (t, 0) != decl)) | |
9749 | TREE_OPERAND (TREE_OPERAND (incr, 1), 1) | |
9750 | = fold_build_cleanup_point_expr (TREE_TYPE (t), t); | |
a68ab351 JJ |
9751 | } |
9752 | ||
9753 | if (orig_incr) | |
9754 | TREE_VEC_ELT (OMP_FOR_INCR (omp_for), i) = TREE_VEC_ELT (orig_incr, i); | |
969c111d | 9755 | } |
9a771876 JJ |
9756 | OMP_FOR_CLAUSES (omp_for) = clauses; |
9757 | ||
d9a6bd32 JJ |
9758 | /* For simd loops with non-static data member iterators, we could have added |
9759 | OMP_CLAUSE_LINEAR clauses without OMP_CLAUSE_LINEAR_STEP. As we know the | |
9760 | step at this point, fill it in. */ | |
9761 | if (code == OMP_SIMD && !processing_template_decl | |
9762 | && TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)) == 1) | |
629b3d75 MJ |
9763 | for (tree c = omp_find_clause (clauses, OMP_CLAUSE_LINEAR); c; |
9764 | c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE_LINEAR)) | |
d9a6bd32 JJ |
9765 | if (OMP_CLAUSE_LINEAR_STEP (c) == NULL_TREE) |
9766 | { | |
9767 | decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), 0), 0); | |
9768 | gcc_assert (decl == OMP_CLAUSE_DECL (c)); | |
9769 | incr = TREE_VEC_ELT (OMP_FOR_INCR (omp_for), 0); | |
9770 | tree step, stept; | |
9771 | switch (TREE_CODE (incr)) | |
9772 | { | |
9773 | case PREINCREMENT_EXPR: | |
9774 | case POSTINCREMENT_EXPR: | |
9775 | /* c_omp_for_incr_canonicalize_ptr() should have been | |
9776 | called to massage things appropriately. */ | |
71a93b08 | 9777 | gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl))); |
d9a6bd32 JJ |
9778 | OMP_CLAUSE_LINEAR_STEP (c) = build_int_cst (TREE_TYPE (decl), 1); |
9779 | break; | |
9780 | case PREDECREMENT_EXPR: | |
9781 | case POSTDECREMENT_EXPR: | |
9782 | /* c_omp_for_incr_canonicalize_ptr() should have been | |
9783 | called to massage things appropriately. */ | |
71a93b08 | 9784 | gcc_assert (!INDIRECT_TYPE_P (TREE_TYPE (decl))); |
d9a6bd32 JJ |
9785 | OMP_CLAUSE_LINEAR_STEP (c) |
9786 | = build_int_cst (TREE_TYPE (decl), -1); | |
9787 | break; | |
9788 | case MODIFY_EXPR: | |
9789 | gcc_assert (TREE_OPERAND (incr, 0) == decl); | |
9790 | incr = TREE_OPERAND (incr, 1); | |
9791 | switch (TREE_CODE (incr)) | |
9792 | { | |
9793 | case PLUS_EXPR: | |
9794 | if (TREE_OPERAND (incr, 1) == decl) | |
9795 | step = TREE_OPERAND (incr, 0); | |
9796 | else | |
9797 | step = TREE_OPERAND (incr, 1); | |
9798 | break; | |
9799 | case MINUS_EXPR: | |
9800 | case POINTER_PLUS_EXPR: | |
9801 | gcc_assert (TREE_OPERAND (incr, 0) == decl); | |
9802 | step = TREE_OPERAND (incr, 1); | |
9803 | break; | |
9804 | default: | |
9805 | gcc_unreachable (); | |
9806 | } | |
9807 | stept = TREE_TYPE (decl); | |
71a93b08 | 9808 | if (INDIRECT_TYPE_P (stept)) |
d9a6bd32 JJ |
9809 | stept = sizetype; |
9810 | step = fold_convert (stept, step); | |
9811 | if (TREE_CODE (incr) == MINUS_EXPR) | |
9812 | step = fold_build1 (NEGATE_EXPR, stept, step); | |
9813 | OMP_CLAUSE_LINEAR_STEP (c) = step; | |
9814 | break; | |
9815 | default: | |
9816 | gcc_unreachable (); | |
9817 | } | |
9818 | } | |
d81ab49d JJ |
9819 | /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV |
9820 | clauses, we need copy ctor for those rather than default ctor, | |
9821 | plus as for other lastprivates assignment op and dtor. */ | |
9822 | if (code == OMP_LOOP && !processing_template_decl) | |
9823 | for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) | |
9824 | if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE | |
9825 | && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) | |
9826 | && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)), | |
9827 | false, true, true, true)) | |
9828 | CP_OMP_CLAUSE_INFO (c) = NULL_TREE; | |
d9a6bd32 | 9829 | |
969c111d | 9830 | return omp_for; |
1799e5d5 RH |
9831 | } |
9832 | ||
28567c40 JJ |
9833 | /* Fix up range for decls. Those decls were pushed into BIND's BIND_EXPR_VARS |
9834 | and need to be moved into the BIND_EXPR inside of the OMP_FOR's body. */ | |
9835 | ||
9836 | tree | |
9837 | finish_omp_for_block (tree bind, tree omp_for) | |
9838 | { | |
9839 | if (omp_for == NULL_TREE | |
9840 | || !OMP_FOR_ORIG_DECLS (omp_for) | |
9841 | || bind == NULL_TREE | |
9842 | || TREE_CODE (bind) != BIND_EXPR) | |
9843 | return bind; | |
9844 | tree b = NULL_TREE; | |
9845 | for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (omp_for)); i++) | |
9846 | if (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)) == TREE_LIST | |
9847 | && TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i))) | |
9848 | { | |
9849 | tree v = TREE_CHAIN (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (omp_for), i)); | |
9850 | gcc_assert (BIND_EXPR_BLOCK (bind) | |
9851 | && (BIND_EXPR_VARS (bind) | |
9852 | == BLOCK_VARS (BIND_EXPR_BLOCK (bind)))); | |
9853 | for (int j = 2; j < TREE_VEC_LENGTH (v); j++) | |
9854 | for (tree *p = &BIND_EXPR_VARS (bind); *p; p = &DECL_CHAIN (*p)) | |
9855 | { | |
9856 | if (*p == TREE_VEC_ELT (v, j)) | |
9857 | { | |
9858 | tree var = *p; | |
9859 | *p = DECL_CHAIN (*p); | |
9860 | if (b == NULL_TREE) | |
9861 | { | |
9862 | b = make_node (BLOCK); | |
9863 | b = build3 (BIND_EXPR, void_type_node, NULL_TREE, | |
9864 | OMP_FOR_BODY (omp_for), b); | |
9865 | TREE_SIDE_EFFECTS (b) = 1; | |
9866 | OMP_FOR_BODY (omp_for) = b; | |
9867 | } | |
9868 | DECL_CHAIN (var) = BIND_EXPR_VARS (b); | |
9869 | BIND_EXPR_VARS (b) = var; | |
9870 | BLOCK_VARS (BIND_EXPR_BLOCK (b)) = var; | |
9871 | } | |
9872 | } | |
9873 | BLOCK_VARS (BIND_EXPR_BLOCK (bind)) = BIND_EXPR_VARS (bind); | |
9874 | } | |
9875 | return bind; | |
9876 | } | |
9877 | ||
1799e5d5 | 9878 | void |
28567c40 | 9879 | finish_omp_atomic (location_t loc, enum tree_code code, enum tree_code opcode, |
3a2bcffa JJ |
9880 | tree lhs, tree rhs, tree v, tree lhs1, tree rhs1, tree r, |
9881 | tree clauses, enum omp_memory_order mo, bool weak) | |
1799e5d5 | 9882 | { |
239371f9 JJ |
9883 | tree orig_lhs; |
9884 | tree orig_rhs; | |
20906c66 JJ |
9885 | tree orig_v; |
9886 | tree orig_lhs1; | |
9887 | tree orig_rhs1; | |
3a2bcffa | 9888 | tree orig_r; |
239371f9 | 9889 | bool dependent_p; |
e6bd5565 MM |
9890 | tree stmt; |
9891 | ||
239371f9 JJ |
9892 | orig_lhs = lhs; |
9893 | orig_rhs = rhs; | |
20906c66 JJ |
9894 | orig_v = v; |
9895 | orig_lhs1 = lhs1; | |
9896 | orig_rhs1 = rhs1; | |
3a2bcffa | 9897 | orig_r = r; |
239371f9 JJ |
9898 | dependent_p = false; |
9899 | stmt = NULL_TREE; | |
9900 | ||
9901 | /* Even in a template, we can detect invalid uses of the atomic | |
9902 | pragma if neither LHS nor RHS is type-dependent. */ | |
9903 | if (processing_template_decl) | |
e6bd5565 | 9904 | { |
239371f9 | 9905 | dependent_p = (type_dependent_expression_p (lhs) |
20906c66 JJ |
9906 | || (rhs && type_dependent_expression_p (rhs)) |
9907 | || (v && type_dependent_expression_p (v)) | |
9908 | || (lhs1 && type_dependent_expression_p (lhs1)) | |
3a2bcffa JJ |
9909 | || (rhs1 && type_dependent_expression_p (rhs1)) |
9910 | || (r | |
9911 | && r != void_list_node | |
9912 | && type_dependent_expression_p (r))); | |
28567c40 JJ |
9913 | if (clauses) |
9914 | { | |
9915 | gcc_assert (TREE_CODE (clauses) == OMP_CLAUSE | |
9916 | && OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_HINT | |
9917 | && OMP_CLAUSE_CHAIN (clauses) == NULL_TREE); | |
9918 | if (type_dependent_expression_p (OMP_CLAUSE_HINT_EXPR (clauses)) | |
9919 | || TREE_CODE (OMP_CLAUSE_HINT_EXPR (clauses)) != INTEGER_CST) | |
9920 | dependent_p = true; | |
9921 | } | |
239371f9 | 9922 | if (!dependent_p) |
e6bd5565 MM |
9923 | { |
9924 | lhs = build_non_dependent_expr (lhs); | |
20906c66 JJ |
9925 | if (rhs) |
9926 | rhs = build_non_dependent_expr (rhs); | |
9927 | if (v) | |
9928 | v = build_non_dependent_expr (v); | |
9929 | if (lhs1) | |
9930 | lhs1 = build_non_dependent_expr (lhs1); | |
9931 | if (rhs1) | |
9932 | rhs1 = build_non_dependent_expr (rhs1); | |
3a2bcffa JJ |
9933 | if (r && r != void_list_node) |
9934 | r = build_non_dependent_expr (r); | |
e6bd5565 | 9935 | } |
239371f9 JJ |
9936 | } |
9937 | if (!dependent_p) | |
9938 | { | |
acf0174b | 9939 | bool swapped = false; |
3a2bcffa | 9940 | if (rhs1 && opcode != COND_EXPR && cp_tree_equal (lhs, rhs)) |
acf0174b | 9941 | { |
6b4db501 | 9942 | std::swap (rhs, rhs1); |
acf0174b JJ |
9943 | swapped = !commutative_tree_code (opcode); |
9944 | } | |
3a2bcffa | 9945 | if (rhs1 && opcode != COND_EXPR && !cp_tree_equal (lhs, rhs1)) |
acf0174b JJ |
9946 | { |
9947 | if (code == OMP_ATOMIC) | |
9948 | error ("%<#pragma omp atomic update%> uses two different " | |
9949 | "expressions for memory"); | |
9950 | else | |
9951 | error ("%<#pragma omp atomic capture%> uses two different " | |
9952 | "expressions for memory"); | |
9953 | return; | |
9954 | } | |
9955 | if (lhs1 && !cp_tree_equal (lhs, lhs1)) | |
9956 | { | |
9957 | if (code == OMP_ATOMIC) | |
9958 | error ("%<#pragma omp atomic update%> uses two different " | |
9959 | "expressions for memory"); | |
9960 | else | |
9961 | error ("%<#pragma omp atomic capture%> uses two different " | |
9962 | "expressions for memory"); | |
9963 | return; | |
9964 | } | |
28567c40 | 9965 | stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, |
3a2bcffa | 9966 | v, lhs1, rhs1, r, swapped, mo, weak, |
e01d41e5 | 9967 | processing_template_decl != 0); |
239371f9 JJ |
9968 | if (stmt == error_mark_node) |
9969 | return; | |
e6bd5565 | 9970 | } |
239371f9 | 9971 | if (processing_template_decl) |
20906c66 JJ |
9972 | { |
9973 | if (code == OMP_ATOMIC_READ) | |
9974 | { | |
28567c40 JJ |
9975 | stmt = build_min_nt_loc (loc, OMP_ATOMIC_READ, orig_lhs); |
9976 | OMP_ATOMIC_MEMORY_ORDER (stmt) = mo; | |
20906c66 JJ |
9977 | stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt); |
9978 | } | |
9979 | else | |
9980 | { | |
9981 | if (opcode == NOP_EXPR) | |
9982 | stmt = build2 (MODIFY_EXPR, void_type_node, orig_lhs, orig_rhs); | |
3a2bcffa JJ |
9983 | else if (opcode == COND_EXPR) |
9984 | { | |
9985 | stmt = build2 (EQ_EXPR, boolean_type_node, orig_lhs, orig_rhs); | |
9986 | if (orig_r) | |
9987 | stmt = build2 (MODIFY_EXPR, boolean_type_node, orig_r, | |
9988 | stmt); | |
9989 | stmt = build3 (COND_EXPR, void_type_node, stmt, orig_rhs1, | |
9990 | orig_lhs); | |
9991 | orig_rhs1 = NULL_TREE; | |
9992 | } | |
43e1e8b5 | 9993 | else |
20906c66 JJ |
9994 | stmt = build2 (opcode, void_type_node, orig_lhs, orig_rhs); |
9995 | if (orig_rhs1) | |
f330f599 PC |
9996 | stmt = build_min_nt_loc (EXPR_LOCATION (orig_rhs1), |
9997 | COMPOUND_EXPR, orig_rhs1, stmt); | |
20906c66 JJ |
9998 | if (code != OMP_ATOMIC) |
9999 | { | |
28567c40 JJ |
10000 | stmt = build_min_nt_loc (loc, code, orig_lhs1, stmt); |
10001 | OMP_ATOMIC_MEMORY_ORDER (stmt) = mo; | |
3a2bcffa | 10002 | OMP_ATOMIC_WEAK (stmt) = weak; |
20906c66 JJ |
10003 | stmt = build2 (MODIFY_EXPR, void_type_node, orig_v, stmt); |
10004 | } | |
10005 | } | |
28567c40 JJ |
10006 | stmt = build2 (OMP_ATOMIC, void_type_node, |
10007 | clauses ? clauses : integer_zero_node, stmt); | |
10008 | OMP_ATOMIC_MEMORY_ORDER (stmt) = mo; | |
3a2bcffa | 10009 | OMP_ATOMIC_WEAK (stmt) = weak; |
28567c40 | 10010 | SET_EXPR_LOCATION (stmt, loc); |
20906c66 | 10011 | } |
22a32ea0 JJ |
10012 | |
10013 | /* Avoid -Wunused-value warnings here, the whole construct has side-effects | |
10014 | and even if it might be wrapped from fold-const.c or c-omp.c wrapped | |
10015 | in some tree that appears to be unused, the value is not unused. */ | |
10016 | warning_sentinel w (warn_unused_value); | |
e3f505d8 | 10017 | finish_expr_stmt (stmt); |
1799e5d5 RH |
10018 | } |
10019 | ||
10020 | void | |
10021 | finish_omp_barrier (void) | |
10022 | { | |
e79983f4 | 10023 | tree fn = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER); |
cd9cf97b | 10024 | releasing_vec vec; |
c166b898 | 10025 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); |
1799e5d5 RH |
10026 | finish_expr_stmt (stmt); |
10027 | } | |
10028 | ||
10029 | void | |
28567c40 JJ |
10030 | finish_omp_depobj (location_t loc, tree depobj, |
10031 | enum omp_clause_depend_kind kind, tree clause) | |
10032 | { | |
10033 | if (!error_operand_p (depobj) && !type_dependent_expression_p (depobj)) | |
10034 | { | |
10035 | if (!lvalue_p (depobj)) | |
10036 | { | |
10037 | error_at (EXPR_LOC_OR_LOC (depobj, loc), | |
10038 | "%<depobj%> expression is not lvalue expression"); | |
10039 | depobj = error_mark_node; | |
10040 | } | |
10041 | } | |
10042 | ||
10043 | if (processing_template_decl) | |
10044 | { | |
10045 | if (clause == NULL_TREE) | |
10046 | clause = build_int_cst (integer_type_node, kind); | |
10047 | add_stmt (build_min_nt_loc (loc, OMP_DEPOBJ, depobj, clause)); | |
10048 | return; | |
10049 | } | |
10050 | ||
10051 | if (!error_operand_p (depobj)) | |
10052 | { | |
10053 | tree addr = cp_build_addr_expr (depobj, tf_warning_or_error); | |
10054 | if (addr == error_mark_node) | |
10055 | depobj = error_mark_node; | |
10056 | else | |
3554d8ff | 10057 | depobj = cp_build_indirect_ref (loc, addr, RO_UNARY_STAR, |
28567c40 JJ |
10058 | tf_warning_or_error); |
10059 | } | |
10060 | ||
10061 | c_finish_omp_depobj (loc, depobj, kind, clause); | |
10062 | } | |
10063 | ||
10064 | void | |
10065 | finish_omp_flush (int mo) | |
1799e5d5 | 10066 | { |
e79983f4 | 10067 | tree fn = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE); |
cd9cf97b | 10068 | releasing_vec vec; |
ba1cc695 | 10069 | if (mo != MEMMODEL_LAST && mo != MEMMODEL_SEQ_CST) |
28567c40 JJ |
10070 | { |
10071 | fn = builtin_decl_explicit (BUILT_IN_ATOMIC_THREAD_FENCE); | |
10072 | vec->quick_push (build_int_cst (integer_type_node, mo)); | |
10073 | } | |
c166b898 | 10074 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); |
1799e5d5 RH |
10075 | finish_expr_stmt (stmt); |
10076 | } | |
10077 | ||
a68ab351 JJ |
10078 | void |
10079 | finish_omp_taskwait (void) | |
1799e5d5 | 10080 | { |
e79983f4 | 10081 | tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT); |
cd9cf97b | 10082 | releasing_vec vec; |
c166b898 | 10083 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); |
a68ab351 | 10084 | finish_expr_stmt (stmt); |
1799e5d5 | 10085 | } |
20906c66 JJ |
10086 | |
10087 | void | |
10088 | finish_omp_taskyield (void) | |
10089 | { | |
e79983f4 | 10090 | tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD); |
cd9cf97b | 10091 | releasing_vec vec; |
20906c66 | 10092 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); |
20906c66 JJ |
10093 | finish_expr_stmt (stmt); |
10094 | } | |
acf0174b JJ |
10095 | |
10096 | void | |
10097 | finish_omp_cancel (tree clauses) | |
10098 | { | |
10099 | tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCEL); | |
10100 | int mask = 0; | |
629b3d75 | 10101 | if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL)) |
acf0174b | 10102 | mask = 1; |
629b3d75 | 10103 | else if (omp_find_clause (clauses, OMP_CLAUSE_FOR)) |
acf0174b | 10104 | mask = 2; |
629b3d75 | 10105 | else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS)) |
acf0174b | 10106 | mask = 4; |
629b3d75 | 10107 | else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP)) |
acf0174b JJ |
10108 | mask = 8; |
10109 | else | |
10110 | { | |
54d19c3b | 10111 | error ("%<#pragma omp cancel%> must specify one of " |
acf0174b JJ |
10112 | "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses"); |
10113 | return; | |
10114 | } | |
cd9cf97b | 10115 | releasing_vec vec; |
629b3d75 | 10116 | tree ifc = omp_find_clause (clauses, OMP_CLAUSE_IF); |
acf0174b JJ |
10117 | if (ifc != NULL_TREE) |
10118 | { | |
28567c40 JJ |
10119 | if (OMP_CLAUSE_IF_MODIFIER (ifc) != ERROR_MARK |
10120 | && OMP_CLAUSE_IF_MODIFIER (ifc) != VOID_CST) | |
10121 | error_at (OMP_CLAUSE_LOCATION (ifc), | |
10122 | "expected %<cancel%> %<if%> clause modifier"); | |
e21c4491 JJ |
10123 | else |
10124 | { | |
10125 | tree ifc2 = omp_find_clause (OMP_CLAUSE_CHAIN (ifc), OMP_CLAUSE_IF); | |
10126 | if (ifc2 != NULL_TREE) | |
10127 | { | |
10128 | gcc_assert (OMP_CLAUSE_IF_MODIFIER (ifc) == VOID_CST | |
10129 | && OMP_CLAUSE_IF_MODIFIER (ifc2) != ERROR_MARK | |
10130 | && OMP_CLAUSE_IF_MODIFIER (ifc2) != VOID_CST); | |
10131 | error_at (OMP_CLAUSE_LOCATION (ifc2), | |
10132 | "expected %<cancel%> %<if%> clause modifier"); | |
10133 | } | |
10134 | } | |
28567c40 | 10135 | |
e21c4491 JJ |
10136 | if (!processing_template_decl) |
10137 | ifc = maybe_convert_cond (OMP_CLAUSE_IF_EXPR (ifc)); | |
10138 | else | |
10139 | ifc = build_x_binary_op (OMP_CLAUSE_LOCATION (ifc), NE_EXPR, | |
10140 | OMP_CLAUSE_IF_EXPR (ifc), ERROR_MARK, | |
10141 | integer_zero_node, ERROR_MARK, | |
10142 | NULL, tf_warning_or_error); | |
acf0174b JJ |
10143 | } |
10144 | else | |
10145 | ifc = boolean_true_node; | |
10146 | vec->quick_push (build_int_cst (integer_type_node, mask)); | |
10147 | vec->quick_push (ifc); | |
10148 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); | |
acf0174b JJ |
10149 | finish_expr_stmt (stmt); |
10150 | } | |
10151 | ||
10152 | void | |
10153 | finish_omp_cancellation_point (tree clauses) | |
10154 | { | |
10155 | tree fn = builtin_decl_explicit (BUILT_IN_GOMP_CANCELLATION_POINT); | |
10156 | int mask = 0; | |
629b3d75 | 10157 | if (omp_find_clause (clauses, OMP_CLAUSE_PARALLEL)) |
acf0174b | 10158 | mask = 1; |
629b3d75 | 10159 | else if (omp_find_clause (clauses, OMP_CLAUSE_FOR)) |
acf0174b | 10160 | mask = 2; |
629b3d75 | 10161 | else if (omp_find_clause (clauses, OMP_CLAUSE_SECTIONS)) |
acf0174b | 10162 | mask = 4; |
629b3d75 | 10163 | else if (omp_find_clause (clauses, OMP_CLAUSE_TASKGROUP)) |
acf0174b JJ |
10164 | mask = 8; |
10165 | else | |
10166 | { | |
54d19c3b | 10167 | error ("%<#pragma omp cancellation point%> must specify one of " |
acf0174b JJ |
10168 | "%<parallel%>, %<for%>, %<sections%> or %<taskgroup%> clauses"); |
10169 | return; | |
10170 | } | |
cd9cf97b | 10171 | releasing_vec vec |
acf0174b JJ |
10172 | = make_tree_vector_single (build_int_cst (integer_type_node, mask)); |
10173 | tree stmt = finish_call_expr (fn, &vec, false, false, tf_warning_or_error); | |
acf0174b JJ |
10174 | finish_expr_stmt (stmt); |
10175 | } | |
1799e5d5 | 10176 | \f |
0a35513e AH |
10177 | /* Begin a __transaction_atomic or __transaction_relaxed statement. |
10178 | If PCOMPOUND is non-null, this is for a function-transaction-block, and we | |
10179 | should create an extra compound stmt. */ | |
10180 | ||
10181 | tree | |
10182 | begin_transaction_stmt (location_t loc, tree *pcompound, int flags) | |
10183 | { | |
10184 | tree r; | |
10185 | ||
10186 | if (pcompound) | |
10187 | *pcompound = begin_compound_stmt (0); | |
10188 | ||
10189 | r = build_stmt (loc, TRANSACTION_EXPR, NULL_TREE); | |
10190 | ||
10191 | /* Only add the statement to the function if support enabled. */ | |
10192 | if (flag_tm) | |
10193 | add_stmt (r); | |
10194 | else | |
10195 | error_at (loc, ((flags & TM_STMT_ATTR_RELAXED) != 0 | |
10196 | ? G_("%<__transaction_relaxed%> without " | |
10197 | "transactional memory support enabled") | |
10198 | : G_("%<__transaction_atomic%> without " | |
10199 | "transactional memory support enabled"))); | |
10200 | ||
10201 | TRANSACTION_EXPR_BODY (r) = push_stmt_list (); | |
6f2d959b | 10202 | TREE_SIDE_EFFECTS (r) = 1; |
0a35513e AH |
10203 | return r; |
10204 | } | |
10205 | ||
10206 | /* End a __transaction_atomic or __transaction_relaxed statement. | |
10207 | If COMPOUND_STMT is non-null, this is for a function-transaction-block, | |
f0f3286a TR |
10208 | and we should end the compound. If NOEX is non-NULL, we wrap the body in |
10209 | a MUST_NOT_THROW_EXPR with NOEX as condition. */ | |
0a35513e AH |
10210 | |
10211 | void | |
f0f3286a | 10212 | finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex) |
0a35513e AH |
10213 | { |
10214 | TRANSACTION_EXPR_BODY (stmt) = pop_stmt_list (TRANSACTION_EXPR_BODY (stmt)); | |
10215 | TRANSACTION_EXPR_OUTER (stmt) = (flags & TM_STMT_ATTR_OUTER) != 0; | |
10216 | TRANSACTION_EXPR_RELAXED (stmt) = (flags & TM_STMT_ATTR_RELAXED) != 0; | |
10217 | TRANSACTION_EXPR_IS_STMT (stmt) = 1; | |
10218 | ||
f0f3286a TR |
10219 | /* noexcept specifications are not allowed for function transactions. */ |
10220 | gcc_assert (!(noex && compound_stmt)); | |
10221 | if (noex) | |
10222 | { | |
10223 | tree body = build_must_not_throw_expr (TRANSACTION_EXPR_BODY (stmt), | |
10224 | noex); | |
5b5dce39 MP |
10225 | protected_set_expr_location |
10226 | (body, EXPR_LOCATION (TRANSACTION_EXPR_BODY (stmt))); | |
f0f3286a TR |
10227 | TREE_SIDE_EFFECTS (body) = 1; |
10228 | TRANSACTION_EXPR_BODY (stmt) = body; | |
10229 | } | |
10230 | ||
0a35513e AH |
10231 | if (compound_stmt) |
10232 | finish_compound_stmt (compound_stmt); | |
0a35513e AH |
10233 | } |
10234 | ||
f0f3286a TR |
10235 | /* Build a __transaction_atomic or __transaction_relaxed expression. If |
10236 | NOEX is non-NULL, we wrap the body in a MUST_NOT_THROW_EXPR with NOEX as | |
10237 | condition. */ | |
0a35513e AH |
10238 | |
10239 | tree | |
f0f3286a | 10240 | build_transaction_expr (location_t loc, tree expr, int flags, tree noex) |
0a35513e AH |
10241 | { |
10242 | tree ret; | |
f0f3286a TR |
10243 | if (noex) |
10244 | { | |
10245 | expr = build_must_not_throw_expr (expr, noex); | |
5b5dce39 | 10246 | protected_set_expr_location (expr, loc); |
f0f3286a TR |
10247 | TREE_SIDE_EFFECTS (expr) = 1; |
10248 | } | |
0a35513e AH |
10249 | ret = build1 (TRANSACTION_EXPR, TREE_TYPE (expr), expr); |
10250 | if (flags & TM_STMT_ATTR_RELAXED) | |
10251 | TRANSACTION_EXPR_RELAXED (ret) = 1; | |
6f2d959b | 10252 | TREE_SIDE_EFFECTS (ret) = 1; |
0a35513e AH |
10253 | SET_EXPR_LOCATION (ret, loc); |
10254 | return ret; | |
10255 | } | |
10256 | \f | |
54f7877c | 10257 | void |
3a978d72 | 10258 | init_cp_semantics (void) |
54f7877c | 10259 | { |
54f7877c | 10260 | } |
55a3debe | 10261 | \f |
8c0c83fe MP |
10262 | |
10263 | /* If we have a condition in conjunctive normal form (CNF), find the first | |
10264 | failing clause. In other words, given an expression like | |
10265 | ||
10266 | true && true && false && true && false | |
10267 | ||
10268 | return the first 'false'. EXPR is the expression. */ | |
10269 | ||
10270 | static tree | |
10271 | find_failing_clause_r (tree expr) | |
10272 | { | |
10273 | if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR) | |
10274 | { | |
10275 | /* First check the left side... */ | |
10276 | tree e = find_failing_clause_r (TREE_OPERAND (expr, 0)); | |
10277 | if (e == NULL_TREE) | |
10278 | /* ...if we didn't find a false clause, check the right side. */ | |
10279 | e = find_failing_clause_r (TREE_OPERAND (expr, 1)); | |
10280 | return e; | |
10281 | } | |
10282 | tree e = contextual_conv_bool (expr, tf_none); | |
10283 | e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true); | |
10284 | if (integer_zerop (e)) | |
10285 | /* This is the failing clause. */ | |
10286 | return expr; | |
10287 | return NULL_TREE; | |
10288 | } | |
10289 | ||
10290 | /* Wrapper for find_failing_clause_r. */ | |
10291 | ||
10292 | static tree | |
10293 | find_failing_clause (tree expr) | |
10294 | { | |
10295 | if (TREE_CODE (expr) != TRUTH_ANDIF_EXPR) | |
10296 | return NULL_TREE; | |
10297 | return find_failing_clause_r (expr); | |
10298 | } | |
10299 | ||
55a3debe DG |
10300 | /* Build a STATIC_ASSERT for a static assertion with the condition |
10301 | CONDITION and the message text MESSAGE. LOCATION is the location | |
10302 | of the static assertion in the source code. When MEMBER_P, this | |
8c0c83fe MP |
10303 | static assertion is a member of a class. If SHOW_EXPR_P is true, |
10304 | print the condition (because it was instantiation-dependent). */ | |
10305 | ||
43e1e8b5 JM |
10306 | void |
10307 | finish_static_assert (tree condition, tree message, location_t location, | |
8c0c83fe | 10308 | bool member_p, bool show_expr_p) |
55a3debe | 10309 | { |
03943bbd JM |
10310 | tsubst_flags_t complain = tf_warning_or_error; |
10311 | ||
61b6d4cd DS |
10312 | if (message == NULL_TREE |
10313 | || message == error_mark_node | |
10314 | || condition == NULL_TREE | |
10315 | || condition == error_mark_node) | |
10316 | return; | |
10317 | ||
7b3e2d46 DG |
10318 | if (check_for_bare_parameter_packs (condition)) |
10319 | condition = error_mark_node; | |
10320 | ||
8fef0dc6 | 10321 | if (instantiation_dependent_expression_p (condition)) |
55a3debe DG |
10322 | { |
10323 | /* We're in a template; build a STATIC_ASSERT and put it in | |
10324 | the right place. */ | |
10325 | tree assertion; | |
10326 | ||
10327 | assertion = make_node (STATIC_ASSERT); | |
10328 | STATIC_ASSERT_CONDITION (assertion) = condition; | |
10329 | STATIC_ASSERT_MESSAGE (assertion) = message; | |
10330 | STATIC_ASSERT_SOURCE_LOCATION (assertion) = location; | |
10331 | ||
10332 | if (member_p) | |
43e1e8b5 | 10333 | maybe_add_class_template_decl_list (current_class_type, |
55a3debe DG |
10334 | assertion, |
10335 | /*friend_p=*/0); | |
10336 | else | |
10337 | add_stmt (assertion); | |
10338 | ||
10339 | return; | |
10340 | } | |
10341 | ||
861d4af8 AS |
10342 | /* Save the condition in case it was a concept check. */ |
10343 | tree orig_condition = condition; | |
10344 | ||
55a3debe | 10345 | /* Fold the expression and convert it to a boolean value. */ |
8c0c83fe | 10346 | condition = contextual_conv_bool (condition, complain); |
4cd3e7df JJ |
10347 | condition = fold_non_dependent_expr (condition, complain, |
10348 | /*manifestly_const_eval=*/true); | |
55a3debe DG |
10349 | |
10350 | if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition)) | |
10351 | /* Do nothing; the condition is satisfied. */ | |
10352 | ; | |
43e1e8b5 | 10353 | else |
55a3debe | 10354 | { |
8c0c83fe | 10355 | iloc_sentinel ils (location); |
55a3debe | 10356 | |
8c0c83fe | 10357 | if (integer_zerop (condition)) |
e79fc3d4 ESR |
10358 | { |
10359 | int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT | |
10360 | (TREE_TYPE (TREE_TYPE (message)))); | |
10361 | int len = TREE_STRING_LENGTH (message) / sz - 1; | |
8c0c83fe MP |
10362 | |
10363 | /* See if we can find which clause was failing (for logical AND). */ | |
10364 | tree bad = find_failing_clause (orig_condition); | |
10365 | /* If not, or its location is unusable, fall back to the previous | |
10366 | location. */ | |
10367 | location_t cloc = location; | |
10368 | if (cp_expr_location (bad) != UNKNOWN_LOCATION) | |
10369 | cloc = cp_expr_location (bad); | |
10370 | ||
e79fc3d4 ESR |
10371 | /* Report the error. */ |
10372 | if (len == 0) | |
8c0c83fe | 10373 | error_at (cloc, "static assertion failed"); |
e79fc3d4 | 10374 | else |
8c0c83fe MP |
10375 | error_at (cloc, "static assertion failed: %s", |
10376 | TREE_STRING_POINTER (message)); | |
10377 | if (show_expr_p) | |
10378 | inform (cloc, "%qE evaluates to false", | |
10379 | /* Nobody wants to see the artificial (bool) cast. */ | |
10380 | (bad ? tree_strip_nop_conversions (bad) : orig_condition)); | |
861d4af8 | 10381 | |
a7ea3d2c PP |
10382 | /* Actually explain the failure if this is a concept check or a |
10383 | requires-expression. */ | |
10384 | if (concept_check_p (orig_condition) | |
10385 | || TREE_CODE (orig_condition) == REQUIRES_EXPR) | |
861d4af8 | 10386 | diagnose_constraints (location, orig_condition, NULL_TREE); |
e79fc3d4 | 10387 | } |
55a3debe | 10388 | else if (condition && condition != error_mark_node) |
fa2200cb JM |
10389 | { |
10390 | error ("non-constant condition for static assertion"); | |
d8cff23f | 10391 | if (require_rvalue_constant_expression (condition)) |
9299bde0 | 10392 | cxx_constant_value (condition); |
fa2200cb | 10393 | } |
55a3debe DG |
10394 | } |
10395 | } | |
3ad6a8e1 DG |
10396 | \f |
10397 | /* Implements the C++0x decltype keyword. Returns the type of EXPR, | |
10398 | suitable for use as a type-specifier. | |
10399 | ||
10400 | ID_EXPRESSION_OR_MEMBER_ACCESS_P is true when EXPR was parsed as an | |
10401 | id-expression or a class member access, FALSE when it was parsed as | |
10402 | a full expression. */ | |
a77f94e2 | 10403 | |
3ad6a8e1 | 10404 | tree |
5b97c77f JM |
10405 | finish_decltype_type (tree expr, bool id_expression_or_member_access_p, |
10406 | tsubst_flags_t complain) | |
3ad6a8e1 | 10407 | { |
056dd1af | 10408 | tree type = NULL_TREE; |
3ad6a8e1 | 10409 | |
e4fd5b87 DG |
10410 | if (!expr || error_operand_p (expr)) |
10411 | return error_mark_node; | |
10412 | ||
7a547b93 JJ |
10413 | if (TYPE_P (expr) |
10414 | || TREE_CODE (expr) == TYPE_DECL | |
10415 | || (TREE_CODE (expr) == BIT_NOT_EXPR | |
10416 | && TYPE_P (TREE_OPERAND (expr, 0)))) | |
10417 | { | |
5b97c77f | 10418 | if (complain & tf_error) |
a9c697b8 | 10419 | error ("argument to %<decltype%> must be an expression"); |
7a547b93 JJ |
10420 | return error_mark_node; |
10421 | } | |
10422 | ||
f645da0e PP |
10423 | /* decltype is an unevaluated context. */ |
10424 | cp_unevaluated u; | |
10425 | ||
2c905502 JM |
10426 | /* Depending on the resolution of DR 1172, we may later need to distinguish |
10427 | instantiation-dependent but not type-dependent expressions so that, say, | |
10428 | A<decltype(sizeof(T))>::U doesn't require 'typename'. */ | |
463d91c6 | 10429 | if (instantiation_dependent_uneval_expression_p (expr)) |
3ad6a8e1 | 10430 | { |
9e1e64ec | 10431 | type = cxx_make_type (DECLTYPE_TYPE); |
3ad6a8e1 DG |
10432 | DECLTYPE_TYPE_EXPR (type) = expr; |
10433 | DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type) | |
10434 | = id_expression_or_member_access_p; | |
10435 | SET_TYPE_STRUCTURAL_EQUALITY (type); | |
10436 | ||
10437 | return type; | |
10438 | } | |
115232b7 PP |
10439 | else if (processing_template_decl) |
10440 | { | |
115232b7 | 10441 | expr = instantiate_non_dependent_expr_sfinae (expr, complain); |
115232b7 PP |
10442 | if (expr == error_mark_node) |
10443 | return error_mark_node; | |
10444 | } | |
3ad6a8e1 DG |
10445 | |
10446 | /* The type denoted by decltype(e) is defined as follows: */ | |
10447 | ||
46f0d909 | 10448 | expr = resolve_nondeduced_context (expr, complain); |
48326487 | 10449 | |
d3ea4c06 | 10450 | if (invalid_nonstatic_memfn_p (input_location, expr, complain)) |
6c74ff23 JM |
10451 | return error_mark_node; |
10452 | ||
6cdb1428 JM |
10453 | if (type_unknown_p (expr)) |
10454 | { | |
10455 | if (complain & tf_error) | |
a9c697b8 | 10456 | error ("%<decltype%> cannot resolve address of overloaded function"); |
6cdb1428 JM |
10457 | return error_mark_node; |
10458 | } | |
10459 | ||
48326487 JM |
10460 | /* To get the size of a static data member declared as an array of |
10461 | unknown bound, we need to instantiate it. */ | |
5a6ccc94 | 10462 | if (VAR_P (expr) |
48326487 JM |
10463 | && VAR_HAD_UNKNOWN_BOUND (expr) |
10464 | && DECL_TEMPLATE_INSTANTIATION (expr)) | |
10465 | instantiate_decl (expr, /*defer_ok*/true, /*expl_inst_mem*/false); | |
10466 | ||
3ad6a8e1 DG |
10467 | if (id_expression_or_member_access_p) |
10468 | { | |
10469 | /* If e is an id-expression or a class member access (5.2.5 | |
10470 | [expr.ref]), decltype(e) is defined as the type of the entity | |
10471 | named by e. If there is no such entity, or e names a set of | |
10472 | overloaded functions, the program is ill-formed. */ | |
9dc6f476 | 10473 | if (identifier_p (expr)) |
3ad6a8e1 DG |
10474 | expr = lookup_name (expr); |
10475 | ||
4be5c72c JM |
10476 | if (INDIRECT_REF_P (expr) |
10477 | || TREE_CODE (expr) == VIEW_CONVERT_EXPR) | |
3ad6a8e1 DG |
10478 | /* This can happen when the expression is, e.g., "a.b". Just |
10479 | look at the underlying operand. */ | |
10480 | expr = TREE_OPERAND (expr, 0); | |
10481 | ||
10482 | if (TREE_CODE (expr) == OFFSET_REF | |
cf3c30d3 JM |
10483 | || TREE_CODE (expr) == MEMBER_REF |
10484 | || TREE_CODE (expr) == SCOPE_REF) | |
3ad6a8e1 DG |
10485 | /* We're only interested in the field itself. If it is a |
10486 | BASELINK, we will need to see through it in the next | |
10487 | step. */ | |
10488 | expr = TREE_OPERAND (expr, 1); | |
10489 | ||
c5ce25ce | 10490 | if (BASELINK_P (expr)) |
6cdb1428 | 10491 | /* See through BASELINK nodes to the underlying function. */ |
3ad6a8e1 DG |
10492 | expr = BASELINK_FUNCTIONS (expr); |
10493 | ||
94460802 JM |
10494 | /* decltype of a decomposition name drops references in the tuple case |
10495 | (unlike decltype of a normal variable) and keeps cv-qualifiers from | |
10496 | the containing object in the other cases (unlike decltype of a member | |
10497 | access expression). */ | |
10498 | if (DECL_DECOMPOSITION_P (expr)) | |
10499 | { | |
10500 | if (DECL_HAS_VALUE_EXPR_P (expr)) | |
10501 | /* Expr is an array or struct subobject proxy, handle | |
10502 | bit-fields properly. */ | |
10503 | return unlowered_expr_type (expr); | |
10504 | else | |
10505 | /* Expr is a reference variable for the tuple case. */ | |
fc72d1ed | 10506 | return lookup_decomp_type (expr); |
94460802 JM |
10507 | } |
10508 | ||
3ad6a8e1 DG |
10509 | switch (TREE_CODE (expr)) |
10510 | { | |
10511 | case FIELD_DECL: | |
e76d7cc7 | 10512 | if (DECL_BIT_FIELD_TYPE (expr)) |
3ad6a8e1 DG |
10513 | { |
10514 | type = DECL_BIT_FIELD_TYPE (expr); | |
10515 | break; | |
10516 | } | |
10517 | /* Fall through for fields that aren't bitfields. */ | |
81fea426 | 10518 | gcc_fallthrough (); |
3ad6a8e1 DG |
10519 | |
10520 | case FUNCTION_DECL: | |
10521 | case VAR_DECL: | |
10522 | case CONST_DECL: | |
10523 | case PARM_DECL: | |
10524 | case RESULT_DECL: | |
088d4f95 | 10525 | case TEMPLATE_PARM_INDEX: |
03a904b5 | 10526 | expr = mark_type_use (expr); |
3ad6a8e1 DG |
10527 | type = TREE_TYPE (expr); |
10528 | break; | |
10529 | ||
10530 | case ERROR_MARK: | |
10531 | type = error_mark_node; | |
10532 | break; | |
10533 | ||
10534 | case COMPONENT_REF: | |
4882d82a | 10535 | case COMPOUND_EXPR: |
03a904b5 | 10536 | mark_type_use (expr); |
3ad6a8e1 DG |
10537 | type = is_bitfield_expr_with_lowered_type (expr); |
10538 | if (!type) | |
10539 | type = TREE_TYPE (TREE_OPERAND (expr, 1)); | |
10540 | break; | |
10541 | ||
10542 | case BIT_FIELD_REF: | |
10543 | gcc_unreachable (); | |
10544 | ||
10545 | case INTEGER_CST: | |
8733916b | 10546 | case PTRMEM_CST: |
3ad6a8e1 | 10547 | /* We can get here when the id-expression refers to an |
8733916b | 10548 | enumerator or non-type template parameter. */ |
3ad6a8e1 DG |
10549 | type = TREE_TYPE (expr); |
10550 | break; | |
10551 | ||
10552 | default: | |
57c16a5e PC |
10553 | /* Handle instantiated template non-type arguments. */ |
10554 | type = TREE_TYPE (expr); | |
10555 | break; | |
3ad6a8e1 DG |
10556 | } |
10557 | } | |
10558 | else | |
10559 | { | |
c1e41527 JM |
10560 | /* Within a lambda-expression: |
10561 | ||
10562 | Every occurrence of decltype((x)) where x is a possibly | |
10563 | parenthesized id-expression that names an entity of | |
10564 | automatic storage duration is treated as if x were | |
10565 | transformed into an access to a corresponding data member | |
10566 | of the closure type that would have been declared if x | |
10567 | were a use of the denoted entity. */ | |
10568 | if (outer_automatic_var_p (expr) | |
10569 | && current_function_decl | |
10570 | && LAMBDA_FUNCTION_P (current_function_decl)) | |
10571 | type = capture_decltype (expr); | |
10572 | else if (error_operand_p (expr)) | |
10573 | type = error_mark_node; | |
10574 | else if (expr == current_class_ptr) | |
10575 | /* If the expression is just "this", we want the | |
10576 | cv-unqualified pointer for the "this" type. */ | |
10577 | type = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); | |
10578 | else | |
10579 | { | |
10580 | /* Otherwise, where T is the type of e, if e is an lvalue, | |
10581 | decltype(e) is defined as T&; if an xvalue, T&&; otherwise, T. */ | |
10582 | cp_lvalue_kind clk = lvalue_kind (expr); | |
10583 | type = unlowered_expr_type (expr); | |
9f613f06 | 10584 | gcc_assert (!TYPE_REF_P (type)); |
7cea661c MG |
10585 | |
10586 | /* For vector types, pick a non-opaque variant. */ | |
b55b02ea | 10587 | if (VECTOR_TYPE_P (type)) |
7cea661c MG |
10588 | type = strip_typedefs (type); |
10589 | ||
c1e41527 JM |
10590 | if (clk != clk_none && !(clk & clk_class)) |
10591 | type = cp_build_reference_type (type, (clk & clk_rvalueref)); | |
10592 | } | |
3ad6a8e1 DG |
10593 | } |
10594 | ||
3ad6a8e1 DG |
10595 | return type; |
10596 | } | |
cf22909c | 10597 | |
43e1e8b5 | 10598 | /* Called from trait_expr_value to evaluate either __has_nothrow_assign or |
5337720c NS |
10599 | __has_nothrow_copy, depending on assign_p. Returns true iff all |
10600 | the copy {ctor,assign} fns are nothrow. */ | |
cb68ec50 PC |
10601 | |
10602 | static bool | |
b29441ec | 10603 | classtype_has_nothrow_assign_or_copy_p (tree type, bool assign_p) |
cb68ec50 | 10604 | { |
5337720c | 10605 | tree fns = NULL_TREE; |
cb68ec50 | 10606 | |
527b7b19 | 10607 | if (assign_p || TYPE_HAS_COPY_CTOR (type)) |
137073d3 | 10608 | fns = get_class_binding (type, assign_p ? assign_op_identifier |
527b7b19 | 10609 | : ctor_identifier); |
cb68ec50 | 10610 | |
5337720c | 10611 | bool saw_copy = false; |
3f267553 | 10612 | for (ovl_iterator iter (fns); iter; ++iter) |
279086c3 | 10613 | { |
3f267553 | 10614 | tree fn = *iter; |
5337720c NS |
10615 | |
10616 | if (copy_fn_p (fn) > 0) | |
279086c3 | 10617 | { |
5337720c | 10618 | saw_copy = true; |
8d2318ff PC |
10619 | if (!maybe_instantiate_noexcept (fn) |
10620 | || !TYPE_NOTHROW_P (TREE_TYPE (fn))) | |
5337720c | 10621 | return false; |
279086c3 | 10622 | } |
279086c3 | 10623 | } |
b29441ec | 10624 | |
5337720c | 10625 | return saw_copy; |
cb68ec50 PC |
10626 | } |
10627 | ||
6cd005a2 JJ |
10628 | /* Return true if DERIVED is pointer interconvertible base of BASE. */ |
10629 | ||
10630 | static bool | |
10631 | pointer_interconvertible_base_of_p (tree base, tree derived) | |
10632 | { | |
10633 | if (base == error_mark_node || derived == error_mark_node) | |
10634 | return false; | |
10635 | base = TYPE_MAIN_VARIANT (base); | |
10636 | derived = TYPE_MAIN_VARIANT (derived); | |
10637 | if (!NON_UNION_CLASS_TYPE_P (base) | |
10638 | || !NON_UNION_CLASS_TYPE_P (derived)) | |
10639 | return false; | |
10640 | ||
10641 | if (same_type_p (base, derived)) | |
10642 | return true; | |
10643 | ||
10644 | if (!std_layout_type_p (derived)) | |
10645 | return false; | |
10646 | ||
10647 | return uniquely_derived_from_p (base, derived); | |
10648 | } | |
10649 | ||
10650 | /* Helper function for fold_builtin_is_pointer_inverconvertible_with_class, | |
10651 | return true if MEMBERTYPE is the type of the first non-static data member | |
10652 | of TYPE or for unions of any members. */ | |
10653 | static bool | |
10654 | first_nonstatic_data_member_p (tree type, tree membertype) | |
10655 | { | |
10656 | for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) | |
10657 | { | |
10658 | if (TREE_CODE (field) != FIELD_DECL) | |
10659 | continue; | |
10660 | if (DECL_FIELD_IS_BASE (field) && is_empty_field (field)) | |
10661 | continue; | |
10662 | if (DECL_FIELD_IS_BASE (field)) | |
10663 | return first_nonstatic_data_member_p (TREE_TYPE (field), membertype); | |
10664 | if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) | |
10665 | { | |
10666 | if ((TREE_CODE (TREE_TYPE (field)) == UNION_TYPE | |
10667 | || std_layout_type_p (TREE_TYPE (field))) | |
10668 | && first_nonstatic_data_member_p (TREE_TYPE (field), membertype)) | |
10669 | return true; | |
10670 | } | |
10671 | else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field), | |
10672 | membertype)) | |
10673 | return true; | |
10674 | if (TREE_CODE (type) != UNION_TYPE) | |
10675 | return false; | |
10676 | } | |
10677 | return false; | |
10678 | } | |
10679 | ||
10680 | /* Fold __builtin_is_pointer_interconvertible_with_class call. */ | |
10681 | ||
10682 | tree | |
10683 | fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs, | |
10684 | tree *args) | |
10685 | { | |
10686 | /* Unless users call the builtin directly, the following 3 checks should be | |
10687 | ensured from std::is_pointer_interconvertible_with_class function | |
10688 | template. */ | |
10689 | if (nargs != 1) | |
10690 | { | |
10691 | error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> " | |
10692 | "needs a single argument"); | |
10693 | return boolean_false_node; | |
10694 | } | |
10695 | tree arg = args[0]; | |
10696 | if (error_operand_p (arg)) | |
10697 | return boolean_false_node; | |
10698 | if (!TYPE_PTRMEM_P (TREE_TYPE (arg))) | |
10699 | { | |
10700 | error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> " | |
10701 | "argument is not pointer to member"); | |
10702 | return boolean_false_node; | |
10703 | } | |
10704 | ||
10705 | if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg))) | |
10706 | return boolean_false_node; | |
10707 | ||
10708 | tree membertype = TREE_TYPE (TREE_TYPE (arg)); | |
10709 | tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg)); | |
10710 | if (!complete_type_or_else (basetype, NULL_TREE)) | |
10711 | return boolean_false_node; | |
10712 | ||
10713 | if (TREE_CODE (basetype) != UNION_TYPE | |
10714 | && !std_layout_type_p (basetype)) | |
10715 | return boolean_false_node; | |
10716 | ||
10717 | if (!first_nonstatic_data_member_p (basetype, membertype)) | |
10718 | return boolean_false_node; | |
10719 | ||
10720 | if (TREE_CODE (arg) == PTRMEM_CST) | |
10721 | arg = cplus_expand_constant (arg); | |
10722 | ||
10723 | if (integer_nonzerop (arg)) | |
10724 | return boolean_false_node; | |
10725 | if (integer_zerop (arg)) | |
10726 | return boolean_true_node; | |
10727 | ||
10728 | return fold_build2 (EQ_EXPR, boolean_type_node, arg, | |
10729 | build_zero_cst (TREE_TYPE (arg))); | |
10730 | } | |
10731 | ||
32c3a753 JJ |
10732 | /* Helper function for is_corresponding_member_aggr. Return true if |
10733 | MEMBERTYPE pointer-to-data-member ARG can be found in anonymous | |
10734 | union or structure BASETYPE. */ | |
10735 | ||
10736 | static bool | |
10737 | is_corresponding_member_union (tree basetype, tree membertype, tree arg) | |
10738 | { | |
10739 | for (tree field = TYPE_FIELDS (basetype); field; field = DECL_CHAIN (field)) | |
10740 | if (TREE_CODE (field) != FIELD_DECL || DECL_BIT_FIELD_TYPE (field)) | |
10741 | continue; | |
10742 | else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field), | |
10743 | membertype)) | |
10744 | { | |
10745 | if (TREE_CODE (arg) != INTEGER_CST | |
10746 | || tree_int_cst_equal (arg, byte_position (field))) | |
10747 | return true; | |
10748 | } | |
10749 | else if (ANON_AGGR_TYPE_P (TREE_TYPE (field))) | |
10750 | { | |
10751 | tree narg = arg; | |
10752 | if (TREE_CODE (basetype) != UNION_TYPE | |
10753 | && TREE_CODE (narg) == INTEGER_CST) | |
10754 | narg = size_binop (MINUS_EXPR, arg, byte_position (field)); | |
10755 | if (is_corresponding_member_union (TREE_TYPE (field), | |
10756 | membertype, narg)) | |
10757 | return true; | |
10758 | } | |
10759 | return false; | |
10760 | } | |
10761 | ||
10762 | /* Helper function for fold_builtin_is_corresponding_member call. | |
10763 | Return boolean_false_node if MEMBERTYPE1 BASETYPE1::*ARG1 and | |
10764 | MEMBERTYPE2 BASETYPE2::*ARG2 aren't corresponding members, | |
10765 | boolean_true_node if they are corresponding members, or for | |
10766 | non-constant ARG2 the highest member offset for corresponding | |
10767 | members. */ | |
10768 | ||
10769 | static tree | |
10770 | is_corresponding_member_aggr (location_t loc, tree basetype1, tree membertype1, | |
10771 | tree arg1, tree basetype2, tree membertype2, | |
10772 | tree arg2) | |
10773 | { | |
10774 | tree field1 = TYPE_FIELDS (basetype1); | |
10775 | tree field2 = TYPE_FIELDS (basetype2); | |
10776 | tree ret = boolean_false_node; | |
10777 | while (1) | |
10778 | { | |
10779 | bool r = next_common_initial_seqence (field1, field2); | |
10780 | if (field1 == NULL_TREE || field2 == NULL_TREE) | |
10781 | break; | |
10782 | if (r | |
10783 | && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field1), | |
10784 | membertype1) | |
10785 | && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field2), | |
10786 | membertype2)) | |
10787 | { | |
10788 | tree pos = byte_position (field1); | |
10789 | if (TREE_CODE (arg1) == INTEGER_CST | |
10790 | && tree_int_cst_equal (arg1, pos)) | |
10791 | { | |
10792 | if (TREE_CODE (arg2) == INTEGER_CST) | |
10793 | return boolean_true_node; | |
10794 | return pos; | |
10795 | } | |
10796 | else if (TREE_CODE (arg1) != INTEGER_CST) | |
10797 | ret = pos; | |
10798 | } | |
10799 | else if (ANON_AGGR_TYPE_P (TREE_TYPE (field1)) | |
10800 | && ANON_AGGR_TYPE_P (TREE_TYPE (field2))) | |
10801 | { | |
10802 | if ((!lookup_attribute ("no_unique_address", | |
10803 | DECL_ATTRIBUTES (field1))) | |
10804 | != !lookup_attribute ("no_unique_address", | |
10805 | DECL_ATTRIBUTES (field2))) | |
10806 | break; | |
10807 | if (!tree_int_cst_equal (bit_position (field1), | |
10808 | bit_position (field2))) | |
10809 | break; | |
10810 | bool overlap = true; | |
10811 | tree pos = byte_position (field1); | |
10812 | if (TREE_CODE (arg1) == INTEGER_CST) | |
10813 | { | |
10814 | tree off1 = fold_convert (sizetype, arg1); | |
10815 | tree sz1 = TYPE_SIZE_UNIT (TREE_TYPE (field1)); | |
10816 | if (tree_int_cst_lt (off1, pos) | |
10817 | || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz1), off1)) | |
10818 | overlap = false; | |
10819 | } | |
10820 | if (TREE_CODE (arg2) == INTEGER_CST) | |
10821 | { | |
10822 | tree off2 = fold_convert (sizetype, arg2); | |
10823 | tree sz2 = TYPE_SIZE_UNIT (TREE_TYPE (field2)); | |
10824 | if (tree_int_cst_lt (off2, pos) | |
10825 | || tree_int_cst_le (size_binop (PLUS_EXPR, pos, sz2), off2)) | |
10826 | overlap = false; | |
10827 | } | |
10828 | if (overlap | |
10829 | && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field1)) | |
10830 | && NON_UNION_CLASS_TYPE_P (TREE_TYPE (field2))) | |
10831 | { | |
10832 | tree narg1 = arg1; | |
10833 | if (TREE_CODE (arg1) == INTEGER_CST) | |
10834 | narg1 = size_binop (MINUS_EXPR, | |
10835 | fold_convert (sizetype, arg1), pos); | |
10836 | tree narg2 = arg2; | |
10837 | if (TREE_CODE (arg2) == INTEGER_CST) | |
10838 | narg2 = size_binop (MINUS_EXPR, | |
10839 | fold_convert (sizetype, arg2), pos); | |
10840 | tree t1 = TREE_TYPE (field1); | |
10841 | tree t2 = TREE_TYPE (field2); | |
10842 | tree nret = is_corresponding_member_aggr (loc, t1, membertype1, | |
10843 | narg1, t2, membertype2, | |
10844 | narg2); | |
10845 | if (nret != boolean_false_node) | |
10846 | { | |
10847 | if (nret == boolean_true_node) | |
10848 | return nret; | |
10849 | if (TREE_CODE (arg1) == INTEGER_CST) | |
10850 | return size_binop (PLUS_EXPR, nret, pos); | |
10851 | ret = size_binop (PLUS_EXPR, nret, pos); | |
10852 | } | |
10853 | } | |
10854 | else if (overlap | |
10855 | && TREE_CODE (TREE_TYPE (field1)) == UNION_TYPE | |
10856 | && TREE_CODE (TREE_TYPE (field2)) == UNION_TYPE) | |
10857 | { | |
10858 | tree narg1 = arg1; | |
10859 | if (TREE_CODE (arg1) == INTEGER_CST) | |
10860 | narg1 = size_binop (MINUS_EXPR, | |
10861 | fold_convert (sizetype, arg1), pos); | |
10862 | tree narg2 = arg2; | |
10863 | if (TREE_CODE (arg2) == INTEGER_CST) | |
10864 | narg2 = size_binop (MINUS_EXPR, | |
10865 | fold_convert (sizetype, arg2), pos); | |
10866 | if (is_corresponding_member_union (TREE_TYPE (field1), | |
10867 | membertype1, narg1) | |
10868 | && is_corresponding_member_union (TREE_TYPE (field2), | |
10869 | membertype2, narg2)) | |
10870 | { | |
10871 | sorry_at (loc, "%<__builtin_is_corresponding_member%> " | |
10872 | "not well defined for anonymous unions"); | |
10873 | return boolean_false_node; | |
10874 | } | |
10875 | } | |
10876 | } | |
10877 | if (!r) | |
10878 | break; | |
10879 | field1 = DECL_CHAIN (field1); | |
10880 | field2 = DECL_CHAIN (field2); | |
10881 | } | |
10882 | return ret; | |
10883 | } | |
10884 | ||
10885 | /* Fold __builtin_is_corresponding_member call. */ | |
10886 | ||
10887 | tree | |
10888 | fold_builtin_is_corresponding_member (location_t loc, int nargs, | |
10889 | tree *args) | |
10890 | { | |
10891 | /* Unless users call the builtin directly, the following 3 checks should be | |
10892 | ensured from std::is_corresponding_member function template. */ | |
10893 | if (nargs != 2) | |
10894 | { | |
10895 | error_at (loc, "%<__builtin_is_corresponding_member%> " | |
10896 | "needs two arguments"); | |
10897 | return boolean_false_node; | |
10898 | } | |
10899 | tree arg1 = args[0]; | |
10900 | tree arg2 = args[1]; | |
10901 | if (error_operand_p (arg1) || error_operand_p (arg2)) | |
10902 | return boolean_false_node; | |
10903 | if (!TYPE_PTRMEM_P (TREE_TYPE (arg1)) | |
10904 | || !TYPE_PTRMEM_P (TREE_TYPE (arg2))) | |
10905 | { | |
10906 | error_at (loc, "%<__builtin_is_corresponding_member%> " | |
10907 | "argument is not pointer to member"); | |
10908 | return boolean_false_node; | |
10909 | } | |
10910 | ||
10911 | if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg1)) | |
10912 | || !TYPE_PTRDATAMEM_P (TREE_TYPE (arg2))) | |
10913 | return boolean_false_node; | |
10914 | ||
10915 | tree membertype1 = TREE_TYPE (TREE_TYPE (arg1)); | |
10916 | tree basetype1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg1)); | |
10917 | if (!complete_type_or_else (basetype1, NULL_TREE)) | |
10918 | return boolean_false_node; | |
10919 | ||
10920 | tree membertype2 = TREE_TYPE (TREE_TYPE (arg2)); | |
10921 | tree basetype2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg2)); | |
10922 | if (!complete_type_or_else (basetype2, NULL_TREE)) | |
10923 | return boolean_false_node; | |
10924 | ||
10925 | if (!NON_UNION_CLASS_TYPE_P (basetype1) | |
10926 | || !NON_UNION_CLASS_TYPE_P (basetype2) | |
10927 | || !std_layout_type_p (basetype1) | |
10928 | || !std_layout_type_p (basetype2)) | |
10929 | return boolean_false_node; | |
10930 | ||
10931 | /* If the member types aren't layout compatible, then they | |
10932 | can't be corresponding members. */ | |
10933 | if (!layout_compatible_type_p (membertype1, membertype2)) | |
10934 | return boolean_false_node; | |
10935 | ||
10936 | if (TREE_CODE (arg1) == PTRMEM_CST) | |
10937 | arg1 = cplus_expand_constant (arg1); | |
10938 | if (TREE_CODE (arg2) == PTRMEM_CST) | |
10939 | arg2 = cplus_expand_constant (arg2); | |
10940 | ||
10941 | if (null_member_pointer_value_p (arg1) | |
10942 | || null_member_pointer_value_p (arg2)) | |
10943 | return boolean_false_node; | |
10944 | ||
10945 | if (TREE_CODE (arg1) == INTEGER_CST | |
10946 | && TREE_CODE (arg2) == INTEGER_CST | |
10947 | && !tree_int_cst_equal (arg1, arg2)) | |
10948 | return boolean_false_node; | |
10949 | ||
10950 | if (TREE_CODE (arg2) == INTEGER_CST | |
10951 | && TREE_CODE (arg1) != INTEGER_CST) | |
10952 | { | |
10953 | std::swap (arg1, arg2); | |
10954 | std::swap (membertype1, membertype2); | |
10955 | std::swap (basetype1, basetype2); | |
10956 | } | |
10957 | ||
10958 | tree ret = is_corresponding_member_aggr (loc, basetype1, membertype1, arg1, | |
10959 | basetype2, membertype2, arg2); | |
10960 | if (TREE_TYPE (ret) == boolean_type_node) | |
10961 | return ret; | |
10962 | /* If both arg1 and arg2 are INTEGER_CSTs, is_corresponding_member_aggr | |
10963 | already returns boolean_{true,false}_node whether those particular | |
10964 | members are corresponding members or not. Otherwise, if only | |
10965 | one of them is INTEGER_CST (canonicalized to first being INTEGER_CST | |
10966 | above), it returns boolean_false_node if it is certainly not a | |
10967 | corresponding member and otherwise we need to do a runtime check that | |
10968 | those two OFFSET_TYPE offsets are equal. | |
10969 | If neither of the operands is INTEGER_CST, is_corresponding_member_aggr | |
10970 | returns the largest offset at which the members would be corresponding | |
10971 | members, so perform arg1 <= ret && arg1 == arg2 runtime check. */ | |
10972 | gcc_assert (TREE_CODE (arg2) != INTEGER_CST); | |
10973 | if (TREE_CODE (arg1) == INTEGER_CST) | |
10974 | return fold_build2 (EQ_EXPR, boolean_type_node, arg1, | |
10975 | fold_convert (TREE_TYPE (arg1), arg2)); | |
10976 | ret = fold_build2 (LE_EXPR, boolean_type_node, | |
10977 | fold_convert (pointer_sized_int_node, arg1), | |
10978 | fold_convert (pointer_sized_int_node, ret)); | |
10979 | return fold_build2 (TRUTH_AND_EXPR, boolean_type_node, ret, | |
10980 | fold_build2 (EQ_EXPR, boolean_type_node, arg1, | |
10981 | fold_convert (TREE_TYPE (arg1), arg2))); | |
10982 | } | |
10983 | ||
cb68ec50 PC |
10984 | /* Actually evaluates the trait. */ |
10985 | ||
10986 | static bool | |
10987 | trait_expr_value (cp_trait_kind kind, tree type1, tree type2) | |
10988 | { | |
10989 | enum tree_code type_code1; | |
10990 | tree t; | |
10991 | ||
10992 | type_code1 = TREE_CODE (type1); | |
10993 | ||
10994 | switch (kind) | |
10995 | { | |
10996 | case CPTK_HAS_NOTHROW_ASSIGN: | |
c32097d8 | 10997 | type1 = strip_array_types (type1); |
b29441ec PC |
10998 | return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE |
10999 | && (trait_expr_value (CPTK_HAS_TRIVIAL_ASSIGN, type1, type2) | |
11000 | || (CLASS_TYPE_P (type1) | |
11001 | && classtype_has_nothrow_assign_or_copy_p (type1, | |
11002 | true)))); | |
cb68ec50 PC |
11003 | |
11004 | case CPTK_HAS_TRIVIAL_ASSIGN: | |
c32097d8 JM |
11005 | /* ??? The standard seems to be missing the "or array of such a class |
11006 | type" wording for this trait. */ | |
11007 | type1 = strip_array_types (type1); | |
cb68ec50 | 11008 | return (!CP_TYPE_CONST_P (type1) && type_code1 != REFERENCE_TYPE |
c32097d8 | 11009 | && (trivial_type_p (type1) |
cb68ec50 | 11010 | || (CLASS_TYPE_P (type1) |
066ec0a4 | 11011 | && TYPE_HAS_TRIVIAL_COPY_ASSIGN (type1)))); |
cb68ec50 PC |
11012 | |
11013 | case CPTK_HAS_NOTHROW_CONSTRUCTOR: | |
11014 | type1 = strip_array_types (type1); | |
43e1e8b5 | 11015 | return (trait_expr_value (CPTK_HAS_TRIVIAL_CONSTRUCTOR, type1, type2) |
cb68ec50 | 11016 | || (CLASS_TYPE_P (type1) |
ac177431 | 11017 | && (t = locate_ctor (type1)) |
8d2318ff PC |
11018 | && maybe_instantiate_noexcept (t) |
11019 | && TYPE_NOTHROW_P (TREE_TYPE (t)))); | |
cb68ec50 PC |
11020 | |
11021 | case CPTK_HAS_TRIVIAL_CONSTRUCTOR: | |
11022 | type1 = strip_array_types (type1); | |
c32097d8 | 11023 | return (trivial_type_p (type1) |
cb68ec50 PC |
11024 | || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DFLT (type1))); |
11025 | ||
11026 | case CPTK_HAS_NOTHROW_COPY: | |
c32097d8 | 11027 | type1 = strip_array_types (type1); |
cb68ec50 PC |
11028 | return (trait_expr_value (CPTK_HAS_TRIVIAL_COPY, type1, type2) |
11029 | || (CLASS_TYPE_P (type1) | |
b29441ec | 11030 | && classtype_has_nothrow_assign_or_copy_p (type1, false))); |
cb68ec50 PC |
11031 | |
11032 | case CPTK_HAS_TRIVIAL_COPY: | |
c32097d8 JM |
11033 | /* ??? The standard seems to be missing the "or array of such a class |
11034 | type" wording for this trait. */ | |
11035 | type1 = strip_array_types (type1); | |
11036 | return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE | |
066ec0a4 | 11037 | || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_COPY_CTOR (type1))); |
cb68ec50 PC |
11038 | |
11039 | case CPTK_HAS_TRIVIAL_DESTRUCTOR: | |
11040 | type1 = strip_array_types (type1); | |
c32097d8 | 11041 | return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE |
cb68ec50 PC |
11042 | || (CLASS_TYPE_P (type1) |
11043 | && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1))); | |
11044 | ||
11045 | case CPTK_HAS_VIRTUAL_DESTRUCTOR: | |
46408846 | 11046 | return type_has_virtual_destructor (type1); |
cb68ec50 | 11047 | |
342cfb3e JJ |
11048 | case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: |
11049 | return type_has_unique_obj_representations (type1); | |
11050 | ||
cb68ec50 | 11051 | case CPTK_IS_ABSTRACT: |
af88f557 JJ |
11052 | return ABSTRACT_CLASS_TYPE_P (type1); |
11053 | ||
11054 | case CPTK_IS_AGGREGATE: | |
11055 | return CP_AGGREGATE_TYPE_P (type1); | |
cb68ec50 PC |
11056 | |
11057 | case CPTK_IS_BASE_OF: | |
11058 | return (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) | |
1f872df7 PC |
11059 | && (same_type_ignoring_top_level_qualifiers_p (type1, type2) |
11060 | || DERIVED_FROM_P (type1, type2))); | |
cb68ec50 PC |
11061 | |
11062 | case CPTK_IS_CLASS: | |
af88f557 | 11063 | return NON_UNION_CLASS_TYPE_P (type1); |
cb68ec50 | 11064 | |
cb68ec50 | 11065 | case CPTK_IS_EMPTY: |
af88f557 | 11066 | return NON_UNION_CLASS_TYPE_P (type1) && CLASSTYPE_EMPTY_P (type1); |
cb68ec50 PC |
11067 | |
11068 | case CPTK_IS_ENUM: | |
af88f557 | 11069 | return type_code1 == ENUMERAL_TYPE; |
cb68ec50 | 11070 | |
b3908fcc | 11071 | case CPTK_IS_FINAL: |
af88f557 | 11072 | return CLASS_TYPE_P (type1) && CLASSTYPE_FINAL (type1); |
b3908fcc | 11073 | |
32c3a753 JJ |
11074 | case CPTK_IS_LAYOUT_COMPATIBLE: |
11075 | return layout_compatible_type_p (type1, type2); | |
11076 | ||
3c0d13bf | 11077 | case CPTK_IS_LITERAL_TYPE: |
af88f557 | 11078 | return literal_type_p (type1); |
3c0d13bf | 11079 | |
6cd005a2 JJ |
11080 | case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF: |
11081 | return pointer_interconvertible_base_of_p (type1, type2); | |
11082 | ||
cb68ec50 | 11083 | case CPTK_IS_POD: |
af88f557 | 11084 | return pod_type_p (type1); |
cb68ec50 PC |
11085 | |
11086 | case CPTK_IS_POLYMORPHIC: | |
af88f557 | 11087 | return CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1); |
cb68ec50 | 11088 | |
971e17ff AS |
11089 | case CPTK_IS_SAME_AS: |
11090 | return same_type_p (type1, type2); | |
11091 | ||
c32097d8 | 11092 | case CPTK_IS_STD_LAYOUT: |
af88f557 | 11093 | return std_layout_type_p (type1); |
c32097d8 JM |
11094 | |
11095 | case CPTK_IS_TRIVIAL: | |
af88f557 | 11096 | return trivial_type_p (type1); |
c32097d8 | 11097 | |
dd5d5481 JM |
11098 | case CPTK_IS_TRIVIALLY_ASSIGNABLE: |
11099 | return is_trivially_xible (MODIFY_EXPR, type1, type2); | |
11100 | ||
11101 | case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE: | |
11102 | return is_trivially_xible (INIT_EXPR, type1, type2); | |
11103 | ||
b752325e | 11104 | case CPTK_IS_TRIVIALLY_COPYABLE: |
af88f557 | 11105 | return trivially_copyable_p (type1); |
b752325e | 11106 | |
cb68ec50 | 11107 | case CPTK_IS_UNION: |
af88f557 | 11108 | return type_code1 == UNION_TYPE; |
cb68ec50 | 11109 | |
b42cc3ca VV |
11110 | case CPTK_IS_ASSIGNABLE: |
11111 | return is_xible (MODIFY_EXPR, type1, type2); | |
11112 | ||
11113 | case CPTK_IS_CONSTRUCTIBLE: | |
11114 | return is_xible (INIT_EXPR, type1, type2); | |
11115 | ||
9e2256dc VV |
11116 | case CPTK_IS_NOTHROW_ASSIGNABLE: |
11117 | return is_nothrow_xible (MODIFY_EXPR, type1, type2); | |
11118 | ||
11119 | case CPTK_IS_NOTHROW_CONSTRUCTIBLE: | |
11120 | return is_nothrow_xible (INIT_EXPR, type1, type2); | |
11121 | ||
cb68ec50 PC |
11122 | default: |
11123 | gcc_unreachable (); | |
11124 | return false; | |
11125 | } | |
11126 | } | |
11127 | ||
4f75413f | 11128 | /* If TYPE is an array of unknown bound, or (possibly cv-qualified) |
dd5d5481 | 11129 | void, or a complete type, returns true, otherwise false. */ |
ff284b4b | 11130 | |
dd5d5481 | 11131 | static bool |
ff284b4b PC |
11132 | check_trait_type (tree type) |
11133 | { | |
dd5d5481 JM |
11134 | if (type == NULL_TREE) |
11135 | return true; | |
11136 | ||
11137 | if (TREE_CODE (type) == TREE_LIST) | |
11138 | return (check_trait_type (TREE_VALUE (type)) | |
11139 | && check_trait_type (TREE_CHAIN (type))); | |
11140 | ||
f94ae987 JM |
11141 | if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type) |
11142 | && COMPLETE_TYPE_P (TREE_TYPE (type))) | |
dd5d5481 | 11143 | return true; |
ff284b4b PC |
11144 | |
11145 | if (VOID_TYPE_P (type)) | |
dd5d5481 | 11146 | return true; |
ff284b4b | 11147 | |
dd5d5481 | 11148 | return !!complete_type_or_else (strip_array_types (type), NULL_TREE); |
ff284b4b PC |
11149 | } |
11150 | ||
cb68ec50 PC |
11151 | /* Process a trait expression. */ |
11152 | ||
11153 | tree | |
ad527d80 | 11154 | finish_trait_expr (location_t loc, cp_trait_kind kind, tree type1, tree type2) |
cb68ec50 | 11155 | { |
cb68ec50 | 11156 | if (type1 == error_mark_node |
dd5d5481 | 11157 | || type2 == error_mark_node) |
cb68ec50 PC |
11158 | return error_mark_node; |
11159 | ||
11160 | if (processing_template_decl) | |
11161 | { | |
11162 | tree trait_expr = make_node (TRAIT_EXPR); | |
11163 | TREE_TYPE (trait_expr) = boolean_type_node; | |
11164 | TRAIT_EXPR_TYPE1 (trait_expr) = type1; | |
11165 | TRAIT_EXPR_TYPE2 (trait_expr) = type2; | |
11166 | TRAIT_EXPR_KIND (trait_expr) = kind; | |
ad527d80 | 11167 | TRAIT_EXPR_LOCATION (trait_expr) = loc; |
cb68ec50 PC |
11168 | return trait_expr; |
11169 | } | |
11170 | ||
ff284b4b | 11171 | switch (kind) |
cb68ec50 | 11172 | { |
ff284b4b PC |
11173 | case CPTK_HAS_NOTHROW_ASSIGN: |
11174 | case CPTK_HAS_TRIVIAL_ASSIGN: | |
11175 | case CPTK_HAS_NOTHROW_CONSTRUCTOR: | |
11176 | case CPTK_HAS_TRIVIAL_CONSTRUCTOR: | |
11177 | case CPTK_HAS_NOTHROW_COPY: | |
11178 | case CPTK_HAS_TRIVIAL_COPY: | |
11179 | case CPTK_HAS_TRIVIAL_DESTRUCTOR: | |
342cfb3e | 11180 | case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS: |
ff284b4b PC |
11181 | case CPTK_HAS_VIRTUAL_DESTRUCTOR: |
11182 | case CPTK_IS_ABSTRACT: | |
af88f557 | 11183 | case CPTK_IS_AGGREGATE: |
ff284b4b | 11184 | case CPTK_IS_EMPTY: |
b3908fcc | 11185 | case CPTK_IS_FINAL: |
3c0d13bf | 11186 | case CPTK_IS_LITERAL_TYPE: |
ff284b4b PC |
11187 | case CPTK_IS_POD: |
11188 | case CPTK_IS_POLYMORPHIC: | |
c32097d8 JM |
11189 | case CPTK_IS_STD_LAYOUT: |
11190 | case CPTK_IS_TRIVIAL: | |
b752325e | 11191 | case CPTK_IS_TRIVIALLY_COPYABLE: |
ff284b4b | 11192 | if (!check_trait_type (type1)) |
4f75413f | 11193 | return error_mark_node; |
ff284b4b | 11194 | break; |
dd5d5481 | 11195 | |
b42cc3ca VV |
11196 | case CPTK_IS_ASSIGNABLE: |
11197 | case CPTK_IS_CONSTRUCTIBLE: | |
11198 | break; | |
11199 | ||
dd5d5481 JM |
11200 | case CPTK_IS_TRIVIALLY_ASSIGNABLE: |
11201 | case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE: | |
9e2256dc VV |
11202 | case CPTK_IS_NOTHROW_ASSIGNABLE: |
11203 | case CPTK_IS_NOTHROW_CONSTRUCTIBLE: | |
dd5d5481 JM |
11204 | if (!check_trait_type (type1) |
11205 | || !check_trait_type (type2)) | |
11206 | return error_mark_node; | |
11207 | break; | |
ff284b4b PC |
11208 | |
11209 | case CPTK_IS_BASE_OF: | |
6cd005a2 | 11210 | case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF: |
ff284b4b PC |
11211 | if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) |
11212 | && !same_type_ignoring_top_level_qualifiers_p (type1, type2) | |
4f75413f PC |
11213 | && !complete_type_or_else (type2, NULL_TREE)) |
11214 | /* We already issued an error. */ | |
11215 | return error_mark_node; | |
ff284b4b PC |
11216 | break; |
11217 | ||
11218 | case CPTK_IS_CLASS: | |
11219 | case CPTK_IS_ENUM: | |
11220 | case CPTK_IS_UNION: | |
971e17ff | 11221 | case CPTK_IS_SAME_AS: |
ff284b4b | 11222 | break; |
971e17ff | 11223 | |
32c3a753 JJ |
11224 | case CPTK_IS_LAYOUT_COMPATIBLE: |
11225 | if (!array_of_unknown_bound_p (type1) | |
11226 | && TREE_CODE (type1) != VOID_TYPE | |
11227 | && !complete_type_or_else (type1, NULL_TREE)) | |
11228 | /* We already issued an error. */ | |
11229 | return error_mark_node; | |
11230 | if (!array_of_unknown_bound_p (type2) | |
11231 | && TREE_CODE (type2) != VOID_TYPE | |
11232 | && !complete_type_or_else (type2, NULL_TREE)) | |
11233 | /* We already issued an error. */ | |
11234 | return error_mark_node; | |
11235 | break; | |
11236 | ||
ff284b4b PC |
11237 | default: |
11238 | gcc_unreachable (); | |
cb68ec50 PC |
11239 | } |
11240 | ||
6cd005a2 JJ |
11241 | tree val = (trait_expr_value (kind, type1, type2) |
11242 | ? boolean_true_node : boolean_false_node); | |
11243 | return maybe_wrap_with_location (val, loc); | |
cb68ec50 PC |
11244 | } |
11245 | ||
6ec637a4 JJ |
11246 | /* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64, |
11247 | which is ignored for C++. */ | |
11248 | ||
11249 | void | |
11250 | set_float_const_decimal64 (void) | |
11251 | { | |
11252 | } | |
11253 | ||
11254 | void | |
11255 | clear_float_const_decimal64 (void) | |
11256 | { | |
11257 | } | |
11258 | ||
11259 | bool | |
11260 | float_const_decimal64_p (void) | |
11261 | { | |
11262 | return 0; | |
11263 | } | |
11264 | ||
3b49d762 | 11265 | \f |
2d76680f | 11266 | /* Return true if T designates the implied `this' parameter. */ |
7ecbca9d GDR |
11267 | |
11268 | bool | |
2d76680f | 11269 | is_this_parameter (tree t) |
66e61a34 | 11270 | { |
2d76680f | 11271 | if (!DECL_P (t) || DECL_NAME (t) != this_identifier) |
66e61a34 | 11272 | return false; |
8db29d88 AO |
11273 | gcc_assert (TREE_CODE (t) == PARM_DECL || is_capture_proxy (t) |
11274 | || (cp_binding_oracle && TREE_CODE (t) == VAR_DECL)); | |
fbf833b7 PC |
11275 | return true; |
11276 | } | |
11277 | ||
852497a3 | 11278 | /* Insert the deduced return type for an auto function. */ |
d5f4eddd JM |
11279 | |
11280 | void | |
852497a3 | 11281 | apply_deduced_return_type (tree fco, tree return_type) |
d5f4eddd | 11282 | { |
d5f4eddd JM |
11283 | tree result; |
11284 | ||
d5f4eddd JM |
11285 | if (return_type == error_mark_node) |
11286 | return; | |
11287 | ||
852497a3 | 11288 | if (DECL_CONV_FN_P (fco)) |
08fb1316 | 11289 | DECL_NAME (fco) = make_conv_op_name (return_type); |
852497a3 | 11290 | |
643d4cd6 | 11291 | TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco)); |
d5f4eddd JM |
11292 | |
11293 | result = DECL_RESULT (fco); | |
11294 | if (result == NULL_TREE) | |
11295 | return; | |
852497a3 JM |
11296 | if (TREE_TYPE (result) == return_type) |
11297 | return; | |
d5f4eddd | 11298 | |
6781e2af JM |
11299 | if (!processing_template_decl && !VOID_TYPE_P (return_type) |
11300 | && !complete_type_or_else (return_type, NULL_TREE)) | |
11301 | return; | |
11302 | ||
d5f4eddd JM |
11303 | /* We already have a DECL_RESULT from start_preparsed_function. |
11304 | Now we need to redo the work it and allocate_struct_function | |
11305 | did to reflect the new type. */ | |
9b8662c2 | 11306 | gcc_assert (current_function_decl == fco); |
d5f4eddd JM |
11307 | result = build_decl (input_location, RESULT_DECL, NULL_TREE, |
11308 | TYPE_MAIN_VARIANT (return_type)); | |
11309 | DECL_ARTIFICIAL (result) = 1; | |
11310 | DECL_IGNORED_P (result) = 1; | |
11311 | cp_apply_type_quals_to_decl (cp_type_quals (return_type), | |
11312 | result); | |
11313 | ||
11314 | DECL_RESULT (fco) = result; | |
11315 | ||
852497a3 | 11316 | if (!processing_template_decl) |
d5f4eddd | 11317 | { |
852497a3 | 11318 | bool aggr = aggregate_value_p (result, fco); |
d5f4eddd | 11319 | #ifdef PCC_STATIC_STRUCT_RETURN |
852497a3 | 11320 | cfun->returns_pcc_struct = aggr; |
d5f4eddd | 11321 | #endif |
852497a3 | 11322 | cfun->returns_struct = aggr; |
d5f4eddd | 11323 | } |
d5f4eddd JM |
11324 | } |
11325 | ||
11326 | /* DECL is a local variable or parameter from the surrounding scope of a | |
11327 | lambda-expression. Returns the decltype for a use of the capture field | |
11328 | for DECL even if it hasn't been captured yet. */ | |
11329 | ||
11330 | static tree | |
11331 | capture_decltype (tree decl) | |
11332 | { | |
11333 | tree lam = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (current_function_decl)); | |
f00008b4 NS |
11334 | tree cap = lookup_name (DECL_NAME (decl), LOOK_where::BLOCK, |
11335 | LOOK_want::HIDDEN_LAMBDA); | |
d5f4eddd JM |
11336 | tree type; |
11337 | ||
dfd7fdca DM |
11338 | if (cap && is_capture_proxy (cap)) |
11339 | type = TREE_TYPE (cap); | |
d5f4eddd JM |
11340 | else |
11341 | switch (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam)) | |
11342 | { | |
11343 | case CPLD_NONE: | |
11344 | error ("%qD is not captured", decl); | |
11345 | return error_mark_node; | |
11346 | ||
11347 | case CPLD_COPY: | |
11348 | type = TREE_TYPE (decl); | |
9f613f06 | 11349 | if (TYPE_REF_P (type) |
d5f4eddd JM |
11350 | && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE) |
11351 | type = TREE_TYPE (type); | |
11352 | break; | |
11353 | ||
11354 | case CPLD_REFERENCE: | |
11355 | type = TREE_TYPE (decl); | |
9f613f06 | 11356 | if (!TYPE_REF_P (type)) |
d5f4eddd JM |
11357 | type = build_reference_type (TREE_TYPE (decl)); |
11358 | break; | |
11359 | ||
11360 | default: | |
11361 | gcc_unreachable (); | |
11362 | } | |
11363 | ||
9f613f06 | 11364 | if (!TYPE_REF_P (type)) |
d5f4eddd JM |
11365 | { |
11366 | if (!LAMBDA_EXPR_MUTABLE_P (lam)) | |
a3360e77 | 11367 | type = cp_build_qualified_type (type, (cp_type_quals (type) |
d5f4eddd JM |
11368 | |TYPE_QUAL_CONST)); |
11369 | type = build_reference_type (type); | |
11370 | } | |
11371 | return type; | |
11372 | } | |
11373 | ||
378b307d AS |
11374 | /* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true, |
11375 | this is a right unary fold. Otherwise it is a left unary fold. */ | |
11376 | ||
11377 | static tree | |
11378 | finish_unary_fold_expr (tree expr, int op, tree_code dir) | |
11379 | { | |
204a3763 | 11380 | /* Build a pack expansion (assuming expr has pack type). */ |
378b307d AS |
11381 | if (!uses_parameter_packs (expr)) |
11382 | { | |
11383 | error_at (location_of (expr), "operand of fold expression has no " | |
11384 | "unexpanded parameter packs"); | |
11385 | return error_mark_node; | |
11386 | } | |
11387 | tree pack = make_pack_expansion (expr); | |
11388 | ||
204a3763 | 11389 | /* Build the fold expression. */ |
378b307d | 11390 | tree code = build_int_cstu (integer_type_node, abs (op)); |
f494ac0e | 11391 | tree fold = build_min_nt_loc (UNKNOWN_LOCATION, dir, code, pack); |
378b307d AS |
11392 | FOLD_EXPR_MODIFY_P (fold) = (op < 0); |
11393 | return fold; | |
11394 | } | |
11395 | ||
11396 | tree | |
11397 | finish_left_unary_fold_expr (tree expr, int op) | |
11398 | { | |
11399 | return finish_unary_fold_expr (expr, op, UNARY_LEFT_FOLD_EXPR); | |
11400 | } | |
11401 | ||
11402 | tree | |
11403 | finish_right_unary_fold_expr (tree expr, int op) | |
11404 | { | |
11405 | return finish_unary_fold_expr (expr, op, UNARY_RIGHT_FOLD_EXPR); | |
11406 | } | |
11407 | ||
11408 | /* Build a binary fold expression over EXPR1 and EXPR2. The | |
11409 | associativity of the fold is determined by EXPR1 and EXPR2 (whichever | |
11410 | has an unexpanded parameter pack). */ | |
11411 | ||
11412 | tree | |
11413 | finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir) | |
11414 | { | |
11415 | pack = make_pack_expansion (pack); | |
11416 | tree code = build_int_cstu (integer_type_node, abs (op)); | |
f494ac0e | 11417 | tree fold = build_min_nt_loc (UNKNOWN_LOCATION, dir, code, pack, init); |
378b307d AS |
11418 | FOLD_EXPR_MODIFY_P (fold) = (op < 0); |
11419 | return fold; | |
11420 | } | |
11421 | ||
11422 | tree | |
11423 | finish_binary_fold_expr (tree expr1, tree expr2, int op) | |
11424 | { | |
11425 | // Determine which expr has an unexpanded parameter pack and | |
11426 | // set the pack and initial term. | |
11427 | bool pack1 = uses_parameter_packs (expr1); | |
11428 | bool pack2 = uses_parameter_packs (expr2); | |
11429 | if (pack1 && !pack2) | |
11430 | return finish_binary_fold_expr (expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR); | |
11431 | else if (pack2 && !pack1) | |
11432 | return finish_binary_fold_expr (expr2, expr1, op, BINARY_LEFT_FOLD_EXPR); | |
11433 | else | |
11434 | { | |
11435 | if (pack1) | |
11436 | error ("both arguments in binary fold have unexpanded parameter packs"); | |
11437 | else | |
11438 | error ("no unexpanded parameter packs in binary fold"); | |
11439 | } | |
11440 | return error_mark_node; | |
11441 | } | |
11442 | ||
e16f1cc7 JJ |
11443 | /* Finish __builtin_launder (arg). */ |
11444 | ||
11445 | tree | |
11446 | finish_builtin_launder (location_t loc, tree arg, tsubst_flags_t complain) | |
11447 | { | |
11448 | tree orig_arg = arg; | |
11449 | if (!type_dependent_expression_p (arg)) | |
11450 | arg = decay_conversion (arg, complain); | |
11451 | if (error_operand_p (arg)) | |
11452 | return error_mark_node; | |
11453 | if (!type_dependent_expression_p (arg) | |
9f613f06 | 11454 | && !TYPE_PTR_P (TREE_TYPE (arg))) |
e16f1cc7 JJ |
11455 | { |
11456 | error_at (loc, "non-pointer argument to %<__builtin_launder%>"); | |
11457 | return error_mark_node; | |
11458 | } | |
11459 | if (processing_template_decl) | |
11460 | arg = orig_arg; | |
11461 | return build_call_expr_internal_loc (loc, IFN_LAUNDER, | |
11462 | TREE_TYPE (arg), 1, arg); | |
11463 | } | |
11464 | ||
d8fcab68 JJ |
11465 | /* Finish __builtin_convertvector (arg, type). */ |
11466 | ||
11467 | tree | |
11468 | cp_build_vec_convert (tree arg, location_t loc, tree type, | |
11469 | tsubst_flags_t complain) | |
11470 | { | |
11471 | if (error_operand_p (type)) | |
11472 | return error_mark_node; | |
11473 | if (error_operand_p (arg)) | |
11474 | return error_mark_node; | |
11475 | ||
11476 | tree ret = NULL_TREE; | |
11477 | if (!type_dependent_expression_p (arg) && !dependent_type_p (type)) | |
5a8ad97b JJ |
11478 | ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg), |
11479 | decay_conversion (arg, complain), | |
d8fcab68 JJ |
11480 | loc, type, (complain & tf_error) != 0); |
11481 | ||
11482 | if (!processing_template_decl) | |
11483 | return ret; | |
11484 | ||
11485 | return build_call_expr_internal_loc (loc, IFN_VEC_CONVERT, type, 1, arg); | |
11486 | } | |
11487 | ||
896048cf JJ |
11488 | /* Finish __builtin_bit_cast (type, arg). */ |
11489 | ||
11490 | tree | |
11491 | cp_build_bit_cast (location_t loc, tree type, tree arg, | |
11492 | tsubst_flags_t complain) | |
11493 | { | |
11494 | if (error_operand_p (type)) | |
11495 | return error_mark_node; | |
11496 | if (!dependent_type_p (type)) | |
11497 | { | |
11498 | if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)) | |
11499 | return error_mark_node; | |
11500 | if (TREE_CODE (type) == ARRAY_TYPE) | |
11501 | { | |
11502 | /* std::bit_cast for destination ARRAY_TYPE is not possible, | |
11503 | as functions may not return an array, so don't bother trying | |
11504 | to support this (and then deal with VLAs etc.). */ | |
11505 | error_at (loc, "%<__builtin_bit_cast%> destination type %qT " | |
11506 | "is an array type", type); | |
11507 | return error_mark_node; | |
11508 | } | |
11509 | if (!trivially_copyable_p (type)) | |
11510 | { | |
11511 | error_at (loc, "%<__builtin_bit_cast%> destination type %qT " | |
11512 | "is not trivially copyable", type); | |
11513 | return error_mark_node; | |
11514 | } | |
11515 | } | |
11516 | ||
11517 | if (error_operand_p (arg)) | |
11518 | return error_mark_node; | |
11519 | ||
11520 | if (!type_dependent_expression_p (arg)) | |
11521 | { | |
11522 | if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE) | |
11523 | { | |
11524 | /* Don't perform array-to-pointer conversion. */ | |
11525 | arg = mark_rvalue_use (arg, loc, true); | |
11526 | if (!complete_type_or_maybe_complain (TREE_TYPE (arg), arg, complain)) | |
11527 | return error_mark_node; | |
11528 | } | |
11529 | else | |
11530 | arg = decay_conversion (arg, complain); | |
11531 | ||
11532 | if (error_operand_p (arg)) | |
11533 | return error_mark_node; | |
11534 | ||
11535 | if (!trivially_copyable_p (TREE_TYPE (arg))) | |
11536 | { | |
11537 | error_at (cp_expr_loc_or_loc (arg, loc), | |
11538 | "%<__builtin_bit_cast%> source type %qT " | |
11539 | "is not trivially copyable", TREE_TYPE (arg)); | |
11540 | return error_mark_node; | |
11541 | } | |
11542 | if (!dependent_type_p (type) | |
11543 | && !cp_tree_equal (TYPE_SIZE_UNIT (type), | |
11544 | TYPE_SIZE_UNIT (TREE_TYPE (arg)))) | |
11545 | { | |
11546 | error_at (loc, "%<__builtin_bit_cast%> source size %qE " | |
11547 | "not equal to destination type size %qE", | |
11548 | TYPE_SIZE_UNIT (TREE_TYPE (arg)), | |
11549 | TYPE_SIZE_UNIT (type)); | |
11550 | return error_mark_node; | |
11551 | } | |
11552 | } | |
11553 | ||
11554 | tree ret = build_min (BIT_CAST_EXPR, type, arg); | |
11555 | SET_EXPR_LOCATION (ret, loc); | |
606f2af1 JJ |
11556 | |
11557 | if (!processing_template_decl && CLASS_TYPE_P (type)) | |
11558 | ret = get_target_expr_sfinae (ret, complain); | |
11559 | ||
896048cf JJ |
11560 | return ret; |
11561 | } | |
11562 | ||
cf22909c | 11563 | #include "gt-cp-semantics.h" |