OSDN Git Service

Fix PR c++/42260 and ensure PR c++/45383 is fixed
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index d068a7e..2f8d96e 100644 (file)
@@ -1178,6 +1178,10 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
 
   switch (TREE_CODE (type))
     {
+    case NULLPTR_TYPE:
+      gcc_assert (hi == 0 && low == 0);
+      /* Fallthru.  */
+
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       /* Cache NULL pointer.  */
@@ -1358,10 +1362,33 @@ build_vector_from_ctor (tree type, VEC(constructor_elt,gc) *v)
     list = tree_cons (NULL_TREE, value, list);
   for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
     list = tree_cons (NULL_TREE,
-                     fold_convert (TREE_TYPE (type), integer_zero_node), list);
+                     build_zero_cst (TREE_TYPE (type)), list);
   return build_vector (type, nreverse (list));
 }
 
+/* Build a vector of type VECTYPE where all the elements are SCs.  */
+tree
+build_vector_from_val (tree vectype, tree sc) 
+{
+  int i, nunits = TYPE_VECTOR_SUBPARTS (vectype);
+  VEC(constructor_elt, gc) *v = NULL;
+
+  if (sc == error_mark_node)
+    return sc;
+
+  gcc_assert (useless_type_conversion_p (TREE_TYPE (sc),
+                                        TREE_TYPE (vectype)));
+
+  v = VEC_alloc (constructor_elt, gc, nunits);
+  for (i = 0; i < nunits; ++i)
+    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, sc);
+
+  if (CONSTANT_CLASS_P (sc))
+    return build_vector_from_ctor (vectype, v);
+  else 
+    return build_constructor (vectype, v);
+}
+
 /* Return a new CONSTRUCTOR node whose type is TYPE and whose values
    are in the VEC pointed to by VALS.  */
 tree
@@ -1564,38 +1591,60 @@ build_one_cst (tree type)
 
     case VECTOR_TYPE:
       {
-       tree scalar, cst;
-       int i;
-
-       scalar = build_one_cst (TREE_TYPE (type));
-
-       /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
-       cst = NULL_TREE;
-       for (i = TYPE_VECTOR_SUBPARTS (type); --i >= 0; )
-         cst = tree_cons (NULL_TREE, scalar, cst);
+       tree scalar = build_one_cst (TREE_TYPE (type));
 
-       return build_vector (type, cst);
+       return build_vector_from_val (type, scalar);
       }
 
     case COMPLEX_TYPE:
       return build_complex (type,
                            build_one_cst (TREE_TYPE (type)),
-                           fold_convert (TREE_TYPE (type), integer_zero_node));
+                           build_zero_cst (TREE_TYPE (type)));
 
     default:
       gcc_unreachable ();
     }
 }
 
-/* Build 0 constant of type TYPE.  This is used by constructor folding and thus
-   the constant should correspond zero in memory representation.  */
+/* Build 0 constant of type TYPE.  This is used by constructor folding
+   and thus the constant should be represented in memory by
+   zero(es).  */
 
 tree
 build_zero_cst (tree type)
 {
-  if (!AGGREGATE_TYPE_P (type))
-    return fold_convert (type, integer_zero_node);
-  return build_constructor (type, NULL);
+  switch (TREE_CODE (type))
+    {
+    case INTEGER_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE:
+    case POINTER_TYPE: case REFERENCE_TYPE:
+    case OFFSET_TYPE:
+      return build_int_cst (type, 0);
+
+    case REAL_TYPE:
+      return build_real (type, dconst0);
+
+    case FIXED_POINT_TYPE:
+      return build_fixed (type, FCONST0 (TYPE_MODE (type)));
+
+    case VECTOR_TYPE:
+      {
+       tree scalar = build_zero_cst (TREE_TYPE (type));
+
+       return build_vector_from_val (type, scalar);
+      }
+
+    case COMPLEX_TYPE:
+      {
+       tree zero = build_zero_cst (TREE_TYPE (type));
+
+       return build_complex (type, zero, zero);
+      }
+
+    default:
+      if (!AGGREGATE_TYPE_P (type))
+       return fold_convert (type, integer_zero_node);
+      return build_constructor (type, NULL);
+    }
 }
 
 
