xref: /netbsd-src/external/gpl3/gcc/dist/gcc/cp/cp-gimplify.cc (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
1 /* C++-specific tree lowering bits; see also c-gimplify.cc and gimple.cc.
2 
3    Copyright (C) 2002-2022 Free Software Foundation, Inc.
4    Contributed by Jason Merrill <jason@redhat.com>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "target.h"
26 #include "basic-block.h"
27 #include "cp-tree.h"
28 #include "gimple.h"
29 #include "predict.h"
30 #include "stor-layout.h"
31 #include "tree-iterator.h"
32 #include "gimplify.h"
33 #include "c-family/c-ubsan.h"
34 #include "stringpool.h"
35 #include "attribs.h"
36 #include "asan.h"
37 #include "gcc-rich-location.h"
38 #include "memmodel.h"
39 #include "tm_p.h"
40 #include "output.h"
41 #include "file-prefix-map.h"
42 #include "cgraph.h"
43 #include "omp-general.h"
44 #include "opts.h"
45 
46 struct cp_fold_data
47 {
48   hash_set<tree> pset;
49   bool genericize; // called from cp_fold_function?
50 
cp_fold_datacp_fold_data51   cp_fold_data (bool g): genericize (g) {}
52 };
53 
54 /* Forward declarations.  */
55 
56 static tree cp_genericize_r (tree *, int *, void *);
57 static tree cp_fold_r (tree *, int *, void *);
58 static void cp_genericize_tree (tree*, bool);
59 static tree cp_fold (tree);
60 
61 /* Genericize a TRY_BLOCK.  */
62 
63 static void
genericize_try_block(tree * stmt_p)64 genericize_try_block (tree *stmt_p)
65 {
66   tree body = TRY_STMTS (*stmt_p);
67   tree cleanup = TRY_HANDLERS (*stmt_p);
68 
69   *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
70 }
71 
72 /* Genericize a HANDLER by converting to a CATCH_EXPR.  */
73 
74 static void
genericize_catch_block(tree * stmt_p)75 genericize_catch_block (tree *stmt_p)
76 {
77   tree type = HANDLER_TYPE (*stmt_p);
78   tree body = HANDLER_BODY (*stmt_p);
79 
80   /* FIXME should the caught type go in TREE_TYPE?  */
81   *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
82 }
83 
84 /* A terser interface for building a representation of an exception
85    specification.  */
86 
87 static tree
build_gimple_eh_filter_tree(tree body,tree allowed,tree failure)88 build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
89 {
90   tree t;
91 
92   /* FIXME should the allowed types go in TREE_TYPE?  */
93   t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
94   append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
95 
96   t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
97   append_to_statement_list (body, &TREE_OPERAND (t, 0));
98 
99   return t;
100 }
101 
102 /* Genericize an EH_SPEC_BLOCK by converting it to a
103    TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
104 
105 static void
genericize_eh_spec_block(tree * stmt_p)106 genericize_eh_spec_block (tree *stmt_p)
107 {
108   tree body = EH_SPEC_STMTS (*stmt_p);
109   tree allowed = EH_SPEC_RAISES (*stmt_p);
110   tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
111 
112   *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
113   suppress_warning (*stmt_p);
114   suppress_warning (TREE_OPERAND (*stmt_p, 1));
115 }
116 
117 /* Return the first non-compound statement in STMT.  */
118 
119 tree
first_stmt(tree stmt)120 first_stmt (tree stmt)
121 {
122   switch (TREE_CODE (stmt))
123     {
124     case STATEMENT_LIST:
125       if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
126 	return first_stmt (p->stmt);
127       return void_node;
128 
129     case BIND_EXPR:
130       return first_stmt (BIND_EXPR_BODY (stmt));
131 
132     default:
133       return stmt;
134     }
135 }
136 
137 /* Genericize an IF_STMT by turning it into a COND_EXPR.  */
138 
139 static void
genericize_if_stmt(tree * stmt_p)140 genericize_if_stmt (tree *stmt_p)
141 {
142   tree stmt, cond, then_, else_;
143   location_t locus = EXPR_LOCATION (*stmt_p);
144 
145   stmt = *stmt_p;
146   cond = IF_COND (stmt);
147   then_ = THEN_CLAUSE (stmt);
148   else_ = ELSE_CLAUSE (stmt);
149 
150   if (then_ && else_)
151     {
152       tree ft = first_stmt (then_);
153       tree fe = first_stmt (else_);
154       br_predictor pr;
155       if (TREE_CODE (ft) == PREDICT_EXPR
156 	  && TREE_CODE (fe) == PREDICT_EXPR
157 	  && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
158 	  && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL))
159 	{
160 	  gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus));
161 	  richloc.add_range (EXPR_LOC_OR_LOC (fe, locus));
162 	  warning_at (&richloc, OPT_Wattributes,
163 		      "both branches of %<if%> statement marked as %qs",
164 		      pr == PRED_HOT_LABEL ? "likely" : "unlikely");
165 	}
166     }
167 
168   if (!then_)
169     then_ = build_empty_stmt (locus);
170   if (!else_)
171     else_ = build_empty_stmt (locus);
172 
173   /* consteval if has been verified not to have the then_/else_ blocks
174      entered by gotos/case labels from elsewhere, and as then_ block
175      can contain unfolded immediate function calls, we have to discard
176      the then_ block regardless of whether else_ has side-effects or not.  */
177   if (IF_STMT_CONSTEVAL_P (stmt))
178     {
179       if (block_may_fallthru (then_))
180 	stmt = build3 (COND_EXPR, void_type_node, boolean_false_node,
181 		       void_node, else_);
182       else
183 	stmt = else_;
184     }
185   else if (IF_STMT_CONSTEXPR_P (stmt))
186     stmt = integer_nonzerop (cond) ? then_ : else_;
187   /* ??? This optimization doesn't seem to belong here, but removing it
188      causes -Wreturn-type regressions (e.g. 107310).  */
189   else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
190     stmt = then_;
191   else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
192     stmt = else_;
193   else
194     stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
195   protected_set_expr_location_if_unset (stmt, locus);
196   *stmt_p = stmt;
197 }
198 
199 /* Hook into the middle of gimplifying an OMP_FOR node.  */
200 
201 static enum gimplify_status
cp_gimplify_omp_for(tree * expr_p,gimple_seq * pre_p)202 cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
203 {
204   tree for_stmt = *expr_p;
205   gimple_seq seq = NULL;
206 
207   /* Protect ourselves from recursion.  */
208   if (OMP_FOR_GIMPLIFYING_P (for_stmt))
209     return GS_UNHANDLED;
210   OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
211 
212   gimplify_and_add (for_stmt, &seq);
213   gimple_seq_add_seq (pre_p, seq);
214 
215   OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
216 
217   return GS_ALL_DONE;
218 }
219 
220 /*  Gimplify an EXPR_STMT node.  */
221 
222 static void
gimplify_expr_stmt(tree * stmt_p)223 gimplify_expr_stmt (tree *stmt_p)
224 {
225   tree stmt = EXPR_STMT_EXPR (*stmt_p);
226 
227   if (stmt == error_mark_node)
228     stmt = NULL;
229 
230   /* Gimplification of a statement expression will nullify the
231      statement if all its side effects are moved to *PRE_P and *POST_P.
232 
233      In this case we will not want to emit the gimplified statement.
234      However, we may still want to emit a warning, so we do that before
235      gimplification.  */
236   if (stmt && warn_unused_value)
237     {
238       if (!TREE_SIDE_EFFECTS (stmt))
239 	{
240 	  if (!IS_EMPTY_STMT (stmt)
241 	      && !VOID_TYPE_P (TREE_TYPE (stmt))
242 	      && !warning_suppressed_p (stmt, OPT_Wunused_value))
243 	    warning (OPT_Wunused_value, "statement with no effect");
244 	}
245       else
246 	warn_if_unused_value (stmt, input_location);
247     }
248 
249   if (stmt == NULL_TREE)
250     stmt = alloc_stmt_list ();
251 
252   *stmt_p = stmt;
253 }
254 
255 /* Gimplify initialization from an AGGR_INIT_EXPR.  */
256 
257 static void
cp_gimplify_init_expr(tree * expr_p)258 cp_gimplify_init_expr (tree *expr_p)
259 {
260   tree from = TREE_OPERAND (*expr_p, 1);
261   tree to = TREE_OPERAND (*expr_p, 0);
262   tree t;
263 
264   if (TREE_CODE (from) == TARGET_EXPR)
265     if (tree init = TARGET_EXPR_INITIAL (from))
266       {
267 	if (target_expr_needs_replace (from))
268 	  {
269 	    /* If this was changed by cp_genericize_target_expr, we need to
270 	       walk into it to replace uses of the slot.  */
271 	    replace_decl (&init, TARGET_EXPR_SLOT (from), to);
272 	    *expr_p = init;
273 	    return;
274 	  }
275 	else
276 	  from = init;
277       }
278 
279   /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
280      inside the TARGET_EXPR.  */
281   for (t = from; t; )
282     {
283       tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
284 
285       /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
286 	 replace the slot operand with our target.
287 
288 	 Should we add a target parm to gimplify_expr instead?  No, as in this
289 	 case we want to replace the INIT_EXPR.  */
290       if (TREE_CODE (sub) == AGGR_INIT_EXPR
291 	  || TREE_CODE (sub) == VEC_INIT_EXPR)
292 	{
293 	  if (TREE_CODE (sub) == AGGR_INIT_EXPR)
294 	    AGGR_INIT_EXPR_SLOT (sub) = to;
295 	  else
296 	    VEC_INIT_EXPR_SLOT (sub) = to;
297 	  *expr_p = from;
298 
299 	  /* The initialization is now a side-effect, so the container can
300 	     become void.  */
301 	  if (from != sub)
302 	    TREE_TYPE (from) = void_type_node;
303 	}
304 
305       /* Handle aggregate NSDMI.  */
306       replace_placeholders (sub, to);
307 
308       if (t == sub)
309 	break;
310       else
311 	t = TREE_OPERAND (t, 1);
312     }
313 
314 }
315 
316 /* Gimplify a MUST_NOT_THROW_EXPR.  */
317 
318 static enum gimplify_status
gimplify_must_not_throw_expr(tree * expr_p,gimple_seq * pre_p)319 gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
320 {
321   tree stmt = *expr_p;
322   tree temp = voidify_wrapper_expr (stmt, NULL);
323   tree body = TREE_OPERAND (stmt, 0);
324   gimple_seq try_ = NULL;
325   gimple_seq catch_ = NULL;
326   gimple *mnt;
327 
328   gimplify_and_add (body, &try_);
329   mnt = gimple_build_eh_must_not_throw (terminate_fn);
330   gimple_seq_add_stmt_without_update (&catch_, mnt);
331   mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
332 
333   gimple_seq_add_stmt_without_update (pre_p, mnt);
334   if (temp)
335     {
336       *expr_p = temp;
337       return GS_OK;
338     }
339 
340   *expr_p = NULL;
341   return GS_ALL_DONE;
342 }
343 
344 /* Return TRUE if an operand (OP) of a given TYPE being copied is
345    really just an empty class copy.
346 
347    Check that the operand has a simple form so that TARGET_EXPRs and
348    non-empty CONSTRUCTORs get reduced properly, and we leave the
349    return slot optimization alone because it isn't a copy.  */
350 
351 bool
simple_empty_class_p(tree type,tree op,tree_code code)352 simple_empty_class_p (tree type, tree op, tree_code code)
353 {
354   if (TREE_CODE (op) == COMPOUND_EXPR)
355     return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
356   if (SIMPLE_TARGET_EXPR_P (op)
357       && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
358     /* The TARGET_EXPR is itself a simple copy, look through it.  */
359     return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
360 
361   if (TREE_CODE (op) == PARM_DECL
362       && TREE_ADDRESSABLE (TREE_TYPE (op)))
363     {
364       tree fn = DECL_CONTEXT (op);
365       if (DECL_THUNK_P (fn)
366 	  || lambda_static_thunk_p (fn))
367 	/* In a thunk, we pass through invisible reference parms, so this isn't
368 	   actually a copy.  */
369 	return false;
370     }
371 
372   return
373     (TREE_CODE (op) == EMPTY_CLASS_EXPR
374      || code == MODIFY_EXPR
375      || is_gimple_lvalue (op)
376      || INDIRECT_REF_P (op)
377      || (TREE_CODE (op) == CONSTRUCTOR
378 	 && CONSTRUCTOR_NELTS (op) == 0)
379      || (TREE_CODE (op) == CALL_EXPR
380 	 && !CALL_EXPR_RETURN_SLOT_OPT (op)))
381     && !TREE_CLOBBER_P (op)
382     && is_really_empty_class (type, /*ignore_vptr*/true);
383 }
384 
385 /* Returns true if evaluating E as an lvalue has side-effects;
386    specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
387    have side-effects until there is a read or write through it.  */
388 
389 static bool
lvalue_has_side_effects(tree e)390 lvalue_has_side_effects (tree e)
391 {
392   if (!TREE_SIDE_EFFECTS (e))
393     return false;
394   while (handled_component_p (e))
395     {
396       if (TREE_CODE (e) == ARRAY_REF
397 	  && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
398 	return true;
399       e = TREE_OPERAND (e, 0);
400     }
401   if (DECL_P (e))
402     /* Just naming a variable has no side-effects.  */
403     return false;
404   else if (INDIRECT_REF_P (e))
405     /* Similarly, indirection has no side-effects.  */
406     return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
407   else
408     /* For anything else, trust TREE_SIDE_EFFECTS.  */
409     return TREE_SIDE_EFFECTS (e);
410 }
411 
412 /* Gimplify *EXPR_P as rvalue into an expression that can't be modified
413    by expressions with side-effects in other operands.  */
414 
415 static enum gimplify_status
gimplify_to_rvalue(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p,bool (* gimple_test_f)(tree))416 gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
417 		    bool (*gimple_test_f) (tree))
418 {
419   enum gimplify_status t
420     = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
421   if (t == GS_ERROR)
422     return GS_ERROR;
423   else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
424     *expr_p = get_initialized_tmp_var (*expr_p, pre_p);
425   return t;
426 }
427 
428 /* Like gimplify_arg, but if ORDERED is set (which should be set if
429    any of the arguments this argument is sequenced before has
430    TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type
431    are gimplified into SSA_NAME or a fresh temporary and for
432    non-is_gimple_reg_type we don't optimize away TARGET_EXPRs.  */
433 
434 static enum gimplify_status
cp_gimplify_arg(tree * arg_p,gimple_seq * pre_p,location_t call_location,bool ordered)435 cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
436 		 bool ordered)
437 {
438   enum gimplify_status t;
439   if (ordered
440       && !is_gimple_reg_type (TREE_TYPE (*arg_p))
441       && TREE_CODE (*arg_p) == TARGET_EXPR)
442     {
443       /* gimplify_arg would strip away the TARGET_EXPR, but
444 	 that can mean we don't copy the argument and some following
445 	 argument with side-effect could modify it.  */
446       protected_set_expr_location (*arg_p, call_location);
447       return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either);
448     }
449   else
450     {
451       t = gimplify_arg (arg_p, pre_p, call_location);
452       if (t == GS_ERROR)
453 	return GS_ERROR;
454       else if (ordered
455 	       && is_gimple_reg_type (TREE_TYPE (*arg_p))
456 	       && is_gimple_variable (*arg_p)
457 	       && TREE_CODE (*arg_p) != SSA_NAME
458 	       /* No need to force references into register, references
459 		  can't be modified.  */
460 	       && !TYPE_REF_P (TREE_TYPE (*arg_p))
461 	       /* And this can't be modified either.  */
462 	       && *arg_p != current_class_ptr)
463 	*arg_p = get_initialized_tmp_var (*arg_p, pre_p);
464       return t;
465     }
466 
467 }
468 
469 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
470 
471 int
cp_gimplify_expr(tree * expr_p,gimple_seq * pre_p,gimple_seq * post_p)472 cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
473 {
474   int saved_stmts_are_full_exprs_p = 0;
475   location_t loc = cp_expr_loc_or_input_loc (*expr_p);
476   enum tree_code code = TREE_CODE (*expr_p);
477   enum gimplify_status ret;
478 
479   if (STATEMENT_CODE_P (code))
480     {
481       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
482       current_stmt_tree ()->stmts_are_full_exprs_p
483 	= STMT_IS_FULL_EXPR_P (*expr_p);
484     }
485 
486   switch (code)
487     {
488     case AGGR_INIT_EXPR:
489       simplify_aggr_init_expr (expr_p);
490       ret = GS_OK;
491       break;
492 
493     case VEC_INIT_EXPR:
494       {
495 	*expr_p = expand_vec_init_expr (NULL_TREE, *expr_p,
496 					tf_warning_or_error);
497 
498 	cp_fold_data data (/*genericize*/true);
499 	cp_walk_tree (expr_p, cp_fold_r, &data, NULL);
500 	cp_genericize_tree (expr_p, false);
501 	copy_if_shared (expr_p);
502 	ret = GS_OK;
503       }
504       break;
505 
506     case THROW_EXPR:
507       /* FIXME communicate throw type to back end, probably by moving
508 	 THROW_EXPR into ../tree.def.  */
509       *expr_p = TREE_OPERAND (*expr_p, 0);
510       ret = GS_OK;
511       break;
512 
513     case MUST_NOT_THROW_EXPR:
514       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
515       break;
516 
517       /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
518 	 LHS of an assignment might also be involved in the RHS, as in bug
519 	 25979.  */
520     case INIT_EXPR:
521       cp_gimplify_init_expr (expr_p);
522       if (TREE_CODE (*expr_p) != INIT_EXPR)
523 	return GS_OK;
524       /* Fall through.  */
525     case MODIFY_EXPR:
526     modify_expr_case:
527       {
528 	/* If the back end isn't clever enough to know that the lhs and rhs
529 	   types are the same, add an explicit conversion.  */
530 	tree op0 = TREE_OPERAND (*expr_p, 0);
531 	tree op1 = TREE_OPERAND (*expr_p, 1);
532 
533 	if (!error_operand_p (op0)
534 	    && !error_operand_p (op1)
535 	    && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
536 		|| TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
537 	    && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
538 	  TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
539 					      TREE_TYPE (op0), op1);
540 
541 	else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
542 	  {
543 	    while (TREE_CODE (op1) == TARGET_EXPR)
544 	      /* We're disconnecting the initializer from its target,
545 		 don't create a temporary.  */
546 	      op1 = TARGET_EXPR_INITIAL (op1);
547 
548 	    /* Remove any copies of empty classes.  Also drop volatile
549 	       variables on the RHS to avoid infinite recursion from
550 	       gimplify_expr trying to load the value.  */
551 	    if (TREE_SIDE_EFFECTS (op1))
552 	      {
553 		if (TREE_THIS_VOLATILE (op1)
554 		    && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
555 		  op1 = build_fold_addr_expr (op1);
556 
557 		gimplify_and_add (op1, pre_p);
558 	      }
559 	    gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
560 			   is_gimple_lvalue, fb_lvalue);
561 	    *expr_p = TREE_OPERAND (*expr_p, 0);
562 	    if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
563 	      /* Avoid 'return *<retval>;'  */
564 	      *expr_p = TREE_OPERAND (*expr_p, 0);
565 	  }
566 	/* P0145 says that the RHS is sequenced before the LHS.
567 	   gimplify_modify_expr gimplifies the RHS before the LHS, but that
568 	   isn't quite strong enough in two cases:
569 
570 	   1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
571 	   mean it's evaluated after the LHS.
572 
573 	   2) the value calculation of the RHS is also sequenced before the
574 	   LHS, so for scalar assignment we need to preevaluate if the
575 	   RHS could be affected by LHS side-effects even if it has no
576 	   side-effects of its own.  We don't need this for classes because
577 	   class assignment takes its RHS by reference.  */
578        else if (flag_strong_eval_order > 1
579                 && TREE_CODE (*expr_p) == MODIFY_EXPR
580                 && lvalue_has_side_effects (op0)
581 		&& (TREE_CODE (op1) == CALL_EXPR
582 		    || (SCALAR_TYPE_P (TREE_TYPE (op1))
583 			&& !TREE_CONSTANT (op1))))
584 	 TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
585       }
586       ret = GS_OK;
587       break;
588 
589     case EMPTY_CLASS_EXPR:
590       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
591       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
592       ret = GS_OK;
593       break;
594 
595     case BASELINK:
596       *expr_p = BASELINK_FUNCTIONS (*expr_p);
597       ret = GS_OK;
598       break;
599 
600     case TRY_BLOCK:
601       genericize_try_block (expr_p);
602       ret = GS_OK;
603       break;
604 
605     case HANDLER:
606       genericize_catch_block (expr_p);
607       ret = GS_OK;
608       break;
609 
610     case EH_SPEC_BLOCK:
611       genericize_eh_spec_block (expr_p);
612       ret = GS_OK;
613       break;
614 
615     case USING_STMT:
616       gcc_unreachable ();
617 
618     case FOR_STMT:
619     case WHILE_STMT:
620     case DO_STMT:
621     case SWITCH_STMT:
622     case CONTINUE_STMT:
623     case BREAK_STMT:
624       gcc_unreachable ();
625 
626     case OMP_FOR:
627     case OMP_SIMD:
628     case OMP_DISTRIBUTE:
629     case OMP_LOOP:
630     case OMP_TASKLOOP:
631       ret = cp_gimplify_omp_for (expr_p, pre_p);
632       break;
633 
634     case EXPR_STMT:
635       gimplify_expr_stmt (expr_p);
636       ret = GS_OK;
637       break;
638 
639     case UNARY_PLUS_EXPR:
640       {
641 	tree arg = TREE_OPERAND (*expr_p, 0);
642 	tree type = TREE_TYPE (*expr_p);
643 	*expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
644 					    : arg;
645 	ret = GS_OK;
646       }
647       break;
648 
649     case CALL_EXPR:
650       ret = GS_OK;
651       if (flag_strong_eval_order == 2
652 	  && CALL_EXPR_FN (*expr_p)
653 	  && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
654 	  && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
655 	{
656 	  tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
657 	  enum gimplify_status t
658 	    = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
659 				  is_gimple_call_addr);
660 	  if (t == GS_ERROR)
661 	    ret = GS_ERROR;
662 	  /* GIMPLE considers most pointer conversion useless, but for
663 	     calls we actually care about the exact function pointer type.  */
664 	  else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
665 	    CALL_EXPR_FN (*expr_p)
666 	      = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
667 	}
668       if (!CALL_EXPR_FN (*expr_p))
669 	/* Internal function call.  */;
670       else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
671 	{
672 	  /* This is a call to a (compound) assignment operator that used
673 	     the operator syntax; gimplify the RHS first.  */
674 	  gcc_assert (call_expr_nargs (*expr_p) == 2);
675 	  gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
676 	  enum gimplify_status t
677 	    = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc,
678 			       TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0)));
679 	  if (t == GS_ERROR)
680 	    ret = GS_ERROR;
681 	}
682       else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
683 	{
684 	  /* Leave the last argument for gimplify_call_expr, to avoid problems
685 	     with __builtin_va_arg_pack().  */
686 	  int nargs = call_expr_nargs (*expr_p) - 1;
687 	  int last_side_effects_arg = -1;
688 	  for (int i = nargs; i > 0; --i)
689 	    if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
690 	      {
691 		last_side_effects_arg = i;
692 		break;
693 	      }
694 	  for (int i = 0; i < nargs; ++i)
695 	    {
696 	      enum gimplify_status t
697 		= cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc,
698 				   i < last_side_effects_arg);
699 	      if (t == GS_ERROR)
700 		ret = GS_ERROR;
701 	    }
702 	}
703       else if (flag_strong_eval_order
704 	       && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
705 	{
706 	  /* If flag_strong_eval_order, evaluate the object argument first.  */
707 	  tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
708 	  if (INDIRECT_TYPE_P (fntype))
709 	    fntype = TREE_TYPE (fntype);
710 	  if (TREE_CODE (fntype) == METHOD_TYPE)
711 	    {
712 	      int nargs = call_expr_nargs (*expr_p);
713 	      bool side_effects = false;
714 	      for (int i = 1; i < nargs; ++i)
715 		if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
716 		  {
717 		    side_effects = true;
718 		    break;
719 		  }
720 	      enum gimplify_status t
721 		= cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc,
722 				   side_effects);
723 	      if (t == GS_ERROR)
724 		ret = GS_ERROR;
725 	    }
726 	}
727       if (ret != GS_ERROR)
728 	{
729 	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
730 	  if (decl && fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
731 	    switch (DECL_FE_FUNCTION_CODE (decl))
732 	      {
733 	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
734 		*expr_p = boolean_false_node;
735 		break;
736 	      case CP_BUILT_IN_SOURCE_LOCATION:
737 		*expr_p
738 		  = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
739 		break;
740 	      case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
741 		*expr_p
742 		  = fold_builtin_is_corresponding_member
743 			(EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
744 			 &CALL_EXPR_ARG (*expr_p, 0));
745 		break;
746 	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
747 		*expr_p
748 		  = fold_builtin_is_pointer_inverconvertible_with_class
749 			(EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
750 			 &CALL_EXPR_ARG (*expr_p, 0));
751 		break;
752 	      default:
753 		break;
754 	      }
755 	}
756       break;
757 
758     case TARGET_EXPR:
759       /* A TARGET_EXPR that expresses direct-initialization should have been
760 	 elided by cp_gimplify_init_expr.  */
761       gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
762       ret = GS_UNHANDLED;
763       break;
764 
765     case PTRMEM_CST:
766       *expr_p = cplus_expand_constant (*expr_p);
767       if (TREE_CODE (*expr_p) == PTRMEM_CST)
768 	ret = GS_ERROR;
769       else
770 	ret = GS_OK;
771       break;
772 
773     case RETURN_EXPR:
774       if (TREE_OPERAND (*expr_p, 0)
775 	  && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
776 	      || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
777 	{
778 	  expr_p = &TREE_OPERAND (*expr_p, 0);
779 	  /* Avoid going through the INIT_EXPR case, which can
780 	     degrade INIT_EXPRs into AGGR_INIT_EXPRs.  */
781 	  goto modify_expr_case;
782 	}
783       /* Fall through.  */
784 
785     default:
786       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
787       break;
788     }
789 
790   /* Restore saved state.  */
791   if (STATEMENT_CODE_P (code))
792     current_stmt_tree ()->stmts_are_full_exprs_p
793       = saved_stmts_are_full_exprs_p;
794 
795   return ret;
796 }
797 
798 static inline bool
is_invisiref_parm(const_tree t)799 is_invisiref_parm (const_tree t)
800 {
801   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
802 	  && DECL_BY_REFERENCE (t));
803 }
804 
805 /* A stable comparison routine for use with splay trees and DECLs.  */
806 
807 static int
splay_tree_compare_decl_uid(splay_tree_key xa,splay_tree_key xb)808 splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
809 {
810   tree a = (tree) xa;
811   tree b = (tree) xb;
812 
813   return DECL_UID (a) - DECL_UID (b);
814 }
815 
816 /* OpenMP context during genericization.  */
817 
818 struct cp_genericize_omp_taskreg
819 {
820   bool is_parallel;
821   bool default_shared;
822   struct cp_genericize_omp_taskreg *outer;
823   splay_tree variables;
824 };
825 
826 /* Return true if genericization should try to determine if
827    DECL is firstprivate or shared within task regions.  */
828 
829 static bool
omp_var_to_track(tree decl)830 omp_var_to_track (tree decl)
831 {
832   tree type = TREE_TYPE (decl);
833   if (is_invisiref_parm (decl))
834     type = TREE_TYPE (type);
835   else if (TYPE_REF_P (type))
836     type = TREE_TYPE (type);
837   while (TREE_CODE (type) == ARRAY_TYPE)
838     type = TREE_TYPE (type);
839   if (type == error_mark_node || !CLASS_TYPE_P (type))
840     return false;
841   if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
842     return false;
843   if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
844     return false;
845   return true;
846 }
847 
848 /* Note DECL use in OpenMP region OMP_CTX during genericization.  */
849 
850 static void
omp_cxx_notice_variable(struct cp_genericize_omp_taskreg * omp_ctx,tree decl)851 omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
852 {
853   splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
854 					 (splay_tree_key) decl);
855   if (n == NULL)
856     {
857       int flags = OMP_CLAUSE_DEFAULT_SHARED;
858       if (omp_ctx->outer)
859 	omp_cxx_notice_variable (omp_ctx->outer, decl);
860       if (!omp_ctx->default_shared)
861 	{
862 	  struct cp_genericize_omp_taskreg *octx;
863 
864 	  for (octx = omp_ctx->outer; octx; octx = octx->outer)
865 	    {
866 	      n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
867 	      if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
868 		{
869 		  flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
870 		  break;
871 		}
872 	      if (octx->is_parallel)
873 		break;
874 	    }
875 	  if (octx == NULL
876 	      && (TREE_CODE (decl) == PARM_DECL
877 		  || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
878 		      && DECL_CONTEXT (decl) == current_function_decl)))
879 	    flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
880 	  if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
881 	    {
882 	      /* DECL is implicitly determined firstprivate in
883 		 the current task construct.  Ensure copy ctor and
884 		 dtor are instantiated, because during gimplification
885 		 it will be already too late.  */
886 	      tree type = TREE_TYPE (decl);
887 	      if (is_invisiref_parm (decl))
888 		type = TREE_TYPE (type);
889 	      else if (TYPE_REF_P (type))
890 		type = TREE_TYPE (type);
891 	      while (TREE_CODE (type) == ARRAY_TYPE)
892 		type = TREE_TYPE (type);
893 	      get_copy_ctor (type, tf_none);
894 	      get_dtor (type, tf_none);
895 	    }
896 	}
897       splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
898     }
899 }
900 
901 /* If we might need to clean up a partially constructed object, break down the
902    CONSTRUCTOR with split_nonconstant_init.  Also expand VEC_INIT_EXPR at this
903    point.  If initializing TO with FROM is non-trivial, overwrite *REPLACE with
904    the result.  */
905 
906 static void
cp_genericize_init(tree * replace,tree from,tree to)907 cp_genericize_init (tree *replace, tree from, tree to)
908 {
909   if (TREE_CODE (from) == VEC_INIT_EXPR)
910     {
911       tree init = expand_vec_init_expr (to, from, tf_warning_or_error);
912 
913       /* Make cp_gimplify_init_expr call replace_decl.  */
914       *replace = fold_convert (void_type_node, init);
915     }
916   else if (flag_exceptions
917 	   && TREE_CODE (from) == CONSTRUCTOR
918 	   && TREE_SIDE_EFFECTS (from)
919 	   && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from)))
920     {
921       to = cp_stabilize_reference (to);
922       replace_placeholders (from, to);
923       *replace = split_nonconstant_init (to, from);
924     }
925 }
926 
927 /* For an INIT_EXPR, replace the INIT_EXPR itself.  */
928 
929 static void
cp_genericize_init_expr(tree * stmt_p)930 cp_genericize_init_expr (tree *stmt_p)
931 {
932   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
933   tree to = TREE_OPERAND (*stmt_p, 0);
934   tree from = TREE_OPERAND (*stmt_p, 1);
935   if (SIMPLE_TARGET_EXPR_P (from)
936       /* Return gets confused if we clobber its INIT_EXPR this soon.  */
937       && TREE_CODE (to) != RESULT_DECL)
938     from = TARGET_EXPR_INITIAL (from);
939   cp_genericize_init (stmt_p, from, to);
940 }
941 
942 /* For a TARGET_EXPR, change the TARGET_EXPR_INITIAL.  We will need to use
943    replace_decl later when we know what we're initializing.  */
944 
945 static void
cp_genericize_target_expr(tree * stmt_p)946 cp_genericize_target_expr (tree *stmt_p)
947 {
948   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
949   tree slot = TARGET_EXPR_SLOT (*stmt_p);
950   cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
951 		      TARGET_EXPR_INITIAL (*stmt_p), slot);
952   gcc_assert (!DECL_INITIAL (slot));
953 }
954 
955 /* Genericization context.  */
956 
957 struct cp_genericize_data
958 {
959   hash_set<tree> *p_set;
960   auto_vec<tree> bind_expr_stack;
961   struct cp_genericize_omp_taskreg *omp_ctx;
962   tree try_block;
963   bool no_sanitize_p;
964   bool handle_invisiref_parm_p;
965 };
966 
967 /* Perform any pre-gimplification folding of C++ front end trees to
968    GENERIC.
969    Note:  The folding of non-omp cases is something to move into
970      the middle-end.  As for now we have most foldings only on GENERIC
971      in fold-const, we need to perform this before transformation to
972      GIMPLE-form.  */
973 
974 static tree
cp_fold_r(tree * stmt_p,int * walk_subtrees,void * data_)975 cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
976 {
977   cp_fold_data *data = (cp_fold_data*)data_;
978   tree stmt = *stmt_p;
979   enum tree_code code = TREE_CODE (stmt);
980 
981   switch (code)
982     {
983     case PTRMEM_CST:
984       if (TREE_CODE (PTRMEM_CST_MEMBER (stmt)) == FUNCTION_DECL
985 	  && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (stmt)))
986 	{
987 	  if (!data->pset.add (stmt))
988 	    error_at (PTRMEM_CST_LOCATION (stmt),
989 		      "taking address of an immediate function %qD",
990 		      PTRMEM_CST_MEMBER (stmt));
991 	  stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt));
992 	  break;
993 	}
994       break;
995 
996     case ADDR_EXPR:
997       if (TREE_CODE (TREE_OPERAND (stmt, 0)) == FUNCTION_DECL
998 	  && DECL_IMMEDIATE_FUNCTION_P (TREE_OPERAND (stmt, 0)))
999 	{
1000 	  error_at (EXPR_LOCATION (stmt),
1001 		    "taking address of an immediate function %qD",
1002 		    TREE_OPERAND (stmt, 0));
1003 	  stmt = *stmt_p = build_zero_cst (TREE_TYPE (stmt));
1004 	  break;
1005 	}
1006       break;
1007 
1008     case CALL_EXPR:
1009       if (tree fndecl = cp_get_callee_fndecl_nofold (stmt))
1010 	if (DECL_IMMEDIATE_FUNCTION_P (fndecl)
1011 	    && source_location_current_p (fndecl))
1012 	  *stmt_p = stmt = cxx_constant_value (stmt);
1013       break;
1014 
1015     case VAR_DECL:
1016       /* In initializers replace anon union artificial VAR_DECLs
1017 	 with their DECL_VALUE_EXPRs, as nothing will do it later.
1018 	 Ditto for structured bindings.  */
1019       if (!data->genericize
1020 	  && DECL_HAS_VALUE_EXPR_P (stmt)
1021 	  && (DECL_ANON_UNION_VAR_P (stmt)
1022 	      || (DECL_DECOMPOSITION_P (stmt) && DECL_DECOMP_BASE (stmt))))
1023 	{
1024 	  *stmt_p = stmt = unshare_expr (DECL_VALUE_EXPR (stmt));
1025 	  break;
1026 	}
1027       break;
1028 
1029     default:
1030       break;
1031     }
1032 
1033   *stmt_p = stmt = cp_fold (*stmt_p);
1034 
1035   if (data->pset.add (stmt))
1036     {
1037       /* Don't walk subtrees of stmts we've already walked once, otherwise
1038 	 we can have exponential complexity with e.g. lots of nested
1039 	 SAVE_EXPRs or TARGET_EXPRs.  cp_fold uses a cache and will return
1040 	 always the same tree, which the first time cp_fold_r has been
1041 	 called on it had the subtrees walked.  */
1042       *walk_subtrees = 0;
1043       return NULL;
1044     }
1045 
1046   code = TREE_CODE (stmt);
1047   switch (code)
1048     {
1049       tree x;
1050       int i, n;
1051     case OMP_FOR:
1052     case OMP_SIMD:
1053     case OMP_DISTRIBUTE:
1054     case OMP_LOOP:
1055     case OMP_TASKLOOP:
1056     case OACC_LOOP:
1057       cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
1058       cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
1059       cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
1060       x = OMP_FOR_COND (stmt);
1061       if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
1062 	{
1063 	  cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
1064 	  cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
1065 	}
1066       else if (x && TREE_CODE (x) == TREE_VEC)
1067 	{
1068 	  n = TREE_VEC_LENGTH (x);
1069 	  for (i = 0; i < n; i++)
1070 	    {
1071 	      tree o = TREE_VEC_ELT (x, i);
1072 	      if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
1073 		cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1074 	    }
1075 	}
1076       x = OMP_FOR_INCR (stmt);
1077       if (x && TREE_CODE (x) == TREE_VEC)
1078 	{
1079 	  n = TREE_VEC_LENGTH (x);
1080 	  for (i = 0; i < n; i++)
1081 	    {
1082 	      tree o = TREE_VEC_ELT (x, i);
1083 	      if (o && TREE_CODE (o) == MODIFY_EXPR)
1084 		o = TREE_OPERAND (o, 1);
1085 	      if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
1086 			|| TREE_CODE (o) == POINTER_PLUS_EXPR))
1087 		{
1088 		  cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
1089 		  cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
1090 		}
1091 	    }
1092 	}
1093       cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
1094       *walk_subtrees = 0;
1095       return NULL;
1096 
1097     case IF_STMT:
1098       if (IF_STMT_CONSTEVAL_P (stmt))
1099 	{
1100 	  /* Don't walk THEN_CLAUSE (stmt) for consteval if.  IF_COND is always
1101 	     boolean_false_node.  */
1102 	  cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
1103 	  cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
1104 	  *walk_subtrees = 0;
1105 	  return NULL;
1106 	}
1107       break;
1108 
1109       /* These are only for genericize time; they're here rather than in
1110 	 cp_genericize to avoid problems with the invisible reference
1111 	 transition.  */
1112     case INIT_EXPR:
1113       if (data->genericize)
1114 	cp_genericize_init_expr (stmt_p);
1115       break;
1116 
1117     case TARGET_EXPR:
1118       if (data->genericize)
1119 	cp_genericize_target_expr (stmt_p);
1120       break;
1121 
1122     default:
1123       break;
1124     }
1125 
1126   return NULL;
1127 }
1128 
1129 /* Fold ALL the trees!  FIXME we should be able to remove this, but
1130    apparently that still causes optimization regressions.  */
1131 
1132 void
cp_fold_function(tree fndecl)1133 cp_fold_function (tree fndecl)
1134 {
1135   cp_fold_data data (/*genericize*/true);
1136   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
1137 }
1138 
1139 /* Turn SPACESHIP_EXPR EXPR into GENERIC.  */
1140 
genericize_spaceship(tree expr)1141 static tree genericize_spaceship (tree expr)
1142 {
1143   iloc_sentinel s (cp_expr_location (expr));
1144   tree type = TREE_TYPE (expr);
1145   tree op0 = TREE_OPERAND (expr, 0);
1146   tree op1 = TREE_OPERAND (expr, 1);
1147   return genericize_spaceship (input_location, type, op0, op1);
1148 }
1149 
1150 /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
1151    to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
1152    the middle-end (c++/88256).  If EXPR is a DECL, use add_stmt and return
1153    NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR.  */
1154 
1155 tree
predeclare_vla(tree expr)1156 predeclare_vla (tree expr)
1157 {
1158   tree type = TREE_TYPE (expr);
1159   if (type == error_mark_node)
1160     return expr;
1161   if (is_typedef_decl (expr))
1162     type = DECL_ORIGINAL_TYPE (expr);
1163 
1164   /* We need to strip pointers for gimplify_type_sizes.  */
1165   tree vla = type;
1166   while (POINTER_TYPE_P (vla))
1167     {
1168       if (TYPE_NAME (vla))
1169 	return expr;
1170       vla = TREE_TYPE (vla);
1171     }
1172   if (vla == type || TYPE_NAME (vla)
1173       || !variably_modified_type_p (vla, NULL_TREE))
1174     return expr;
1175 
1176   tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
1177   DECL_ARTIFICIAL (decl) = 1;
1178   TYPE_NAME (vla) = decl;
1179   tree dexp = build_stmt (input_location, DECL_EXPR, decl);
1180   if (DECL_P (expr))
1181     {
1182       add_stmt (dexp);
1183       return NULL_TREE;
1184     }
1185   else
1186     {
1187       expr = build2 (COMPOUND_EXPR, type, dexp, expr);
1188       return expr;
1189     }
1190 }
1191 
1192 /* Perform any pre-gimplification lowering of C++ front end trees to
1193    GENERIC.  */
1194 
1195 static tree
cp_genericize_r(tree * stmt_p,int * walk_subtrees,void * data)1196 cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
1197 {
1198   tree stmt = *stmt_p;
1199   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
1200   hash_set<tree> *p_set = wtd->p_set;
1201 
1202   /* If in an OpenMP context, note var uses.  */
1203   if (__builtin_expect (wtd->omp_ctx != NULL, 0)
1204       && (VAR_P (stmt)
1205 	  || TREE_CODE (stmt) == PARM_DECL
1206 	  || TREE_CODE (stmt) == RESULT_DECL)
1207       && omp_var_to_track (stmt))
1208     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
1209 
1210   /* Don't dereference parms in a thunk, pass the references through. */
1211   if ((TREE_CODE (stmt) == CALL_EXPR && call_from_lambda_thunk_p (stmt))
1212       || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
1213     {
1214       *walk_subtrees = 0;
1215       return NULL;
1216     }
1217 
1218   /* Dereference invisible reference parms.  */
1219   if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
1220     {
1221       *stmt_p = convert_from_reference (stmt);
1222       p_set->add (*stmt_p);
1223       *walk_subtrees = 0;
1224       return NULL;
1225     }
1226 
1227   /* Map block scope extern declarations to visible declarations with the
1228      same name and type in outer scopes if any.  */
1229   if (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
1230     if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
1231       {
1232 	if (alias != error_mark_node)
1233 	  {
1234 	    *stmt_p = alias;
1235 	    TREE_USED (alias) |= TREE_USED (stmt);
1236 	  }
1237 	*walk_subtrees = 0;
1238 	return NULL;
1239       }
1240 
1241   if (TREE_CODE (stmt) == INTEGER_CST
1242       && TYPE_REF_P (TREE_TYPE (stmt))
1243       && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1244       && !wtd->no_sanitize_p)
1245     {
1246       ubsan_maybe_instrument_reference (stmt_p);
1247       if (*stmt_p != stmt)
1248 	{
1249 	  *walk_subtrees = 0;
1250 	  return NULL_TREE;
1251 	}
1252     }
1253 
1254   /* Other than invisiref parms, don't walk the same tree twice.  */
1255   if (p_set->contains (stmt))
1256     {
1257       *walk_subtrees = 0;
1258       return NULL_TREE;
1259     }
1260 
1261   switch (TREE_CODE (stmt))
1262     {
1263     case ADDR_EXPR:
1264       if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1265 	{
1266 	  /* If in an OpenMP context, note var uses.  */
1267 	  if (__builtin_expect (wtd->omp_ctx != NULL, 0)
1268 	      && omp_var_to_track (TREE_OPERAND (stmt, 0)))
1269 	    omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
1270 	  *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
1271 	  *walk_subtrees = 0;
1272 	}
1273       break;
1274 
1275     case RETURN_EXPR:
1276       if (TREE_OPERAND (stmt, 0) && is_invisiref_parm (TREE_OPERAND (stmt, 0)))
1277 	/* Don't dereference an invisiref RESULT_DECL inside a RETURN_EXPR.  */
1278 	*walk_subtrees = 0;
1279       break;
1280 
1281     case OMP_CLAUSE:
1282       switch (OMP_CLAUSE_CODE (stmt))
1283 	{
1284 	case OMP_CLAUSE_LASTPRIVATE:
1285 	  /* Don't dereference an invisiref in OpenMP clauses.  */
1286 	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1287 	    {
1288 	      *walk_subtrees = 0;
1289 	      if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
1290 		cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
1291 			      cp_genericize_r, data, NULL);
1292 	    }
1293 	  break;
1294 	case OMP_CLAUSE_PRIVATE:
1295 	  /* Don't dereference an invisiref in OpenMP clauses.  */
1296 	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1297 	    *walk_subtrees = 0;
1298 	  else if (wtd->omp_ctx != NULL)
1299 	    {
1300 	      /* Private clause doesn't cause any references to the
1301 		 var in outer contexts, avoid calling
1302 		 omp_cxx_notice_variable for it.  */
1303 	      struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
1304 	      wtd->omp_ctx = NULL;
1305 	      cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
1306 			    data, NULL);
1307 	      wtd->omp_ctx = old;
1308 	      *walk_subtrees = 0;
1309 	    }
1310 	  break;
1311 	case OMP_CLAUSE_SHARED:
1312 	case OMP_CLAUSE_FIRSTPRIVATE:
1313 	case OMP_CLAUSE_COPYIN:
1314 	case OMP_CLAUSE_COPYPRIVATE:
1315 	case OMP_CLAUSE_INCLUSIVE:
1316 	case OMP_CLAUSE_EXCLUSIVE:
1317 	  /* Don't dereference an invisiref in OpenMP clauses.  */
1318 	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1319 	    *walk_subtrees = 0;
1320 	  break;
1321 	case OMP_CLAUSE_REDUCTION:
1322 	case OMP_CLAUSE_IN_REDUCTION:
1323 	case OMP_CLAUSE_TASK_REDUCTION:
1324 	  /* Don't dereference an invisiref in reduction clause's
1325 	     OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
1326 	     still needs to be genericized.  */
1327 	  if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
1328 	    {
1329 	      *walk_subtrees = 0;
1330 	      if (OMP_CLAUSE_REDUCTION_INIT (stmt))
1331 		cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
1332 			      cp_genericize_r, data, NULL);
1333 	      if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
1334 		cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
1335 			      cp_genericize_r, data, NULL);
1336 	    }
1337 	  break;
1338 	default:
1339 	  break;
1340 	}
1341       break;
1342 
1343     /* Due to the way voidify_wrapper_expr is written, we don't get a chance
1344        to lower this construct before scanning it, so we need to lower these
1345        before doing anything else.  */
1346     case CLEANUP_STMT:
1347       *stmt_p = build2_loc (EXPR_LOCATION (stmt),
1348 			    CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
1349 						   : TRY_FINALLY_EXPR,
1350 			    void_type_node,
1351 			    CLEANUP_BODY (stmt),
1352 			    CLEANUP_EXPR (stmt));
1353       break;
1354 
1355     case IF_STMT:
1356       genericize_if_stmt (stmt_p);
1357       /* *stmt_p has changed, tail recurse to handle it again.  */
1358       return cp_genericize_r (stmt_p, walk_subtrees, data);
1359 
1360     /* COND_EXPR might have incompatible types in branches if one or both
1361        arms are bitfields.  Fix it up now.  */
1362     case COND_EXPR:
1363       {
1364 	tree type_left
1365 	  = (TREE_OPERAND (stmt, 1)
1366 	     ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
1367 	     : NULL_TREE);
1368 	tree type_right
1369 	  = (TREE_OPERAND (stmt, 2)
1370 	     ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
1371 	     : NULL_TREE);
1372 	if (type_left
1373 	    && !useless_type_conversion_p (TREE_TYPE (stmt),
1374 					   TREE_TYPE (TREE_OPERAND (stmt, 1))))
1375 	  {
1376 	    TREE_OPERAND (stmt, 1)
1377 	      = fold_convert (type_left, TREE_OPERAND (stmt, 1));
1378 	    gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1379 						   type_left));
1380 	  }
1381 	if (type_right
1382 	    && !useless_type_conversion_p (TREE_TYPE (stmt),
1383 					   TREE_TYPE (TREE_OPERAND (stmt, 2))))
1384 	  {
1385 	    TREE_OPERAND (stmt, 2)
1386 	      = fold_convert (type_right, TREE_OPERAND (stmt, 2));
1387 	    gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
1388 						   type_right));
1389 	  }
1390       }
1391       break;
1392 
1393     case BIND_EXPR:
1394       if (__builtin_expect (wtd->omp_ctx != NULL, 0))
1395 	{
1396 	  tree decl;
1397 	  for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
1398 	    if (VAR_P (decl)
1399 		&& !DECL_EXTERNAL (decl)
1400 		&& omp_var_to_track (decl))
1401 	      {
1402 		splay_tree_node n
1403 		  = splay_tree_lookup (wtd->omp_ctx->variables,
1404 				       (splay_tree_key) decl);
1405 		if (n == NULL)
1406 		  splay_tree_insert (wtd->omp_ctx->variables,
1407 				     (splay_tree_key) decl,
1408 				     TREE_STATIC (decl)
1409 				     ? OMP_CLAUSE_DEFAULT_SHARED
1410 				     : OMP_CLAUSE_DEFAULT_PRIVATE);
1411 	      }
1412 	}
1413       if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
1414 	{
1415 	  /* The point here is to not sanitize static initializers.  */
1416 	  bool no_sanitize_p = wtd->no_sanitize_p;
1417 	  wtd->no_sanitize_p = true;
1418 	  for (tree decl = BIND_EXPR_VARS (stmt);
1419 	       decl;
1420 	       decl = DECL_CHAIN (decl))
1421 	    if (VAR_P (decl)
1422 		&& TREE_STATIC (decl)
1423 		&& DECL_INITIAL (decl))
1424 	      cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
1425 	  wtd->no_sanitize_p = no_sanitize_p;
1426 	}
1427       wtd->bind_expr_stack.safe_push (stmt);
1428       cp_walk_tree (&BIND_EXPR_BODY (stmt),
1429 		    cp_genericize_r, data, NULL);
1430       wtd->bind_expr_stack.pop ();
1431       break;
1432 
1433     case USING_STMT:
1434       {
1435 	tree block = NULL_TREE;
1436 
1437 	/* Get the innermost inclosing GIMPLE_BIND that has a non NULL
1438 	   BLOCK, and append an IMPORTED_DECL to its
1439 	   BLOCK_VARS chained list.  */
1440 	if (wtd->bind_expr_stack.exists ())
1441 	  {
1442 	    int i;
1443 	    for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
1444 	      if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
1445 		break;
1446 	  }
1447 	if (block)
1448 	  {
1449 	    tree decl = TREE_OPERAND (stmt, 0);
1450 	    gcc_assert (decl);
1451 
1452 	    if (undeduced_auto_decl (decl))
1453 	      /* Omit from the GENERIC, the back-end can't handle it.  */;
1454 	    else
1455 	      {
1456 		tree using_directive = make_node (IMPORTED_DECL);
1457 		TREE_TYPE (using_directive) = void_type_node;
1458 		DECL_CONTEXT (using_directive) = current_function_decl;
1459 		DECL_SOURCE_LOCATION (using_directive)
1460 		  = cp_expr_loc_or_input_loc (stmt);
1461 
1462 		IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
1463 		DECL_CHAIN (using_directive) = BLOCK_VARS (block);
1464 		BLOCK_VARS (block) = using_directive;
1465 	      }
1466 	  }
1467 	/* The USING_STMT won't appear in GENERIC.  */
1468 	*stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1469 	*walk_subtrees = 0;
1470       }
1471       break;
1472 
1473     case DECL_EXPR:
1474       if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
1475 	{
1476 	  /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
1477 	  *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
1478 	  *walk_subtrees = 0;
1479 	}
1480       else
1481 	{
1482 	  tree d = DECL_EXPR_DECL (stmt);
1483 	  if (VAR_P (d))
1484 	    gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
1485 	}
1486       break;
1487 
1488     case OMP_PARALLEL:
1489     case OMP_TASK:
1490     case OMP_TASKLOOP:
1491       {
1492 	struct cp_genericize_omp_taskreg omp_ctx;
1493 	tree c, decl;
1494 	splay_tree_node n;
1495 
1496 	*walk_subtrees = 0;
1497 	cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
1498 	omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
1499 	omp_ctx.default_shared = omp_ctx.is_parallel;
1500 	omp_ctx.outer = wtd->omp_ctx;
1501 	omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
1502 	wtd->omp_ctx = &omp_ctx;
1503 	for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
1504 	  switch (OMP_CLAUSE_CODE (c))
1505 	    {
1506 	    case OMP_CLAUSE_SHARED:
1507 	    case OMP_CLAUSE_PRIVATE:
1508 	    case OMP_CLAUSE_FIRSTPRIVATE:
1509 	    case OMP_CLAUSE_LASTPRIVATE:
1510 	      decl = OMP_CLAUSE_DECL (c);
1511 	      if (decl == error_mark_node || !omp_var_to_track (decl))
1512 		break;
1513 	      n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
1514 	      if (n != NULL)
1515 		break;
1516 	      splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
1517 				 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1518 				 ? OMP_CLAUSE_DEFAULT_SHARED
1519 				 : OMP_CLAUSE_DEFAULT_PRIVATE);
1520 	      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
1521 		omp_cxx_notice_variable (omp_ctx.outer, decl);
1522 	      break;
1523 	    case OMP_CLAUSE_DEFAULT:
1524 	      if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
1525 		omp_ctx.default_shared = true;
1526 	    default:
1527 	      break;
1528 	    }
1529 	if (TREE_CODE (stmt) == OMP_TASKLOOP)
1530 	  c_genericize_control_stmt (stmt_p, walk_subtrees, data,
1531 				     cp_genericize_r, cp_walk_subtrees);
1532 	else
1533 	  cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
1534 	wtd->omp_ctx = omp_ctx.outer;
1535 	splay_tree_delete (omp_ctx.variables);
1536       }
1537       break;
1538 
1539     case OMP_TARGET:
1540       cfun->has_omp_target = true;
1541       break;
1542 
1543     case TRY_BLOCK:
1544       {
1545         *walk_subtrees = 0;
1546         tree try_block = wtd->try_block;
1547         wtd->try_block = stmt;
1548         cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
1549         wtd->try_block = try_block;
1550         cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
1551       }
1552       break;
1553 
1554     case MUST_NOT_THROW_EXPR:
1555       /* MUST_NOT_THROW_COND might be something else with TM.  */
1556       if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
1557 	{
1558 	  *walk_subtrees = 0;
1559 	  tree try_block = wtd->try_block;
1560 	  wtd->try_block = stmt;
1561 	  cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
1562 	  wtd->try_block = try_block;
1563 	}
1564       break;
1565 
1566     case THROW_EXPR:
1567       {
1568 	location_t loc = location_of (stmt);
1569 	if (warning_suppressed_p (stmt /* What warning? */))
1570 	  /* Never mind.  */;
1571 	else if (wtd->try_block)
1572 	  {
1573 	    if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
1574 	      {
1575 		auto_diagnostic_group d;
1576 		if (warning_at (loc, OPT_Wterminate,
1577 				"%<throw%> will always call %<terminate%>")
1578 		    && cxx_dialect >= cxx11
1579 		    && DECL_DESTRUCTOR_P (current_function_decl))
1580 		  inform (loc, "in C++11 destructors default to %<noexcept%>");
1581 	      }
1582 	  }
1583 	else
1584 	  {
1585 	    if (warn_cxx11_compat && cxx_dialect < cxx11
1586 		&& DECL_DESTRUCTOR_P (current_function_decl)
1587 		&& (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
1588 		    == NULL_TREE)
1589 		&& (get_defaulted_eh_spec (current_function_decl)
1590 		    == empty_except_spec))
1591 	      warning_at (loc, OPT_Wc__11_compat,
1592 			  "in C++11 this %<throw%> will call %<terminate%> "
1593 			  "because destructors default to %<noexcept%>");
1594 	  }
1595       }
1596       break;
1597 
1598     case CONVERT_EXPR:
1599       gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
1600       break;
1601 
1602     case SPACESHIP_EXPR:
1603       *stmt_p = genericize_spaceship (*stmt_p);
1604       break;
1605 
1606     case PTRMEM_CST:
1607       /* By the time we get here we're handing off to the back end, so we don't
1608 	 need or want to preserve PTRMEM_CST anymore.  */
1609       *stmt_p = cplus_expand_constant (stmt);
1610       *walk_subtrees = 0;
1611       break;
1612 
1613     case MEM_REF:
1614       /* For MEM_REF, make sure not to sanitize the second operand even
1615 	 if it has reference type.  It is just an offset with a type
1616 	 holding other information.  There is no other processing we
1617 	 need to do for INTEGER_CSTs, so just ignore the second argument
1618 	 unconditionally.  */
1619       cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
1620       *walk_subtrees = 0;
1621       break;
1622 
1623     case NOP_EXPR:
1624       *stmt_p = predeclare_vla (*stmt_p);
1625       if (!wtd->no_sanitize_p
1626 	  && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
1627 	  && TYPE_REF_P (TREE_TYPE (stmt)))
1628 	ubsan_maybe_instrument_reference (stmt_p);
1629       break;
1630 
1631     case CALL_EXPR:
1632       /* Evaluate function concept checks instead of treating them as
1633 	 normal functions.  */
1634       if (concept_check_p (stmt))
1635 	{
1636 	  *stmt_p = evaluate_concept_check (stmt);
1637 	  * walk_subtrees = 0;
1638 	  break;
1639 	}
1640 
1641       if (!wtd->no_sanitize_p
1642 	  && sanitize_flags_p ((SANITIZE_NULL
1643 				| SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
1644 	{
1645 	  tree fn = CALL_EXPR_FN (stmt);
1646 	  if (fn != NULL_TREE
1647 	      && !error_operand_p (fn)
1648 	      && INDIRECT_TYPE_P (TREE_TYPE (fn))
1649 	      && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
1650 	    {
1651 	      bool is_ctor
1652 		= TREE_CODE (fn) == ADDR_EXPR
1653 		  && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
1654 		  && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
1655 	      if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
1656 		ubsan_maybe_instrument_member_call (stmt, is_ctor);
1657 	      if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
1658 		cp_ubsan_maybe_instrument_member_call (stmt);
1659 	    }
1660 	  else if (fn == NULL_TREE
1661 		   && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
1662 		   && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
1663 		   && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
1664 	    *walk_subtrees = 0;
1665 	}
1666       /* Fall through.  */
1667     case AGGR_INIT_EXPR:
1668       /* For calls to a multi-versioned function, overload resolution
1669 	 returns the function with the highest target priority, that is,
1670 	 the version that will checked for dispatching first.  If this
1671 	 version is inlinable, a direct call to this version can be made
1672 	 otherwise the call should go through the dispatcher.  */
1673       {
1674 	tree fn = cp_get_callee_fndecl_nofold (stmt);
1675 	if (fn && DECL_FUNCTION_VERSIONED (fn)
1676 	    && (current_function_decl == NULL
1677 		|| !targetm.target_option.can_inline_p (current_function_decl,
1678 							fn)))
1679 	  if (tree dis = get_function_version_dispatcher (fn))
1680 	    {
1681 	      mark_versions_used (dis);
1682 	      dis = build_address (dis);
1683 	      if (TREE_CODE (stmt) == CALL_EXPR)
1684 		CALL_EXPR_FN (stmt) = dis;
1685 	      else
1686 		AGGR_INIT_EXPR_FN (stmt) = dis;
1687 	    }
1688       }
1689       break;
1690 
1691     case TARGET_EXPR:
1692       if (TARGET_EXPR_INITIAL (stmt)
1693 	  && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
1694 	  && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
1695 	TARGET_EXPR_NO_ELIDE (stmt) = 1;
1696       break;
1697 
1698     case TEMPLATE_ID_EXPR:
1699       gcc_assert (concept_check_p (stmt));
1700       /* Emit the value of the concept check.  */
1701       *stmt_p = evaluate_concept_check (stmt);
1702       walk_subtrees = 0;
1703       break;
1704 
1705     case OMP_DISTRIBUTE:
1706       /* Need to explicitly instantiate copy ctors on class iterators of
1707 	 composite distribute parallel for.  */
1708       if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
1709 	{
1710 	  tree *data[4] = { NULL, NULL, NULL, NULL };
1711 	  tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
1712 				  find_combined_omp_for, data, NULL);
1713 	  if (inner != NULL_TREE
1714 	      && TREE_CODE (inner) == OMP_FOR)
1715 	    {
1716 	      for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
1717 		if (OMP_FOR_ORIG_DECLS (inner)
1718 		    && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
1719 				  i)) == TREE_LIST
1720 		    && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
1721 				     i)))
1722 		  {
1723 		    tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
1724 		    /* Class iterators aren't allowed on OMP_SIMD, so the only
1725 		       case we need to solve is distribute parallel for.  */
1726 		    gcc_assert (TREE_CODE (inner) == OMP_FOR
1727 				&& data[1]);
1728 		    tree orig_decl = TREE_PURPOSE (orig);
1729 		    tree c, cl = NULL_TREE;
1730 		    for (c = OMP_FOR_CLAUSES (inner);
1731 			 c; c = OMP_CLAUSE_CHAIN (c))
1732 		      if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1733 			   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
1734 			  && OMP_CLAUSE_DECL (c) == orig_decl)
1735 			{
1736 			  cl = c;
1737 			  break;
1738 			}
1739 		    if (cl == NULL_TREE)
1740 		      {
1741 			for (c = OMP_PARALLEL_CLAUSES (*data[1]);
1742 			     c; c = OMP_CLAUSE_CHAIN (c))
1743 			  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1744 			      && OMP_CLAUSE_DECL (c) == orig_decl)
1745 			    {
1746 			      cl = c;
1747 			      break;
1748 			    }
1749 		      }
1750 		    if (cl)
1751 		      {
1752 			orig_decl = require_complete_type (orig_decl);
1753 			tree inner_type = TREE_TYPE (orig_decl);
1754 			if (orig_decl == error_mark_node)
1755 			  continue;
1756 			if (TYPE_REF_P (TREE_TYPE (orig_decl)))
1757 			  inner_type = TREE_TYPE (inner_type);
1758 
1759 			while (TREE_CODE (inner_type) == ARRAY_TYPE)
1760 			  inner_type = TREE_TYPE (inner_type);
1761 			get_copy_ctor (inner_type, tf_warning_or_error);
1762 		      }
1763 		}
1764 	    }
1765 	}
1766       /* FALLTHRU */
1767 
1768     case FOR_STMT:
1769     case WHILE_STMT:
1770     case DO_STMT:
1771     case SWITCH_STMT:
1772     case CONTINUE_STMT:
1773     case BREAK_STMT:
1774     case OMP_FOR:
1775     case OMP_SIMD:
1776     case OMP_LOOP:
1777     case OACC_LOOP:
1778     case STATEMENT_LIST:
1779       /* These cases are handled by shared code.  */
1780       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
1781 				 cp_genericize_r, cp_walk_subtrees);
1782       break;
1783 
1784     case BIT_CAST_EXPR:
1785       *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
1786 			    TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
1787       break;
1788 
1789     default:
1790       if (IS_TYPE_OR_DECL_P (stmt))
1791 	*walk_subtrees = 0;
1792       break;
1793     }
1794 
1795   p_set->add (*stmt_p);
1796 
1797   return NULL;
1798 }
1799 
1800 /* Lower C++ front end trees to GENERIC in T_P.  */
1801 
1802 static void
cp_genericize_tree(tree * t_p,bool handle_invisiref_parm_p)1803 cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
1804 {
1805   struct cp_genericize_data wtd;
1806 
1807   wtd.p_set = new hash_set<tree>;
1808   wtd.bind_expr_stack.create (0);
1809   wtd.omp_ctx = NULL;
1810   wtd.try_block = NULL_TREE;
1811   wtd.no_sanitize_p = false;
1812   wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
1813   cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
1814   delete wtd.p_set;
1815   if (sanitize_flags_p (SANITIZE_VPTR))
1816     cp_ubsan_instrument_member_accesses (t_p);
1817 }
1818 
1819 /* If a function that should end with a return in non-void
1820    function doesn't obviously end with return, add ubsan
1821    instrumentation code to verify it at runtime.  If -fsanitize=return
1822    is not enabled, instrument __builtin_unreachable.  */
1823 
1824 static void
cp_maybe_instrument_return(tree fndecl)1825 cp_maybe_instrument_return (tree fndecl)
1826 {
1827   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
1828       || DECL_CONSTRUCTOR_P (fndecl)
1829       || DECL_DESTRUCTOR_P (fndecl)
1830       || !targetm.warn_func_return (fndecl))
1831     return;
1832 
1833   if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
1834       /* Don't add __builtin_unreachable () if not optimizing, it will not
1835 	 improve any optimizations in that case, just break UB code.
1836 	 Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
1837 	 UBSan covers this with ubsan_instrument_return above where sufficient
1838 	 information is provided, while the __builtin_unreachable () below
1839 	 if return sanitization is disabled will just result in hard to
1840 	 understand runtime error without location.  */
1841       && (!optimize
1842 	  || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
1843     return;
1844 
1845   tree t = DECL_SAVED_TREE (fndecl);
1846   while (t)
1847     {
1848       switch (TREE_CODE (t))
1849 	{
1850 	case BIND_EXPR:
1851 	  t = BIND_EXPR_BODY (t);
1852 	  continue;
1853 	case TRY_FINALLY_EXPR:
1854 	case CLEANUP_POINT_EXPR:
1855 	  t = TREE_OPERAND (t, 0);
1856 	  continue;
1857 	case STATEMENT_LIST:
1858 	  {
1859 	    tree_stmt_iterator i = tsi_last (t);
1860 	    while (!tsi_end_p (i))
1861 	      {
1862 		tree p = tsi_stmt (i);
1863 		if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
1864 		  break;
1865 		tsi_prev (&i);
1866 	      }
1867 	    if (!tsi_end_p (i))
1868 	      {
1869 		t = tsi_stmt (i);
1870 		continue;
1871 	      }
1872 	  }
1873 	  break;
1874 	case RETURN_EXPR:
1875 	  return;
1876 	default:
1877 	  break;
1878 	}
1879       break;
1880     }
1881   if (t == NULL_TREE)
1882     return;
1883   tree *p = &DECL_SAVED_TREE (fndecl);
1884   if (TREE_CODE (*p) == BIND_EXPR)
1885     p = &BIND_EXPR_BODY (*p);
1886 
1887   location_t loc = DECL_SOURCE_LOCATION (fndecl);
1888   if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
1889     t = ubsan_instrument_return (loc);
1890   else
1891     {
1892       tree fndecl = builtin_decl_explicit (BUILT_IN_UNREACHABLE);
1893       t = build_call_expr_loc (BUILTINS_LOCATION, fndecl, 0);
1894     }
1895 
1896   append_to_statement_list (t, p);
1897 }
1898 
1899 void
cp_genericize(tree fndecl)1900 cp_genericize (tree fndecl)
1901 {
1902   tree t;
1903 
1904   /* Fix up the types of parms passed by invisible reference.  */
1905   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1906     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1907       {
1908 	/* If a function's arguments are copied to create a thunk,
1909 	   then DECL_BY_REFERENCE will be set -- but the type of the
1910 	   argument will be a pointer type, so we will never get
1911 	   here.  */
1912 	gcc_assert (!DECL_BY_REFERENCE (t));
1913 	gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1914 	TREE_TYPE (t) = DECL_ARG_TYPE (t);
1915 	DECL_BY_REFERENCE (t) = 1;
1916 	TREE_ADDRESSABLE (t) = 0;
1917 	relayout_decl (t);
1918       }
1919 
1920   /* Do the same for the return value.  */
1921   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
1922     {
1923       t = DECL_RESULT (fndecl);
1924       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
1925       DECL_BY_REFERENCE (t) = 1;
1926       TREE_ADDRESSABLE (t) = 0;
1927       relayout_decl (t);
1928       if (DECL_NAME (t))
1929 	{
1930 	  /* Adjust DECL_VALUE_EXPR of the original var.  */
1931 	  tree outer = outer_curly_brace_block (current_function_decl);
1932 	  tree var;
1933 
1934 	  if (outer)
1935 	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
1936 	      if (VAR_P (var)
1937 		  && DECL_NAME (t) == DECL_NAME (var)
1938 		  && DECL_HAS_VALUE_EXPR_P (var)
1939 		  && DECL_VALUE_EXPR (var) == t)
1940 		{
1941 		  tree val = convert_from_reference (t);
1942 		  SET_DECL_VALUE_EXPR (var, val);
1943 		  break;
1944 		}
1945 	}
1946     }
1947 
1948   /* If we're a clone, the body is already GIMPLE.  */
1949   if (DECL_CLONED_FUNCTION_P (fndecl))
1950     return;
1951 
1952   /* Allow cp_genericize calls to be nested.  */
1953   bc_state_t save_state;
1954   save_bc_state (&save_state);
1955 
1956   /* We do want to see every occurrence of the parms, so we can't just use
1957      walk_tree's hash functionality.  */
1958   cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
1959 
1960   cp_maybe_instrument_return (fndecl);
1961 
1962   /* Do everything else.  */
1963   c_genericize (fndecl);
1964   restore_bc_state (&save_state);
1965 }
1966 
1967 /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
1968    NULL if there is in fact nothing to do.  ARG2 may be null if FN
1969    actually only takes one argument.  */
1970 
1971 static tree
cxx_omp_clause_apply_fn(tree fn,tree arg1,tree arg2)1972 cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
1973 {
1974   tree defparm, parm, t;
1975   int i = 0;
1976   int nargs;
1977   tree *argarray;
1978 
1979   if (fn == NULL)
1980     return NULL;
1981 
1982   nargs = list_length (DECL_ARGUMENTS (fn));
1983   argarray = XALLOCAVEC (tree, nargs);
1984 
1985   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
1986   if (arg2)
1987     defparm = TREE_CHAIN (defparm);
1988 
1989   bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
1990   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
1991     {
1992       tree inner_type = TREE_TYPE (arg1);
1993       tree start1, end1, p1;
1994       tree start2 = NULL, p2 = NULL;
1995       tree ret = NULL, lab;
1996 
1997       start1 = arg1;
1998       start2 = arg2;
1999       do
2000 	{
2001 	  inner_type = TREE_TYPE (inner_type);
2002 	  start1 = build4 (ARRAY_REF, inner_type, start1,
2003 			   size_zero_node, NULL, NULL);
2004 	  if (arg2)
2005 	    start2 = build4 (ARRAY_REF, inner_type, start2,
2006 			     size_zero_node, NULL, NULL);
2007 	}
2008       while (TREE_CODE (inner_type) == ARRAY_TYPE);
2009       start1 = build_fold_addr_expr_loc (input_location, start1);
2010       if (arg2)
2011 	start2 = build_fold_addr_expr_loc (input_location, start2);
2012 
2013       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
2014       end1 = fold_build_pointer_plus (start1, end1);
2015 
2016       p1 = create_tmp_var (TREE_TYPE (start1));
2017       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
2018       append_to_statement_list (t, &ret);
2019 
2020       if (arg2)
2021 	{
2022 	  p2 = create_tmp_var (TREE_TYPE (start2));
2023 	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
2024 	  append_to_statement_list (t, &ret);
2025 	}
2026 
2027       lab = create_artificial_label (input_location);
2028       t = build1 (LABEL_EXPR, void_type_node, lab);
2029       append_to_statement_list (t, &ret);
2030 
2031       argarray[i++] = p1;
2032       if (arg2)
2033 	argarray[i++] = p2;
2034       /* Handle default arguments.  */
2035       for (parm = defparm; parm && parm != void_list_node;
2036 	   parm = TREE_CHAIN (parm), i++)
2037 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
2038 					   TREE_PURPOSE (parm), fn,
2039 					   i - is_method, tf_warning_or_error);
2040       t = build_call_a (fn, i, argarray);
2041       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2042 	t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2043       t = fold_convert (void_type_node, t);
2044       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2045       append_to_statement_list (t, &ret);
2046 
2047       t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
2048       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
2049       append_to_statement_list (t, &ret);
2050 
2051       if (arg2)
2052 	{
2053 	  t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
2054 	  t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
2055 	  append_to_statement_list (t, &ret);
2056 	}
2057 
2058       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
2059       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
2060       append_to_statement_list (t, &ret);
2061 
2062       return ret;
2063     }
2064   else
2065     {
2066       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
2067       if (arg2)
2068 	argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
2069       /* Handle default arguments.  */
2070       for (parm = defparm; parm && parm != void_list_node;
2071 	   parm = TREE_CHAIN (parm), i++)
2072 	argarray[i] = convert_default_arg (TREE_VALUE (parm),
2073 					   TREE_PURPOSE (parm), fn,
2074 					   i - is_method, tf_warning_or_error);
2075       t = build_call_a (fn, i, argarray);
2076       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
2077 	t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
2078       t = fold_convert (void_type_node, t);
2079       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
2080     }
2081 }
2082 
2083 /* Return code to initialize DECL with its default constructor, or
2084    NULL if there's nothing to do.  */
2085 
2086 tree
cxx_omp_clause_default_ctor(tree clause,tree decl,tree)2087 cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
2088 {
2089   tree info = CP_OMP_CLAUSE_INFO (clause);
2090   tree ret = NULL;
2091 
2092   if (info)
2093     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
2094 
2095   return ret;
2096 }
2097 
2098 /* Return code to initialize DST with a copy constructor from SRC.  */
2099 
2100 tree
cxx_omp_clause_copy_ctor(tree clause,tree dst,tree src)2101 cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
2102 {
2103   tree info = CP_OMP_CLAUSE_INFO (clause);
2104   tree ret = NULL;
2105 
2106   if (info)
2107     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
2108   if (ret == NULL)
2109     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2110 
2111   return ret;
2112 }
2113 
2114 /* Similarly, except use an assignment operator instead.  */
2115 
2116 tree
cxx_omp_clause_assign_op(tree clause,tree dst,tree src)2117 cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
2118 {
2119   tree info = CP_OMP_CLAUSE_INFO (clause);
2120   tree ret = NULL;
2121 
2122   if (info)
2123     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
2124   if (ret == NULL)
2125     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
2126 
2127   return ret;
2128 }
2129 
2130 /* Return code to destroy DECL.  */
2131 
2132 tree
cxx_omp_clause_dtor(tree clause,tree decl)2133 cxx_omp_clause_dtor (tree clause, tree decl)
2134 {
2135   tree info = CP_OMP_CLAUSE_INFO (clause);
2136   tree ret = NULL;
2137 
2138   if (info)
2139     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
2140 
2141   return ret;
2142 }
2143 
2144 /* True if OpenMP should privatize what this DECL points to rather
2145    than the DECL itself.  */
2146 
2147 bool
cxx_omp_privatize_by_reference(const_tree decl)2148 cxx_omp_privatize_by_reference (const_tree decl)
2149 {
2150   return (TYPE_REF_P (TREE_TYPE (decl))
2151 	  || is_invisiref_parm (decl));
2152 }
2153 
2154 /* Return true if DECL is const qualified var having no mutable member.  */
2155 bool
cxx_omp_const_qual_no_mutable(tree decl)2156 cxx_omp_const_qual_no_mutable (tree decl)
2157 {
2158   tree type = TREE_TYPE (decl);
2159   if (TYPE_REF_P (type))
2160     {
2161       if (!is_invisiref_parm (decl))
2162 	return false;
2163       type = TREE_TYPE (type);
2164 
2165       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
2166 	{
2167 	  /* NVR doesn't preserve const qualification of the
2168 	     variable's type.  */
2169 	  tree outer = outer_curly_brace_block (current_function_decl);
2170 	  tree var;
2171 
2172 	  if (outer)
2173 	    for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
2174 	      if (VAR_P (var)
2175 		  && DECL_NAME (decl) == DECL_NAME (var)
2176 		  && (TYPE_MAIN_VARIANT (type)
2177 		      == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
2178 		{
2179 		  if (TYPE_READONLY (TREE_TYPE (var)))
2180 		    type = TREE_TYPE (var);
2181 		  break;
2182 		}
2183 	}
2184     }
2185 
2186   if (type == error_mark_node)
2187     return false;
2188 
2189   /* Variables with const-qualified type having no mutable member
2190      are predetermined shared.  */
2191   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
2192     return true;
2193 
2194   return false;
2195 }
2196 
2197 /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
2198    of DECL is predetermined.  */
2199 
2200 enum omp_clause_default_kind
cxx_omp_predetermined_sharing_1(tree decl)2201 cxx_omp_predetermined_sharing_1 (tree decl)
2202 {
2203   /* Static data members are predetermined shared.  */
2204   if (TREE_STATIC (decl))
2205     {
2206       tree ctx = CP_DECL_CONTEXT (decl);
2207       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
2208 	return OMP_CLAUSE_DEFAULT_SHARED;
2209 
2210       if (c_omp_predefined_variable (decl))
2211 	return OMP_CLAUSE_DEFAULT_SHARED;
2212     }
2213 
2214   /* this may not be specified in data-sharing clauses, still we need
2215      to predetermined it firstprivate.  */
2216   if (decl == current_class_ptr)
2217     return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
2218 
2219   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2220 }
2221 
2222 /* Likewise, but also include the artificial vars.  We don't want to
2223    disallow the artificial vars being mentioned in explicit clauses,
2224    as we use artificial vars e.g. for loop constructs with random
2225    access iterators other than pointers, but during gimplification
2226    we want to treat them as predetermined.  */
2227 
2228 enum omp_clause_default_kind
cxx_omp_predetermined_sharing(tree decl)2229 cxx_omp_predetermined_sharing (tree decl)
2230 {
2231   enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
2232   if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
2233     return ret;
2234 
2235   /* Predetermine artificial variables holding integral values, those
2236      are usually result of gimplify_one_sizepos or SAVE_EXPR
2237      gimplification.  */
2238   if (VAR_P (decl)
2239       && DECL_ARTIFICIAL (decl)
2240       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
2241       && !(DECL_LANG_SPECIFIC (decl)
2242 	   && DECL_OMP_PRIVATIZED_MEMBER (decl)))
2243     return OMP_CLAUSE_DEFAULT_SHARED;
2244 
2245   /* Similarly for typeinfo symbols.  */
2246   if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
2247     return OMP_CLAUSE_DEFAULT_SHARED;
2248 
2249   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
2250 }
2251 
2252 enum omp_clause_defaultmap_kind
cxx_omp_predetermined_mapping(tree decl)2253 cxx_omp_predetermined_mapping (tree decl)
2254 {
2255   /* Predetermine artificial variables holding integral values, those
2256      are usually result of gimplify_one_sizepos or SAVE_EXPR
2257      gimplification.  */
2258   if (VAR_P (decl)
2259       && DECL_ARTIFICIAL (decl)
2260       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
2261       && !(DECL_LANG_SPECIFIC (decl)
2262 	   && DECL_OMP_PRIVATIZED_MEMBER (decl)))
2263     return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
2264 
2265   if (c_omp_predefined_variable (decl))
2266     return OMP_CLAUSE_DEFAULTMAP_TO;
2267 
2268   return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
2269 }
2270 
2271 /* Finalize an implicitly determined clause.  */
2272 
2273 void
cxx_omp_finish_clause(tree c,gimple_seq *,bool)2274 cxx_omp_finish_clause (tree c, gimple_seq *, bool /* openacc */)
2275 {
2276   tree decl, inner_type;
2277   bool make_shared = false;
2278 
2279   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
2280       && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
2281       && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
2282 	  || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
2283     return;
2284 
2285   decl = OMP_CLAUSE_DECL (c);
2286   decl = require_complete_type (decl);
2287   inner_type = TREE_TYPE (decl);
2288   if (decl == error_mark_node)
2289     make_shared = true;
2290   else if (TYPE_REF_P (TREE_TYPE (decl)))
2291     inner_type = TREE_TYPE (inner_type);
2292 
2293   /* We're interested in the base element, not arrays.  */
2294   while (TREE_CODE (inner_type) == ARRAY_TYPE)
2295     inner_type = TREE_TYPE (inner_type);
2296 
2297   /* Check for special function availability by building a call to one.
2298      Save the results, because later we won't be in the right context
2299      for making these queries.  */
2300   bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
2301   bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
2302   if (!make_shared
2303       && CLASS_TYPE_P (inner_type)
2304       && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
2305 				     true))
2306     make_shared = true;
2307 
2308   if (make_shared)
2309     {
2310       OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
2311       OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
2312       OMP_CLAUSE_SHARED_READONLY (c) = 0;
2313     }
2314 }
2315 
2316 /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
2317    disregarded in OpenMP construct, because it is going to be
2318    remapped during OpenMP lowering.  SHARED is true if DECL
2319    is going to be shared, false if it is going to be privatized.  */
2320 
2321 bool
cxx_omp_disregard_value_expr(tree decl,bool shared)2322 cxx_omp_disregard_value_expr (tree decl, bool shared)
2323 {
2324   if (shared)
2325     return false;
2326   if (VAR_P (decl)
2327       && DECL_HAS_VALUE_EXPR_P (decl)
2328       && DECL_ARTIFICIAL (decl)
2329       && DECL_LANG_SPECIFIC (decl)
2330       && DECL_OMP_PRIVATIZED_MEMBER (decl))
2331     return true;
2332   if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
2333     return true;
2334   return false;
2335 }
2336 
2337 /* Fold expression X which is used as an rvalue if RVAL is true.  */
2338 
2339 tree
cp_fold_maybe_rvalue(tree x,bool rval)2340 cp_fold_maybe_rvalue (tree x, bool rval)
2341 {
2342   while (true)
2343     {
2344       x = cp_fold (x);
2345       if (rval)
2346 	x = mark_rvalue_use (x);
2347       if (rval && DECL_P (x)
2348 	  && !TYPE_REF_P (TREE_TYPE (x)))
2349 	{
2350 	  tree v = decl_constant_value (x);
2351 	  if (v != x && v != error_mark_node)
2352 	    {
2353 	      x = v;
2354 	      continue;
2355 	    }
2356 	}
2357       break;
2358     }
2359   return x;
2360 }
2361 
2362 /* Fold expression X which is used as an rvalue.  */
2363 
2364 tree
cp_fold_rvalue(tree x)2365 cp_fold_rvalue (tree x)
2366 {
2367   return cp_fold_maybe_rvalue (x, true);
2368 }
2369 
2370 /* Perform folding on expression X.  */
2371 
2372 tree
cp_fully_fold(tree x)2373 cp_fully_fold (tree x)
2374 {
2375   if (processing_template_decl)
2376     return x;
2377   /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
2378      have to call both.  */
2379   if (cxx_dialect >= cxx11)
2380     {
2381       x = maybe_constant_value (x);
2382       /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
2383 	 a TARGET_EXPR; undo that here.  */
2384       if (TREE_CODE (x) == TARGET_EXPR)
2385 	x = TARGET_EXPR_INITIAL (x);
2386       else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
2387 	       && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
2388 	       && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
2389 	x = TREE_OPERAND (x, 0);
2390     }
2391   return cp_fold_rvalue (x);
2392 }
2393 
2394 /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
2395    in some cases.  */
2396 
2397 tree
cp_fully_fold_init(tree x)2398 cp_fully_fold_init (tree x)
2399 {
2400   if (processing_template_decl)
2401     return x;
2402   x = cp_fully_fold (x);
2403   cp_fold_data data (/*genericize*/false);
2404   cp_walk_tree (&x, cp_fold_r, &data, NULL);
2405   return x;
2406 }
2407 
2408 /* c-common interface to cp_fold.  If IN_INIT, this is in a static initializer
2409    and certain changes are made to the folding done.  Or should be (FIXME).  We
2410    never touch maybe_const, as it is only used for the C front-end
2411    C_MAYBE_CONST_EXPR.  */
2412 
2413 tree
c_fully_fold(tree x,bool,bool *,bool lval)2414 c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
2415 {
2416   return cp_fold_maybe_rvalue (x, !lval);
2417 }
2418 
2419 static GTY((deletable)) hash_map<tree, tree> *fold_cache;
2420 
2421 /* Dispose of the whole FOLD_CACHE.  */
2422 
2423 void
clear_fold_cache(void)2424 clear_fold_cache (void)
2425 {
2426   if (fold_cache != NULL)
2427     fold_cache->empty ();
2428 }
2429 
2430 /*  This function tries to fold an expression X.
2431     To avoid combinatorial explosion, folding results are kept in fold_cache.
2432     If X is invalid, we don't fold at all.
2433     For performance reasons we don't cache expressions representing a
2434     declaration or constant.
2435     Function returns X or its folded variant.  */
2436 
2437 static tree
cp_fold(tree x)2438 cp_fold (tree x)
2439 {
2440   tree op0, op1, op2, op3;
2441   tree org_x = x, r = NULL_TREE;
2442   enum tree_code code;
2443   location_t loc;
2444   bool rval_ops = true;
2445 
2446   if (!x || x == error_mark_node)
2447     return x;
2448 
2449   if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
2450     return x;
2451 
2452   /* Don't bother to cache DECLs or constants.  */
2453   if (DECL_P (x) || CONSTANT_CLASS_P (x))
2454     return x;
2455 
2456   if (fold_cache == NULL)
2457     fold_cache = hash_map<tree, tree>::create_ggc (101);
2458 
2459   if (tree *cached = fold_cache->get (x))
2460     {
2461       /* unshare_expr doesn't recurse into SAVE_EXPRs.  If SAVE_EXPR's
2462 	 argument has been folded into a tree invariant, make sure it is
2463 	 unshared.  See PR112727.  */
2464       if (TREE_CODE (x) == SAVE_EXPR && *cached != x)
2465 	return unshare_expr (*cached);
2466       return *cached;
2467     }
2468 
2469   uid_sensitive_constexpr_evaluation_checker c;
2470 
2471   code = TREE_CODE (x);
2472   switch (code)
2473     {
2474     case CLEANUP_POINT_EXPR:
2475       /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
2476 	 effects.  */
2477       r = cp_fold_rvalue (TREE_OPERAND (x, 0));
2478       if (!TREE_SIDE_EFFECTS (r))
2479 	x = r;
2480       break;
2481 
2482     case SIZEOF_EXPR:
2483       x = fold_sizeof_expr (x);
2484       break;
2485 
2486     case VIEW_CONVERT_EXPR:
2487       rval_ops = false;
2488       /* FALLTHRU */
2489     case CONVERT_EXPR:
2490     case NOP_EXPR:
2491     case NON_LVALUE_EXPR:
2492 
2493       if (VOID_TYPE_P (TREE_TYPE (x)))
2494 	{
2495 	  /* This is just to make sure we don't end up with casts to
2496 	     void from error_mark_node.  If we just return x, then
2497 	     cp_fold_r might fold the operand into error_mark_node and
2498 	     leave the conversion in the IR.  STRIP_USELESS_TYPE_CONVERSION
2499 	     during gimplification doesn't like such casts.
2500 	     Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
2501 	     folding of the operand should be in the caches and if in cp_fold_r
2502 	     it will modify it in place.  */
2503 	  op0 = cp_fold (TREE_OPERAND (x, 0));
2504 	  if (op0 == error_mark_node)
2505 	    x = error_mark_node;
2506 	  break;
2507 	}
2508 
2509       loc = EXPR_LOCATION (x);
2510       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
2511 
2512       if (code == CONVERT_EXPR
2513 	  && SCALAR_TYPE_P (TREE_TYPE (x))
2514 	  && op0 != void_node)
2515 	/* During parsing we used convert_to_*_nofold; re-convert now using the
2516 	   folding variants, since fold() doesn't do those transformations.  */
2517 	x = fold (convert (TREE_TYPE (x), op0));
2518       else if (op0 != TREE_OPERAND (x, 0))
2519 	{
2520 	  if (op0 == error_mark_node)
2521 	    x = error_mark_node;
2522 	  else
2523 	    x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
2524 	}
2525       else
2526 	x = fold (x);
2527 
2528       /* Conversion of an out-of-range value has implementation-defined
2529 	 behavior; the language considers it different from arithmetic
2530 	 overflow, which is undefined.  */
2531       if (TREE_CODE (op0) == INTEGER_CST
2532 	  && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
2533 	TREE_OVERFLOW (x) = false;
2534 
2535       break;
2536 
2537     case INDIRECT_REF:
2538       /* We don't need the decltype(auto) obfuscation anymore.  */
2539       if (REF_PARENTHESIZED_P (x))
2540 	{
2541 	  tree p = maybe_undo_parenthesized_ref (x);
2542 	  if (p != x)
2543 	    return cp_fold (p);
2544 	}
2545       goto unary;
2546 
2547     case ADDR_EXPR:
2548       loc = EXPR_LOCATION (x);
2549       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false);
2550 
2551       /* Cope with user tricks that amount to offsetof.  */
2552       if (op0 != error_mark_node
2553 	  && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0)))
2554 	{
2555 	  tree val = get_base_address (op0);
2556 	  if (val
2557 	      && INDIRECT_REF_P (val)
2558 	      && COMPLETE_TYPE_P (TREE_TYPE (val))
2559 	      && TREE_CONSTANT (TREE_OPERAND (val, 0)))
2560 	    {
2561 	      val = TREE_OPERAND (val, 0);
2562 	      STRIP_NOPS (val);
2563 	      val = maybe_constant_value (val);
2564 	      if (TREE_CODE (val) == INTEGER_CST)
2565 		return fold_offsetof (op0, TREE_TYPE (x));
2566 	    }
2567 	}
2568       goto finish_unary;
2569 
2570     case REALPART_EXPR:
2571     case IMAGPART_EXPR:
2572       rval_ops = false;
2573       /* FALLTHRU */
2574     case CONJ_EXPR:
2575     case FIX_TRUNC_EXPR:
2576     case FLOAT_EXPR:
2577     case NEGATE_EXPR:
2578     case ABS_EXPR:
2579     case ABSU_EXPR:
2580     case BIT_NOT_EXPR:
2581     case TRUTH_NOT_EXPR:
2582     case FIXED_CONVERT_EXPR:
2583     unary:
2584 
2585       loc = EXPR_LOCATION (x);
2586       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
2587 
2588     finish_unary:
2589       if (op0 != TREE_OPERAND (x, 0))
2590 	{
2591 	  if (op0 == error_mark_node)
2592 	    x = error_mark_node;
2593 	  else
2594 	    {
2595 	      x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
2596 	      if (code == INDIRECT_REF
2597 		  && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
2598 		{
2599 		  TREE_READONLY (x) = TREE_READONLY (org_x);
2600 		  TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
2601 		  TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
2602 		}
2603 	    }
2604 	}
2605       else
2606 	x = fold (x);
2607 
2608       gcc_assert (TREE_CODE (x) != COND_EXPR
2609 		  || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
2610       break;
2611 
2612     case UNARY_PLUS_EXPR:
2613       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
2614       if (op0 == error_mark_node)
2615 	x = error_mark_node;
2616       else
2617 	x = fold_convert (TREE_TYPE (x), op0);
2618       break;
2619 
2620     case POSTDECREMENT_EXPR:
2621     case POSTINCREMENT_EXPR:
2622     case INIT_EXPR:
2623     case PREDECREMENT_EXPR:
2624     case PREINCREMENT_EXPR:
2625     case COMPOUND_EXPR:
2626     case MODIFY_EXPR:
2627       rval_ops = false;
2628       /* FALLTHRU */
2629     case POINTER_PLUS_EXPR:
2630     case PLUS_EXPR:
2631     case POINTER_DIFF_EXPR:
2632     case MINUS_EXPR:
2633     case MULT_EXPR:
2634     case TRUNC_DIV_EXPR:
2635     case CEIL_DIV_EXPR:
2636     case FLOOR_DIV_EXPR:
2637     case ROUND_DIV_EXPR:
2638     case TRUNC_MOD_EXPR:
2639     case CEIL_MOD_EXPR:
2640     case ROUND_MOD_EXPR:
2641     case RDIV_EXPR:
2642     case EXACT_DIV_EXPR:
2643     case MIN_EXPR:
2644     case MAX_EXPR:
2645     case LSHIFT_EXPR:
2646     case RSHIFT_EXPR:
2647     case LROTATE_EXPR:
2648     case RROTATE_EXPR:
2649     case BIT_AND_EXPR:
2650     case BIT_IOR_EXPR:
2651     case BIT_XOR_EXPR:
2652     case TRUTH_AND_EXPR:
2653     case TRUTH_ANDIF_EXPR:
2654     case TRUTH_OR_EXPR:
2655     case TRUTH_ORIF_EXPR:
2656     case TRUTH_XOR_EXPR:
2657     case LT_EXPR: case LE_EXPR:
2658     case GT_EXPR: case GE_EXPR:
2659     case EQ_EXPR: case NE_EXPR:
2660     case UNORDERED_EXPR: case ORDERED_EXPR:
2661     case UNLT_EXPR: case UNLE_EXPR:
2662     case UNGT_EXPR: case UNGE_EXPR:
2663     case UNEQ_EXPR: case LTGT_EXPR:
2664     case RANGE_EXPR: case COMPLEX_EXPR:
2665 
2666       loc = EXPR_LOCATION (x);
2667       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops);
2668       op1 = cp_fold_rvalue (TREE_OPERAND (x, 1));
2669 
2670       /* decltype(nullptr) has only one value, so optimize away all comparisons
2671 	 with that type right away, keeping them in the IL causes troubles for
2672 	 various optimizations.  */
2673       if (COMPARISON_CLASS_P (org_x)
2674 	  && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
2675 	  && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
2676 	{
2677 	  switch (code)
2678 	    {
2679 	    case EQ_EXPR:
2680 	      x = constant_boolean_node (true, TREE_TYPE (x));
2681 	      break;
2682 	    case NE_EXPR:
2683 	      x = constant_boolean_node (false, TREE_TYPE (x));
2684 	      break;
2685 	    default:
2686 	      gcc_unreachable ();
2687 	    }
2688 	  return omit_two_operands_loc (loc, TREE_TYPE (x), x,
2689 					op0, op1);
2690 	}
2691 
2692       if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
2693 	{
2694 	  if (op0 == error_mark_node || op1 == error_mark_node)
2695 	    x = error_mark_node;
2696 	  else
2697 	    x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
2698 	}
2699       else
2700 	x = fold (x);
2701 
2702       /* This is only needed for -Wnonnull-compare and only if
2703 	 TREE_NO_WARNING (org_x), but to avoid that option affecting code
2704 	 generation, we do it always.  */
2705       if (COMPARISON_CLASS_P (org_x))
2706 	{
2707 	  if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
2708 	    ;
2709 	  else if (COMPARISON_CLASS_P (x))
2710 	    {
2711 	      if (warn_nonnull_compare
2712 		  && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
2713 		suppress_warning (x, OPT_Wnonnull_compare);
2714 	    }
2715 	  /* Otherwise give up on optimizing these, let GIMPLE folders
2716 	     optimize those later on.  */
2717 	  else if (op0 != TREE_OPERAND (org_x, 0)
2718 		   || op1 != TREE_OPERAND (org_x, 1))
2719 	    {
2720 	      x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
2721 	      if (warn_nonnull_compare
2722 		  && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
2723 		suppress_warning (x, OPT_Wnonnull_compare);
2724 	    }
2725 	  else
2726 	    x = org_x;
2727 	}
2728 
2729       break;
2730 
2731     case VEC_COND_EXPR:
2732     case COND_EXPR:
2733       loc = EXPR_LOCATION (x);
2734       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0));
2735       op1 = cp_fold (TREE_OPERAND (x, 1));
2736       op2 = cp_fold (TREE_OPERAND (x, 2));
2737 
2738       if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
2739 	{
2740 	  warning_sentinel s (warn_int_in_bool_context);
2741 	  if (!VOID_TYPE_P (TREE_TYPE (op1)))
2742 	    op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
2743 	  if (!VOID_TYPE_P (TREE_TYPE (op2)))
2744 	    op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
2745 	}
2746       else if (VOID_TYPE_P (TREE_TYPE (x)))
2747 	{
2748 	  if (TREE_CODE (op0) == INTEGER_CST)
2749 	    {
2750 	      /* If the condition is constant, fold can fold away
2751 		 the COND_EXPR.  If some statement-level uses of COND_EXPR
2752 		 have one of the branches NULL, avoid folding crash.  */
2753 	      if (!op1)
2754 		op1 = build_empty_stmt (loc);
2755 	      if (!op2)
2756 		op2 = build_empty_stmt (loc);
2757 	    }
2758 	  else
2759 	    {
2760 	      /* Otherwise, don't bother folding a void condition, since
2761 		 it can't produce a constant value.  */
2762 	      if (op0 != TREE_OPERAND (x, 0)
2763 		  || op1 != TREE_OPERAND (x, 1)
2764 		  || op2 != TREE_OPERAND (x, 2))
2765 		x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
2766 	      break;
2767 	    }
2768 	}
2769 
2770       if (op0 != TREE_OPERAND (x, 0)
2771 	  || op1 != TREE_OPERAND (x, 1)
2772 	  || op2 != TREE_OPERAND (x, 2))
2773 	{
2774 	  if (op0 == error_mark_node
2775 	      || op1 == error_mark_node
2776 	      || op2 == error_mark_node)
2777 	    x = error_mark_node;
2778 	  else
2779 	    x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
2780 	}
2781       else
2782 	x = fold (x);
2783 
2784       /* A COND_EXPR might have incompatible types in branches if one or both
2785 	 arms are bitfields.  If folding exposed such a branch, fix it up.  */
2786       if (TREE_CODE (x) != code
2787 	  && x != error_mark_node
2788 	  && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
2789 	x = fold_convert (TREE_TYPE (org_x), x);
2790 
2791       break;
2792 
2793     case CALL_EXPR:
2794       {
2795 	tree callee = get_callee_fndecl (x);
2796 
2797 	/* "Inline" calls to std::move/forward and other cast-like functions
2798 	   by simply folding them into a corresponding cast to their return
2799 	   type.  This is cheaper than relying on the middle end to do so, and
2800 	   also means we avoid generating useless debug info for them at all.
2801 
2802 	   At this point the argument has already been converted into a
2803 	   reference, so it suffices to use a NOP_EXPR to express the
2804 	   cast.  */
2805 	if ((OPTION_SET_P (flag_fold_simple_inlines)
2806 	     ? flag_fold_simple_inlines
2807 	     : !flag_no_inline)
2808 	    && call_expr_nargs (x) == 1
2809 	    && decl_in_std_namespace_p (callee)
2810 	    && DECL_NAME (callee) != NULL_TREE
2811 	    && (id_equal (DECL_NAME (callee), "move")
2812 		|| id_equal (DECL_NAME (callee), "forward")
2813 		|| id_equal (DECL_NAME (callee), "addressof")
2814 		/* This addressof equivalent is used heavily in libstdc++.  */
2815 		|| id_equal (DECL_NAME (callee), "__addressof")
2816 		|| id_equal (DECL_NAME (callee), "as_const")))
2817 	  {
2818 	    r = CALL_EXPR_ARG (x, 0);
2819 	    /* Check that the return and argument types are sane before
2820 	       folding.  */
2821 	    if (INDIRECT_TYPE_P (TREE_TYPE (x))
2822 		&& INDIRECT_TYPE_P (TREE_TYPE (r)))
2823 	      {
2824 		if (!same_type_p (TREE_TYPE (x), TREE_TYPE (r)))
2825 		  r = build_nop (TREE_TYPE (x), r);
2826 		x = cp_fold (r);
2827 		break;
2828 	      }
2829 	  }
2830 
2831 	int sv = optimize, nw = sv;
2832 
2833 	/* Some built-in function calls will be evaluated at compile-time in
2834 	   fold ().  Set optimize to 1 when folding __builtin_constant_p inside
2835 	   a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
2836 	if (callee && fndecl_built_in_p (callee) && !optimize
2837 	    && DECL_IS_BUILTIN_CONSTANT_P (callee)
2838 	    && current_function_decl
2839 	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2840 	  nw = 1;
2841 
2842 	if (callee && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
2843 	  {
2844 	    switch (DECL_FE_FUNCTION_CODE (callee))
2845 	      {
2846 		/* Defer folding __builtin_is_constant_evaluated.  */
2847 	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
2848 		break;
2849 	      case CP_BUILT_IN_SOURCE_LOCATION:
2850 		x = fold_builtin_source_location (EXPR_LOCATION (x));
2851 		break;
2852 	      case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
2853 	        x = fold_builtin_is_corresponding_member
2854 			(EXPR_LOCATION (x), call_expr_nargs (x),
2855 			 &CALL_EXPR_ARG (x, 0));
2856 		break;
2857 	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
2858                 x = fold_builtin_is_pointer_inverconvertible_with_class
2859 			(EXPR_LOCATION (x), call_expr_nargs (x),
2860 			 &CALL_EXPR_ARG (x, 0));
2861 		break;
2862 	      default:
2863 		break;
2864 	      }
2865 	    break;
2866 	  }
2867 
2868 	if (callee
2869 	    && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
2870 				  BUILT_IN_FRONTEND))
2871 	  {
2872 	    x = fold_builtin_source_location (EXPR_LOCATION (x));
2873 	    break;
2874 	  }
2875 
2876 	bool changed = false;
2877 	int m = call_expr_nargs (x);
2878 	for (int i = 0; i < m; i++)
2879 	  {
2880 	    r = cp_fold (CALL_EXPR_ARG (x, i));
2881 	    if (r != CALL_EXPR_ARG (x, i))
2882 	      {
2883 		if (r == error_mark_node)
2884 		  {
2885 		    x = error_mark_node;
2886 		    break;
2887 		  }
2888 		if (!changed)
2889 		  x = copy_node (x);
2890 		CALL_EXPR_ARG (x, i) = r;
2891 		changed = true;
2892 	      }
2893 	  }
2894 	if (x == error_mark_node)
2895 	  break;
2896 
2897 	optimize = nw;
2898 	r = fold (x);
2899 	optimize = sv;
2900 
2901 	if (TREE_CODE (r) != CALL_EXPR)
2902 	  {
2903 	    x = cp_fold (r);
2904 	    break;
2905 	  }
2906 
2907 	optimize = nw;
2908 
2909 	/* Invoke maybe_constant_value for functions declared
2910 	   constexpr and not called with AGGR_INIT_EXPRs.
2911 	   TODO:
2912 	   Do constexpr expansion of expressions where the call itself is not
2913 	   constant, but the call followed by an INDIRECT_REF is.  */
2914 	if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
2915 	    && !flag_no_inline)
2916 	  r = maybe_constant_value (x);
2917 	optimize = sv;
2918 
2919         if (TREE_CODE (r) != CALL_EXPR)
2920 	  {
2921 	    if (DECL_CONSTRUCTOR_P (callee))
2922 	      {
2923 		loc = EXPR_LOCATION (x);
2924 		tree s = build_fold_indirect_ref_loc (loc,
2925 						      CALL_EXPR_ARG (x, 0));
2926 		r = build2_loc (loc, INIT_EXPR, TREE_TYPE (s), s, r);
2927 	      }
2928 	    x = r;
2929 	    break;
2930 	  }
2931 
2932 	break;
2933       }
2934 
2935     case CONSTRUCTOR:
2936       {
2937 	unsigned i;
2938 	constructor_elt *p;
2939 	vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
2940 	vec<constructor_elt, va_gc> *nelts = NULL;
2941 	FOR_EACH_VEC_SAFE_ELT (elts, i, p)
2942 	  {
2943 	    tree op = cp_fold (p->value);
2944 	    if (op != p->value)
2945 	      {
2946 		if (op == error_mark_node)
2947 		  {
2948 		    x = error_mark_node;
2949 		    vec_free (nelts);
2950 		    break;
2951 		  }
2952 		if (nelts == NULL)
2953 		  nelts = elts->copy ();
2954 		(*nelts)[i].value = op;
2955 	      }
2956 	  }
2957 	if (nelts)
2958 	  {
2959 	    x = build_constructor (TREE_TYPE (x), nelts);
2960 	    CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
2961 	      = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
2962 	  }
2963 	if (VECTOR_TYPE_P (TREE_TYPE (x)))
2964 	  x = fold (x);
2965 	break;
2966       }
2967     case TREE_VEC:
2968       {
2969 	bool changed = false;
2970 	int n = TREE_VEC_LENGTH (x);
2971 
2972 	for (int i = 0; i < n; i++)
2973 	  {
2974 	    tree op = cp_fold (TREE_VEC_ELT (x, i));
2975 	    if (op != TREE_VEC_ELT (x, i))
2976 	      {
2977 		if (!changed)
2978 		  x = copy_node (x);
2979 		TREE_VEC_ELT (x, i) = op;
2980 		changed = true;
2981 	      }
2982 	  }
2983       }
2984 
2985       break;
2986 
2987     case ARRAY_REF:
2988     case ARRAY_RANGE_REF:
2989 
2990       loc = EXPR_LOCATION (x);
2991       op0 = cp_fold (TREE_OPERAND (x, 0));
2992       op1 = cp_fold (TREE_OPERAND (x, 1));
2993       op2 = cp_fold (TREE_OPERAND (x, 2));
2994       op3 = cp_fold (TREE_OPERAND (x, 3));
2995 
2996       if (op0 != TREE_OPERAND (x, 0)
2997 	  || op1 != TREE_OPERAND (x, 1)
2998 	  || op2 != TREE_OPERAND (x, 2)
2999 	  || op3 != TREE_OPERAND (x, 3))
3000 	{
3001 	  if (op0 == error_mark_node
3002 	      || op1 == error_mark_node
3003 	      || op2 == error_mark_node
3004 	      || op3 == error_mark_node)
3005 	    x = error_mark_node;
3006 	  else
3007 	    {
3008 	      x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
3009 	      TREE_READONLY (x) = TREE_READONLY (org_x);
3010 	      TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
3011 	      TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3012 	    }
3013 	}
3014 
3015       x = fold (x);
3016       break;
3017 
3018     case SAVE_EXPR:
3019       /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
3020 	 folding, evaluates to an invariant.  In that case no need to wrap
3021 	 this folded tree with a SAVE_EXPR.  */
3022       r = cp_fold (TREE_OPERAND (x, 0));
3023       if (tree_invariant_p (r))
3024 	x = r;
3025       break;
3026 
3027     case REQUIRES_EXPR:
3028       x = evaluate_requires_expr (x);
3029       break;
3030 
3031     default:
3032       return org_x;
3033     }
3034 
3035   if (EXPR_P (x) && TREE_CODE (x) == code)
3036     {
3037       TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
3038       copy_warning (x, org_x);
3039     }
3040 
3041   if (!c.evaluation_restricted_p ())
3042     {
3043       fold_cache->put (org_x, x);
3044       /* Prevent that we try to fold an already folded result again.  */
3045       if (x != org_x)
3046 	fold_cache->put (x, x);
3047     }
3048 
3049   return x;
3050 }
3051 
3052 /* Look up either "hot" or "cold" in attribute list LIST.  */
3053 
3054 tree
lookup_hotness_attribute(tree list)3055 lookup_hotness_attribute (tree list)
3056 {
3057   for (; list; list = TREE_CHAIN (list))
3058     {
3059       tree name = get_attribute_name (list);
3060       if (is_attribute_p ("hot", name)
3061 	  || is_attribute_p ("cold", name)
3062 	  || is_attribute_p ("likely", name)
3063 	  || is_attribute_p ("unlikely", name))
3064 	break;
3065     }
3066   return list;
3067 }
3068 
3069 /* Remove both "hot" and "cold" attributes from LIST.  */
3070 
3071 static tree
remove_hotness_attribute(tree list)3072 remove_hotness_attribute (tree list)
3073 {
3074   list = remove_attribute ("hot", list);
3075   list = remove_attribute ("cold", list);
3076   list = remove_attribute ("likely", list);
3077   list = remove_attribute ("unlikely", list);
3078   return list;
3079 }
3080 
3081 /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
3082    PREDICT_EXPR.  */
3083 
3084 tree
process_stmt_hotness_attribute(tree std_attrs,location_t attrs_loc)3085 process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
3086 {
3087   if (std_attrs == error_mark_node)
3088     return std_attrs;
3089   if (tree attr = lookup_hotness_attribute (std_attrs))
3090     {
3091       tree name = get_attribute_name (attr);
3092       bool hot = (is_attribute_p ("hot", name)
3093 		  || is_attribute_p ("likely", name));
3094       tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
3095 				      hot ? TAKEN : NOT_TAKEN);
3096       SET_EXPR_LOCATION (pred, attrs_loc);
3097       add_stmt (pred);
3098       if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
3099 	warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
3100 		 get_attribute_name (other), name);
3101       std_attrs = remove_hotness_attribute (std_attrs);
3102     }
3103   return std_attrs;
3104 }
3105 
3106 /* Helper of fold_builtin_source_location, return the
3107    std::source_location::__impl type after performing verification
3108    on it.  LOC is used for reporting any errors.  */
3109 
3110 static tree
get_source_location_impl_type(location_t loc)3111 get_source_location_impl_type (location_t loc)
3112 {
3113   tree name = get_identifier ("source_location");
3114   tree decl = lookup_qualified_name (std_node, name);
3115   if (TREE_CODE (decl) != TYPE_DECL)
3116     {
3117       auto_diagnostic_group d;
3118       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
3119 	qualified_name_lookup_error (std_node, name, decl, loc);
3120       else
3121 	error_at (loc, "%qD is not a type", decl);
3122       return error_mark_node;
3123     }
3124   name = get_identifier ("__impl");
3125   tree type = TREE_TYPE (decl);
3126   decl = lookup_qualified_name (type, name);
3127   if (TREE_CODE (decl) != TYPE_DECL)
3128     {
3129       auto_diagnostic_group d;
3130       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
3131 	qualified_name_lookup_error (type, name, decl, loc);
3132       else
3133 	error_at (loc, "%qD is not a type", decl);
3134       return error_mark_node;
3135     }
3136   type = TREE_TYPE (decl);
3137   if (TREE_CODE (type) != RECORD_TYPE)
3138     {
3139       error_at (loc, "%qD is not a class type", decl);
3140       return error_mark_node;
3141     }
3142 
3143   int cnt = 0;
3144   for (tree field = TYPE_FIELDS (type);
3145        (field = next_initializable_field (field)) != NULL_TREE;
3146        field = DECL_CHAIN (field))
3147     {
3148       if (DECL_NAME (field) != NULL_TREE)
3149 	{
3150 	  const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
3151 	  if (strcmp (n, "_M_file_name") == 0
3152 	      || strcmp (n, "_M_function_name") == 0)
3153 	    {
3154 	      if (TREE_TYPE (field) != const_string_type_node)
3155 		{
3156 		  error_at (loc, "%qD does not have %<const char *%> type",
3157 			    field);
3158 		  return error_mark_node;
3159 		}
3160 	      cnt++;
3161 	      continue;
3162 	    }
3163 	  else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
3164 	    {
3165 	      if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
3166 		{
3167 		  error_at (loc, "%qD does not have integral type", field);
3168 		  return error_mark_node;
3169 		}
3170 	      cnt++;
3171 	      continue;
3172 	    }
3173 	}
3174       cnt = 0;
3175       break;
3176     }
3177   if (cnt != 4)
3178     {
3179       error_at (loc, "%<std::source_location::__impl%> does not contain only "
3180 		     "non-static data members %<_M_file_name%>, "
3181 		     "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
3182       return error_mark_node;
3183     }
3184   return build_qualified_type (type, TYPE_QUAL_CONST);
3185 }
3186 
3187 /* Type for source_location_table hash_set.  */
3188 struct GTY((for_user)) source_location_table_entry {
3189   location_t loc;
3190   unsigned uid;
3191   tree var;
3192 };
3193 
3194 /* Traits class for function start hash maps below.  */
3195 
3196 struct source_location_table_entry_hash
3197   : ggc_remove <source_location_table_entry>
3198 {
3199   typedef source_location_table_entry value_type;
3200   typedef source_location_table_entry compare_type;
3201 
3202   static hashval_t
hashsource_location_table_entry_hash3203   hash (const source_location_table_entry &ref)
3204   {
3205     inchash::hash hstate (0);
3206     hstate.add_int (ref.loc);
3207     hstate.add_int (ref.uid);
3208     return hstate.end ();
3209   }
3210 
3211   static bool
equalsource_location_table_entry_hash3212   equal (const source_location_table_entry &ref1,
3213 	 const source_location_table_entry &ref2)
3214   {
3215     return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
3216   }
3217 
3218   static void
mark_deletedsource_location_table_entry_hash3219   mark_deleted (source_location_table_entry &ref)
3220   {
3221     ref.loc = UNKNOWN_LOCATION;
3222     ref.uid = -1U;
3223     ref.var = NULL_TREE;
3224   }
3225 
3226   static const bool empty_zero_p = true;
3227 
3228   static void
mark_emptysource_location_table_entry_hash3229   mark_empty (source_location_table_entry &ref)
3230   {
3231     ref.loc = UNKNOWN_LOCATION;
3232     ref.uid = 0;
3233     ref.var = NULL_TREE;
3234   }
3235 
3236   static bool
is_deletedsource_location_table_entry_hash3237   is_deleted (const source_location_table_entry &ref)
3238   {
3239     return (ref.loc == UNKNOWN_LOCATION
3240 	    && ref.uid == -1U
3241 	    && ref.var == NULL_TREE);
3242   }
3243 
3244   static bool
is_emptysource_location_table_entry_hash3245   is_empty (const source_location_table_entry &ref)
3246   {
3247     return (ref.loc == UNKNOWN_LOCATION
3248 	    && ref.uid == 0
3249 	    && ref.var == NULL_TREE);
3250   }
3251 
3252   static void
pch_nxsource_location_table_entry_hash3253   pch_nx (source_location_table_entry &p)
3254   {
3255     extern void gt_pch_nx (source_location_table_entry &);
3256     gt_pch_nx (p);
3257   }
3258 
3259   static void
pch_nxsource_location_table_entry_hash3260   pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
3261   {
3262     extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
3263 			   void *);
3264     gt_pch_nx (&p, op, cookie);
3265   }
3266 };
3267 
3268 static GTY(()) hash_table <source_location_table_entry_hash>
3269   *source_location_table;
3270 static GTY(()) unsigned int source_location_id;
3271 
3272 /* Fold __builtin_source_location () call.  LOC is the location
3273    of the call.  */
3274 
3275 tree
fold_builtin_source_location(location_t loc)3276 fold_builtin_source_location (location_t loc)
3277 {
3278   if (source_location_impl == NULL_TREE)
3279     {
3280       auto_diagnostic_group d;
3281       source_location_impl = get_source_location_impl_type (loc);
3282       if (source_location_impl == error_mark_node)
3283 	inform (loc, "evaluating %qs", "__builtin_source_location");
3284     }
3285   if (source_location_impl == error_mark_node)
3286     return build_zero_cst (const_ptr_type_node);
3287   if (source_location_table == NULL)
3288     source_location_table
3289       = hash_table <source_location_table_entry_hash>::create_ggc (64);
3290   const line_map_ordinary *map;
3291   source_location_table_entry entry;
3292   entry.loc
3293     = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
3294 				&map);
3295   entry.uid = current_function_decl ? DECL_UID (current_function_decl) : -1;
3296   entry.var = error_mark_node;
3297   source_location_table_entry *entryp
3298     = source_location_table->find_slot (entry, INSERT);
3299   tree var;
3300   if (entryp->var)
3301     var = entryp->var;
3302   else
3303     {
3304       char tmp_name[32];
3305       ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lsrc_loc", source_location_id++);
3306       var = build_decl (loc, VAR_DECL, get_identifier (tmp_name),
3307 			source_location_impl);
3308       TREE_STATIC (var) = 1;
3309       TREE_PUBLIC (var) = 0;
3310       DECL_ARTIFICIAL (var) = 1;
3311       DECL_IGNORED_P (var) = 1;
3312       DECL_EXTERNAL (var) = 0;
3313       DECL_DECLARED_CONSTEXPR_P (var) = 1;
3314       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
3315       layout_decl (var, 0);
3316 
3317       vec<constructor_elt, va_gc> *v = NULL;
3318       vec_alloc (v, 4);
3319       for (tree field = TYPE_FIELDS (source_location_impl);
3320 	   (field = next_initializable_field (field)) != NULL_TREE;
3321 	   field = DECL_CHAIN (field))
3322 	{
3323 	  const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
3324 	  tree val = NULL_TREE;
3325 	  if (strcmp (n, "_M_file_name") == 0)
3326 	    {
3327 	      if (const char *fname = LOCATION_FILE (loc))
3328 		{
3329 		  fname = remap_macro_filename (fname);
3330 		  val = build_string_literal (strlen (fname) + 1, fname);
3331 		}
3332 	      else
3333 		val = build_string_literal (1, "");
3334 	    }
3335 	  else if (strcmp (n, "_M_function_name") == 0)
3336 	    {
3337 	      const char *name = "";
3338 
3339 	      if (current_function_decl)
3340 		name = cxx_printable_name (current_function_decl, 2);
3341 
3342 	      val = build_string_literal (strlen (name) + 1, name);
3343 	    }
3344 	  else if (strcmp (n, "_M_line") == 0)
3345 	    val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
3346 	  else if (strcmp (n, "_M_column") == 0)
3347 	    val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
3348 	  else
3349 	    gcc_unreachable ();
3350 	  CONSTRUCTOR_APPEND_ELT (v, field, val);
3351 	}
3352 
3353       tree ctor = build_constructor (source_location_impl, v);
3354       TREE_CONSTANT (ctor) = 1;
3355       TREE_STATIC (ctor) = 1;
3356       DECL_INITIAL (var) = ctor;
3357       varpool_node::finalize_decl (var);
3358       *entryp = entry;
3359       entryp->var = var;
3360     }
3361 
3362   return build_fold_addr_expr_with_type_loc (loc, var, const_ptr_type_node);
3363 }
3364 
3365 #include "gt-cp-cp-gimplify.h"
3366