initializer_list: Decorate with constexpr.
[platform/upstream/gcc.git] / gcc / gimplify.c
index e5b011a..885f013 100644 (file)
@@ -587,10 +587,7 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
 
   mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
 
-  if (EXPR_HAS_LOCATION (val))
-    SET_EXPR_LOCATION (mod, EXPR_LOCATION (val));
-  else
-    SET_EXPR_LOCATION (mod, input_location);
+  SET_EXPR_LOCATION (mod, EXPR_LOC_OR_HERE (val));
 
   /* gimplify_modify_expr might want to reduce this further.  */
   gimplify_and_add (mod, pre_p);
@@ -1372,6 +1369,14 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
                                   STACK_CHECK_MAX_VAR_SIZE) > 0))
        gimplify_vla_decl (decl, seq_p);
 
+      /* Some front ends do not explicitly declare all anonymous
+        artificial variables.  We compensate here by declaring the
+        variables, though it would be better if the front ends would
+        explicitly declare them.  */
+      if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
+         && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+       gimple_add_tmp_var (decl);
+
       if (init && init != error_mark_node)
        {
          if (!TREE_STATIC (decl))
@@ -1386,14 +1391,6 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p)
               as they may contain a label address.  */
            walk_tree (&init, force_labels_r, NULL, NULL);
        }
-
-      /* Some front ends do not explicitly declare all anonymous
-        artificial variables.  We compensate here by declaring the
-        variables, though it would be better if the front ends would
-        explicitly declare them.  */
-      if (!DECL_SEEN_IN_BIND_EXPR_P (decl)
-         && DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
-       gimple_add_tmp_var (decl);
     }
 
   return GS_ALL_DONE;
@@ -1476,9 +1473,7 @@ compare_case_labels (const void *p1, const void *p2)
 void
 sort_case_labels (VEC(tree,heap)* label_vec)
 {
-  size_t len = VEC_length (tree, label_vec);
-  qsort (VEC_address (tree, label_vec), len, sizeof (tree),
-         compare_case_labels);
+  VEC_qsort (tree, label_vec, compare_case_labels);
 }
 
 
@@ -2622,8 +2617,7 @@ shortcut_cond_expr (tree expr)
       while (TREE_CODE (pred) == TRUTH_ANDIF_EXPR)
        {
          /* Keep the original source location on the first 'if'.  */
-         location_t locus = EXPR_HAS_LOCATION (expr)
-                            ? EXPR_LOCATION (expr) : input_location;
+         location_t locus = EXPR_LOC_OR_HERE (expr);
          TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
          /* Set the source location of the && on the second 'if'.  */
          if (EXPR_HAS_LOCATION (pred))
@@ -2645,8 +2639,7 @@ shortcut_cond_expr (tree expr)
       while (TREE_CODE (pred) == TRUTH_ORIF_EXPR)
        {
          /* Keep the original source location on the first 'if'.  */
-         location_t locus = EXPR_HAS_LOCATION (expr)
-                            ? EXPR_LOCATION (expr) : input_location;
+         location_t locus = EXPR_LOC_OR_HERE (expr);
          TREE_OPERAND (expr, 0) = TREE_OPERAND (pred, 1);
          /* Set the source location of the || on the second 'if'.  */
          if (EXPR_HAS_LOCATION (pred))
@@ -2710,8 +2703,7 @@ shortcut_cond_expr (tree expr)
   /* If there was nothing else in our arms, just forward the label(s).  */
   if (!then_se && !else_se)
     return shortcut_cond_r (pred, true_label_p, false_label_p,
-                           EXPR_HAS_LOCATION (expr)
-                           ? EXPR_LOCATION (expr) : input_location);
+                           EXPR_LOC_OR_HERE (expr));
 
   /* If our last subexpression already has a terminal label, reuse it.  */
   if (else_se)
@@ -2743,8 +2735,7 @@ shortcut_cond_expr (tree expr)
   jump_over_else = block_may_fallthru (then_);
 
   pred = shortcut_cond_r (pred, true_label_p, false_label_p,
-                         EXPR_HAS_LOCATION (expr)
-                         ? EXPR_LOCATION (expr) : input_location);
+                         EXPR_LOC_OR_HERE (expr));
 
   expr = NULL;
   append_to_statement_list (pred, &expr);