@@ -2746,8 +2795,8 @@ process_call_operands (tree t)
   TREE_READONLY (t) = read_only;
 }
 \f
-/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
-   or offset that depends on a field within a record.  */
+/* Return true if EXP contains a PLACEHOLDER_EXPR, i.e. if it represents a
+   size or offset that depends on a field within a record.  */
 
 bool
 contains_placeholder_p (const_tree exp)
@@ -2833,9 +2882,9 @@ contains_placeholder_p (const_tree exp)
   return 0;
 }
 
-/* Return true if any part of the computation of TYPE involves a
-   PLACEHOLDER_EXPR.  This includes size, bounds, qualifiers
-   (for QUAL_UNION_TYPE) and field positions.  */
+/* Return true if any part of the structure of TYPE involves a PLACEHOLDER_EXPR
+   directly.  This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and
+   field positions.  */
 
 static bool
 type_contains_placeholder_1 (const_tree type)
@@ -2844,7 +2893,8 @@ type_contains_placeholder_1 (const_tree type)
      the case of arrays) type involves a placeholder, this type does.  */
   if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
       || CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
-      || (TREE_TYPE (type) != 0
+      || (!POINTER_TYPE_P (type)
+         && TREE_TYPE (type)
          && type_contains_placeholder_p (TREE_TYPE (type))))
     return true;
 
@@ -2872,8 +2922,8 @@ type_contains_placeholder_1 (const_tree type)
              || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
 
     case ARRAY_TYPE:
-      /* We're already checked the component type (TREE_TYPE), so just check
-        the index type.  */
+      /* We have already checked the component type above, so just check the
+        domain type.  */
       return type_contains_placeholder_p (TYPE_DOMAIN (type));
 
     case RECORD_TYPE:
@@ -2898,6 +2948,8 @@ type_contains_placeholder_1 (const_tree type)
     }
 }
 
+/* Wrapper around above function used to cache its result.  */
+
 bool
 type_contains_placeholder_p (tree type)
 {
@@ -3186,6 +3238,10 @@ substitute_in_expr (tree exp, tree f, tree r)
       }
 
   TREE_READONLY (new_tree) |= TREE_READONLY (exp);
+
+  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
+    TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
+
   return new_tree;
 }
 
@@ -3353,6 +3409,10 @@ substitute_placeholder_in_expr (tree exp, tree obj)
       }
 
   TREE_READONLY (new_tree) |= TREE_READONLY (exp);
+
+  if (code == INDIRECT_REF || code == ARRAY_REF || code == ARRAY_RANGE_REF)
+    TREE_THIS_NOTRAP (new_tree) |= TREE_THIS_NOTRAP (exp);
+
   return new_tree;
 }
 \f
@@ -4466,22 +4526,6 @@ free_lang_data_in_decl (tree decl)
   if (DECL_NAME (decl))
     TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
 
- if (TREE_CODE (decl) == VAR_DECL)
-   {
-     tree context = DECL_CONTEXT (decl);
-
-     if (context)
-       {
-        enum tree_code code = TREE_CODE (context);
-        if (code == FUNCTION_DECL && DECL_ABSTRACT (context))
-          {
-            /* Do not clear the decl context here, that will promote
-               all vars to global ones.  */
-            DECL_INITIAL (decl) = NULL_TREE;
-          }
-       }
-   }
-
   free_lang_data_in_one_sizepos (&DECL_SIZE (decl));
   free_lang_data_in_one_sizepos (&DECL_SIZE_UNIT (decl));
   if (TREE_CODE (decl) == FIELD_DECL)
@@ -4514,11 +4558,21 @@ free_lang_data_in_decl (tree decl)
       /* DECL_SAVED_TREE holds the GENERIC representation for DECL.
         At this point, it is not needed anymore.  */
       DECL_SAVED_TREE (decl) = NULL_TREE;
