OSDN Git Service

boehm-gc:
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 0ea18b2..2d96bd7 100644 (file)
@@ -3128,7 +3128,16 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
 
-  side_effects = TREE_SIDE_EFFECTS (t);
+  /* As a special exception, if COND_EXPR has NULL branches, we
+     assume that it is a gimple statement and always consider
+     it to have side effects.  */
+  if (code == COND_EXPR
+      && tt == void_type_node
+      && arg1 == NULL_TREE
+      && arg2 == NULL_TREE)
+    side_effects = true;
+  else
+    side_effects = TREE_SIDE_EFFECTS (t);
 
   PROCESS_ARG(0);
   PROCESS_ARG(1);
@@ -4164,7 +4173,11 @@ build_distinct_type_copy (tree type)
   /* Make it its own variant.  */
   TYPE_MAIN_VARIANT (t) = t;
   TYPE_NEXT_VARIANT (t) = 0;
-  
+
+  /* Note that it is now possible for TYPE_MIN_VALUE to be a value
+     whose TREE_TYPE is not t.  This can also happen in the Ada
+     frontend when using subtypes.  */
+
   return t;
 }
 
@@ -6120,6 +6133,47 @@ int_fits_type_p (tree c, tree type)
   return !fit_double_type (low, high, &low, &high, type);
 }
 
+/* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
+   bounds or is a POINTER_TYPE, the maximum and/or minimum values that can be
+   represented (assuming two's-complement arithmetic) within the bit
+   precision of the type are returned instead.  */
+
+void
+get_type_static_bounds (tree type, mpz_t min, mpz_t max)
+{
+  if (!POINTER_TYPE_P (type) && TYPE_MIN_VALUE (type)
+      && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (min, tree_to_double_int (TYPE_MIN_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_ui (min, 0);
+      else
+       {
+         double_int mn;
+         mn = double_int_mask (TYPE_PRECISION (type) - 1);
+         mn = double_int_sext (double_int_add (mn, double_int_one),
+                               TYPE_PRECISION (type));
+         mpz_set_double_int (min, mn, false);
+       }
+    }
+
+  if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type) 
+      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (max, tree_to_double_int (TYPE_MAX_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type)),
+                           true);
+      else
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type) - 1),
+                           true);
+    }
+}
+
 /* Subprogram of following function.  Called by walk_tree.
 
    Return *TP if it is an automatic variable or parameter of the
@@ -7218,11 +7272,18 @@ tree
 reconstruct_complex_type (tree type, tree bottom)
 {
   tree inner, outer;
-
-  if (POINTER_TYPE_P (type))
+  
+  if (TREE_CODE (type) == POINTER_TYPE)
     {
       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
-      outer = build_pointer_type (inner);
+      outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
+                                          TYPE_REF_CAN_ALIAS_ALL (type));
+    }
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
+                                            TYPE_REF_CAN_ALIAS_ALL (type));
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -7670,14 +7731,22 @@ int_cst_value (tree x)
 }
 
 
+/* Return an unsigned type the same as TYPE in other respects.  */
+
+static tree
+get_unsigned_type (tree type)
+{
+  return get_signed_or_unsigned_type (1, type);
+}
+
 /* Returns unsigned variant of TYPE.  */
 
 tree
 unsigned_type_for (tree type)
 {
   if (POINTER_TYPE_P (type))
-    return lang_hooks.types.unsigned_type (size_type_node);
-  return lang_hooks.types.unsigned_type (type);
+    return get_unsigned_type (size_type_node);
+  return get_unsigned_type (type);
 }
 
 /* Returns signed variant of TYPE.  */