@@ -4200,9 +4191,18 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
             This kind of code arises in C++ when an object is bound
             to a const reference, and if "x" is a TARGET_EXPR we want
             to take advantage of the optimization below.  */
+           bool volatile_p = TREE_THIS_VOLATILE (*from_p);
            tree t = gimple_fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
            if (t)
              {
+               if (TREE_THIS_VOLATILE (t) != volatile_p)
+                 {
+                   if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
+                     t = build_simple_mem_ref_loc (EXPR_LOCATION (*from_p),
+                                                   build_fold_addr_expr (t));
+                   if (REFERENCE_CLASS_P (t))
+                     TREE_THIS_VOLATILE (t) = volatile_p;
+                 }
                *from_p = t;
                ret = GS_OK;
                changed = true;
@@ -4627,10 +4627,10 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 static enum gimplify_status
 gimplify_variable_sized_compare (tree *expr_p)
 {
+  location_t loc = EXPR_LOCATION (*expr_p);
   tree op0 = TREE_OPERAND (*expr_p, 0);
   tree op1 = TREE_OPERAND (*expr_p, 1);
-  tree t, arg, dest, src;
-  location_t loc = EXPR_LOCATION (*expr_p);
+  tree t, arg, dest, src, expr;
 
   arg = TYPE_SIZE_UNIT (TREE_TYPE (op0));
   arg = unshare_expr (arg);
@@ -4639,8 +4639,11 @@ gimplify_variable_sized_compare (tree *expr_p)
   dest = build_fold_addr_expr_loc (loc, op0);
   t = implicit_built_in_decls[BUILT_IN_MEMCMP];
   t = build_call_expr_loc (loc, t, 3, dest, src, arg);
-  *expr_p
+
+  expr
     = build2 (TREE_CODE (*expr_p), TREE_TYPE (*expr_p), t, integer_zero_node);
+  SET_EXPR_LOCATION (expr, loc);
+  *expr_p = expr;
 
   return GS_OK;
 }
@@ -6789,6 +6792,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
        case INDIRECT_REF:
          {
            bool volatilep = TREE_THIS_VOLATILE (*expr_p);
+           bool notrap = TREE_THIS_NOTRAP (*expr_p);
            tree saved_ptr_type = TREE_TYPE (TREE_OPERAND (*expr_p, 0));
 
            *expr_p = fold_indirect_ref_loc (input_location, *expr_p);
@@ -6800,13 +6804,16 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
 
            ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
                                 is_gimple_reg, fb_rvalue);
-           recalculate_side_effects (*expr_p);
+           if (ret == GS_ERROR)
+             break;
 
+           recalculate_side_effects (*expr_p);
            *expr_p = fold_build2_loc (input_location, MEM_REF,
                                       TREE_TYPE (*expr_p),
                                       TREE_OPERAND (*expr_p, 0),
                                       build_int_cst (saved_ptr_type, 0));
            TREE_THIS_VOLATILE (*expr_p) = volatilep;
+           TREE_THIS_NOTRAP (*expr_p) = notrap;
            ret = GS_OK;
            break;
          }
@@ -6826,6 +6833,8 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
            }
          ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
                               is_gimple_mem_ref_addr, fb_rvalue);
+         if (ret == GS_ERROR)
+           break;
          recalculate_side_effects (*expr_p);
          ret = GS_ALL_DONE;
          break;
@@ -7522,7 +7531,10 @@ gimplify_type_sizes (tree type, gimple_seq *list_p)
       /* Ensure VLA bounds aren't removed, for -O0 they should be variables
         with assigned stack slots, for -O1+ -g they should be tracked
         by VTA.  */
-      if (TYPE_DOMAIN (type)
+      if (!(TYPE_NAME (type)
+           && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
+           && DECL_IGNORED_P (TYPE_NAME (type)))
+         && TYPE_DOMAIN (type)
          && INTEGRAL_TYPE_P (TYPE_DOMAIN (type)))
        {
          t = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
@@ -7619,10 +7631,7 @@ gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
       *expr_p = create_tmp_var (type, NULL);
       tmp = build1 (NOP_EXPR, type, expr);
       stmt = gimplify_assign (*expr_p, tmp, stmt_p);
-      if (EXPR_HAS_LOCATION (expr))
-       gimple_set_location (stmt, EXPR_LOCATION (expr));
-      else
-       gimple_set_location (stmt, input_location);
+      gimple_set_location (stmt, EXPR_LOC_OR_HERE (expr));
     }
 }