+
+      /* Clear the abstract origin if it refers to a method.  Otherwise
+         dwarf2out.c will ICE as we clear TYPE_METHODS and thus the
+        origin will not be output correctly.  */
+      if (DECL_ABSTRACT_ORIGIN (decl)
+         && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))
+         && RECORD_OR_UNION_TYPE_P
+              (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl))))
+       DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     {
-      if (DECL_EXTERNAL (decl)
-         && (!TREE_STATIC (decl) || !TREE_READONLY (decl)))
+      if ((DECL_EXTERNAL (decl)
+          && (!TREE_STATIC (decl) || !TREE_READONLY (decl)))
+         || (decl_function_context (decl) && !TREE_STATIC (decl)))
        DECL_INITIAL (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == TYPE_DECL)
@@ -4982,7 +5036,7 @@ free_lang_data_in_cgraph (void)
     find_decls_types (p->decl, &fld);
 
   /* Find decls and types in every varpool symbol.  */
-  for (v = varpool_nodes_queue; v; v = v->next_needed)
+  for (v = varpool_nodes; v; v = v->next)
     find_decls_types_in_var (v, &fld);
 
   /* Set the assembler name on every decl found.  We need to do this
@@ -9289,7 +9343,8 @@ build_common_builtin_nodes (void)
   ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
   local_define_builtin ("__builtin_unwind_resume", ftype,
                        BUILT_IN_UNWIND_RESUME,
-                       (targetm.except_unwind_info () == UI_SJLJ
+                       ((targetm.except_unwind_info (&global_options)
+                         == UI_SJLJ)
                         ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"),
                        ECF_NORETURN);
 
@@ -10874,11 +10929,7 @@ tree
 lhd_gcc_personality (void)
 {
   if (!gcc_eh_personality_decl)
-    gcc_eh_personality_decl
-      = build_personality_function (targetm.except_unwind_info () == UI_SJLJ
-                                   ? "__gcc_personality_sj0"
-                                   : "__gcc_personality_v0");
-
+    gcc_eh_personality_decl = build_personality_function ("gcc");
   return gcc_eh_personality_decl;
 }
 
@@ -10889,20 +10940,18 @@ lhd_gcc_personality (void)
 tree
 get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
 {
-  tree type;
-
-  if (offset == 0)
-    return binfo;
+  tree type = TREE_TYPE (binfo);
 
-  type = TREE_TYPE (binfo);
-  while (offset > 0)
+  while (true)
     {
-      tree base_binfo, found_binfo;
       HOST_WIDE_INT pos, size;
       tree fld;
       int i;
 
-      if (TREE_CODE (type) != RECORD_TYPE)
+      if (type == expected_type)
+         return binfo;
+      if (TREE_CODE (type) != RECORD_TYPE
+         || offset < 0)
        return NULL_TREE;
 
       for (fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
@@ -10915,27 +10964,28 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
          if (pos <= offset && (pos + size) > offset)
            break;
        }
-      if (!fld)
+      if (!fld || !DECL_ARTIFICIAL (fld))
        return NULL_TREE;
 
-      found_binfo = NULL_TREE;
-      for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
-       if (TREE_TYPE (base_binfo) == TREE_TYPE (fld))
-         {
-           found_binfo = base_binfo;
-           break;
-         }
-
-      if (!found_binfo)
-       return NULL_TREE;
+      /* Offset 0 indicates the primary base, whose vtable contents are
+        represented in the binfo for the derived class.  */
+      if (offset != 0)
+       {
+         tree base_binfo, found_binfo = NULL_TREE;
+         for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+           if (TREE_TYPE (base_binfo) == TREE_TYPE (fld))
+             {
+               found_binfo = base_binfo;
+               break;
+             }
+         if (!found_binfo)
+           return NULL_TREE;
+         binfo = found_binfo;
+       }
 
       type = TREE_TYPE (fld);
-      binfo = found_binfo;
       offset -= pos;
     }
-  if (type != expected_type)
-    return NULL_TREE;
-  return binfo;
 }
 
 /* Returns true if X is a typedef decl.  */