OSDN Git Service

* Make-lang.in (stmp-f2c.h): Don't configure the runtime
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index a79c1c6..6812aa4 100644 (file)
@@ -1,5 +1,5 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
-   Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -47,6 +47,14 @@ Boston, MA 02111-1307, USA.  */
 #endif
 #include <stdio.h>
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_DECLARATION_FREE
+extern void free PROTO((void *));
+#endif
+
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
@@ -696,6 +704,16 @@ savealloc (size)
 {
   return (char *) obstack_alloc (saveable_obstack, size);
 }
+
+/* Allocate SIZE bytes in the expression obstack
+   and return a pointer to them.  */
+
+char *
+expralloc (size)
+     int size;
+{
+  return (char *) obstack_alloc (expression_obstack, size);
+}
 \f
 /* Print out which obstack an object is in.  */
 
@@ -1157,6 +1175,7 @@ copy_node (node)
     ((char *) t)[i] = ((char *) node)[i];
 
   TREE_CHAIN (t) = 0;
+  TREE_ASM_WRITTEN (t) = 0;
 
   if (TREE_CODE_CLASS (code) == 'd')
     DECL_UID (t) = next_decl_uid++;
@@ -1268,6 +1287,45 @@ get_identifier (text)
   return idp;                  /* <-- return if created */
 }
 
+/* If an identifier with the name TEXT (a null-terminated string) has
+   previously been referred to, return that node; otherwise return
+   NULL_TREE.  */
+
+tree
+maybe_get_identifier (text)
+     register char *text;
+{
+  register int hi;
+  register int i;
+  register tree idp;
+  register int len, hash_len;
+
+  /* Compute length of text in len.  */
+  for (len = 0; text[len]; len++);
+
+  /* Decide how much of that length to hash on */
+  hash_len = len;
+  if (warn_id_clash && len > id_clash_len)
+    hash_len = id_clash_len;
+
+  /* Compute hash code */
+  hi = hash_len * 613 + (unsigned) text[0];
+  for (i = 1; i < hash_len; i += 2)
+    hi = ((hi * 613) + (unsigned) (text[i]));
+
+  hi &= (1 << HASHBITS) - 1;
+  hi %= MAX_HASH_TABLE;
+  
+  /* Search table for identifier */
+  for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp))
+    if (IDENTIFIER_LENGTH (idp) == len
+       && IDENTIFIER_POINTER (idp)[0] == text[0]
+       && !bcmp (IDENTIFIER_POINTER (idp), text, len))
+      return idp;              /* <-- return if found */
+
+  return NULL_TREE;
+}
+
 /* Enable warnings on similar identifiers (if requested).
    Done after the built-in identifiers are created.  */
 
@@ -1444,18 +1502,19 @@ build_string (len, str)
 
 /* Return a newly constructed COMPLEX_CST node whose value is
    specified by the real and imaginary parts REAL and IMAG.
-   Both REAL and IMAG should be constant nodes.
-   The TREE_TYPE is not initialized.  */
+   Both REAL and IMAG should be constant nodes.  TYPE, if specified,
+   will be the type of the COMPLEX_CST; otherwise a new type will be made.  */
 
 tree
-build_complex (real, imag)
+build_complex (type, real, imag)
+     tree type;
      tree real, imag;
 {
   register tree t = make_node (COMPLEX_CST);
 
   TREE_REALPART (t) = real;
   TREE_IMAGPART (t) = imag;
-  TREE_TYPE (t) = build_complex_type (TREE_TYPE (real));
+  TREE_TYPE (t) = type ? type : build_complex_type (TREE_TYPE (real));
   TREE_OVERFLOW (t) = TREE_OVERFLOW (real) | TREE_OVERFLOW (imag);
   TREE_CONSTANT_OVERFLOW (t)
     = TREE_CONSTANT_OVERFLOW (real) | TREE_CONSTANT_OVERFLOW (imag);
@@ -1501,6 +1560,7 @@ integer_zerop (expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
           && TREE_INT_CST_LOW (expr) == 0
           && TREE_INT_CST_HIGH (expr) == 0)
          || (TREE_CODE (expr) == COMPLEX_CST
@@ -1518,6 +1578,7 @@ integer_onep (expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
           && TREE_INT_CST_LOW (expr) == 1
           && TREE_INT_CST_HIGH (expr) == 0)
          || (TREE_CODE (expr) == COMPLEX_CST
@@ -1542,7 +1603,8 @@ integer_all_onesp (expr)
       && integer_zerop (TREE_IMAGPART (expr)))
     return 1;
 
-  else if (TREE_CODE (expr) != INTEGER_CST)
+  else if (TREE_CODE (expr) != INTEGER_CST
+          || TREE_CONSTANT_OVERFLOW (expr))
     return 0;
 
   uns = TREE_UNSIGNED (TREE_TYPE (expr));
@@ -1582,6 +1644,7 @@ int
 integer_pow2p (expr)
      tree expr;
 {
+  int prec;
   HOST_WIDE_INT high, low;
 
   STRIP_NOPS (expr);
@@ -1591,12 +1654,28 @@ integer_pow2p (expr)
       && integer_zerop (TREE_IMAGPART (expr)))
     return 1;
 
-  if (TREE_CODE (expr) != INTEGER_CST)
+  if (TREE_CODE (expr) != INTEGER_CST || TREE_CONSTANT_OVERFLOW (expr))
     return 0;
 
+  prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
+         ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
   high = TREE_INT_CST_HIGH (expr);
   low = TREE_INT_CST_LOW (expr);
 
+  /* First clear all bits that are beyond the type's precision in case
+     we've been sign extended.  */
+
+  if (prec == 2 * HOST_BITS_PER_WIDE_INT)
+    ;
+  else if (prec > HOST_BITS_PER_WIDE_INT)
+    high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+  else
+    {
+      high = 0;
+      if (prec < HOST_BITS_PER_WIDE_INT)
+       low &= ~((HOST_WIDE_INT) (-1) << prec);
+    }
+
   if (high == 0 && low == 0)
     return 0;
 
@@ -1604,6 +1683,45 @@ integer_pow2p (expr)
          || (low == 0 && (high & (high - 1)) == 0));
 }
 
+/* Return the power of two represented by a tree node known to be a
+   power of two.  */
+
+int
+tree_log2 (expr)
+     tree expr;
+{
+  int prec;
+  HOST_WIDE_INT high, low;
+
+  STRIP_NOPS (expr);
+
+  if (TREE_CODE (expr) == COMPLEX_CST)
+    return tree_log2 (TREE_REALPART (expr));
+
+  prec = (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
+         ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr)));
+
+  high = TREE_INT_CST_HIGH (expr);
+  low = TREE_INT_CST_LOW (expr);
+
+  /* First clear all bits that are beyond the type's precision in case
+     we've been sign extended.  */
+
+  if (prec == 2 * HOST_BITS_PER_WIDE_INT)
+    ;
+  else if (prec > HOST_BITS_PER_WIDE_INT)
+    high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+  else
+    {
+      high = 0;
+      if (prec < HOST_BITS_PER_WIDE_INT)
+       low &= ~((HOST_WIDE_INT) (-1) << prec);
+    }
+
+  return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
+         :  exact_log2 (low));
+}
+
 /* Return 1 if EXPR is the real constant zero.  */
 
 int
@@ -1613,6 +1731,7 @@ real_zerop (expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst0))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_zerop (TREE_REALPART (expr))
@@ -1628,6 +1747,7 @@ real_onep (expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst1))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_onep (TREE_REALPART (expr))
@@ -1643,6 +1763,7 @@ real_twop (expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == REAL_CST
+          && ! TREE_CONSTANT_OVERFLOW (expr)
           && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), dconst2))
          || (TREE_CODE (expr) == COMPLEX_CST
              && real_twop (TREE_REALPART (expr))
@@ -1891,6 +2012,20 @@ build_decl_list (parm, value)
   return node;
 }
 
+/* Similar, but build on the expression_obstack.  */
+
+tree
+build_expr_list (parm, value)
+     tree parm, value;
+{
+  register tree node;
+  register struct obstack *ambient_obstack = current_obstack;
+  current_obstack = expression_obstack;
+  node = build_tree_list (parm, value);
+  current_obstack = ambient_obstack;
+  return node;
+}
+
 /* Return a newly created TREE_LIST node whose
    purpose and value fields are PARM and VALUE
    and whose TREE_CHAIN is CHAIN.  */
@@ -1937,6 +2072,20 @@ decl_tree_cons (purpose, value, chain)
   return node;
 }
 
+/* Similar, but build on the expression_obstack.  */
+
+tree
+expr_tree_cons (purpose, value, chain)
+     tree purpose, value, chain;
+{
+  register tree node;
+  register struct obstack *ambient_obstack = current_obstack;
+  current_obstack = expression_obstack;
+  node = tree_cons (purpose, value, chain);
+  current_obstack = ambient_obstack;
+  return node;
+}
+
 /* Same as `tree_cons' but make a permanent object.  */
 
 tree
@@ -2035,19 +2184,49 @@ int_size_in_bytes (type)
 }
 \f
 /* Return, as a tree node, the number of elements for TYPE (which is an
-   ARRAY_TYPE) minus one. This counts only elements of the top array.  */
+   ARRAY_TYPE) minus one. This counts only elements of the top array.
+
+   Don't let any SAVE_EXPRs escape; if we are called as part of a cleanup
+   action, they would get unsaved.  */
 
 tree
 array_type_nelts (type)
      tree type;
 {
-  tree index_type = TYPE_DOMAIN (type);
+  tree index_type, min, max;
+
+  /* If they did it with unspecified bounds, then we should have already
+     given an error about it before we got here.  */
+  if (! TYPE_DOMAIN (type))
+    return error_mark_node;
+
+  index_type = TYPE_DOMAIN (type);
+  min = TYPE_MIN_VALUE (index_type);
+  max = TYPE_MAX_VALUE (index_type);
+
+  if (! TREE_CONSTANT (min))
+    {
+      STRIP_NOPS (min);
+      if (TREE_CODE (min) == SAVE_EXPR)
+       min = build (RTL_EXPR, TREE_TYPE (TYPE_MIN_VALUE (index_type)), 0,
+                    SAVE_EXPR_RTL (min));
+      else
+       min = TYPE_MIN_VALUE (index_type);
+    }
 
-  return (integer_zerop (TYPE_MIN_VALUE (index_type))
-         ? TYPE_MAX_VALUE (index_type)
-         : fold (build (MINUS_EXPR, TREE_TYPE (TYPE_MAX_VALUE (index_type)),
-                        TYPE_MAX_VALUE (index_type),
-                        TYPE_MIN_VALUE (index_type))));
+  if (! TREE_CONSTANT (max))
+    {
+      STRIP_NOPS (max);
+      if (TREE_CODE (max) == SAVE_EXPR)
+       max = build (RTL_EXPR, TREE_TYPE (TYPE_MAX_VALUE (index_type)), 0,
+                    SAVE_EXPR_RTL (max));
+      else
+       max = TYPE_MAX_VALUE (index_type);
+    }
+
+  return (integer_zerop (min)
+         ? max
+         : fold (build (MINUS_EXPR, TREE_TYPE (max), max, min)));
 }
 \f
 /* Return nonzero if arg is static -- a reference to an object in
@@ -2072,9 +2251,14 @@ staticp (arg)
     case STRING_CST:
       return 1;
 
+      /* If we are referencing a bitfield, we can't evaluate an
+        ADDR_EXPR at compile time and so it isn't a constant.  */
     case COMPONENT_REF:
+      return (! DECL_BIT_FIELD (TREE_OPERAND (arg, 1))
+             && staticp (TREE_OPERAND (arg, 0)));
+
     case BIT_FIELD_REF:
-      return staticp (TREE_OPERAND (arg, 0));
+      return 0;
 
 #if 0
        /* This case is technically correct, but results in setting
@@ -2185,15 +2369,18 @@ unsave_expr_now (expr)
 {
   enum tree_code code;
   register int i;
+  int first_rtl;
 
   if (expr == NULL_TREE)
     return expr;
 
   code = TREE_CODE (expr);
+  first_rtl = tree_code_length [(int) code];
   switch (code)
     {
     case SAVE_EXPR:
       SAVE_EXPR_RTL (expr) = 0;
+      first_rtl = 2;
       break;
 
     case TARGET_EXPR:
@@ -2205,6 +2392,7 @@ unsave_expr_now (expr)
       /* I don't yet know how to emit a sequence multiple times.  */
       if (RTL_EXPR_SEQUENCE (expr) != 0)
        abort ();
+      first_rtl = 0;
       break;
 
     case CALL_EXPR:
@@ -2219,6 +2407,16 @@ unsave_expr_now (expr)
              exp = TREE_CHAIN (exp);
            }
        }
+      first_rtl = 2;
+      break;
+
+    case WITH_CLEANUP_EXPR:
+      /* Should be defined to be 2.  */
+      first_rtl = 1;
+      break;
+
+    case METHOD_CALL_EXPR:
+      first_rtl = 3;
       break;
     }
 
@@ -2237,7 +2435,7 @@ unsave_expr_now (expr)
     case '<':  /* a comparison expression */
     case '2':  /* a binary arithmetic expression */
     case '1':  /* a unary arithmetic expression */
-      for (i = tree_code_length[(int) code] - 1; i >= 0; i--)
+      for (i = first_rtl - 1; i >= 0; i--)
        unsave_expr_now (TREE_OPERAND (expr, i));
       return expr;
 
@@ -2247,51 +2445,60 @@ unsave_expr_now (expr)
 }
 \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.
-
-   Note that we only allow such expressions within simple arithmetic
-   or a COND_EXPR.  */
+   or offset that depends on a field within a record.  */
 
 int
 contains_placeholder_p (exp)
      tree exp;
 {
   register enum tree_code code = TREE_CODE (exp);
-  tree inner;
 
   /* If we have a WITH_RECORD_EXPR, it "cancels" any PLACEHOLDER_EXPR
      in it since it is supplying a value for it.  */
   if (code == WITH_RECORD_EXPR)
     return 0;
+  else if (code == PLACEHOLDER_EXPR)
+    return 1;
 
   switch (TREE_CODE_CLASS (code))
     {
     case 'r':
-      for (inner = TREE_OPERAND (exp, 0);
-          TREE_CODE_CLASS (TREE_CODE (inner)) == 'r';
-          inner = TREE_OPERAND (inner, 0))
-       ;
-      return TREE_CODE (inner) == PLACEHOLDER_EXPR;
+      /* Don't look at any PLACEHOLDER_EXPRs that might be in index or bit
+        position computations since they will be converted into a
+        WITH_RECORD_EXPR involving the reference, which will assume
+        here will be valid.  */
+      return contains_placeholder_p (TREE_OPERAND (exp, 0));
 
     case '1':
     case '2':  case '<':
     case 'e':
+      switch (code)
+       {
+       case COMPOUND_EXPR:
+         /* Ignoring the first operand isn't quite right, but works best. */
+         return contains_placeholder_p (TREE_OPERAND (exp, 1));
+
+       case RTL_EXPR:
+       case CONSTRUCTOR:
+         return 0;
+
+       case COND_EXPR:
+         return (contains_placeholder_p (TREE_OPERAND (exp, 0))
+                 || contains_placeholder_p (TREE_OPERAND (exp, 1))
+                 || contains_placeholder_p (TREE_OPERAND (exp, 2)));
+
+       case SAVE_EXPR:
+          return (SAVE_EXPR_RTL (exp) == 0
+                  && contains_placeholder_p (TREE_OPERAND (exp, 0)));
+       }
+
       switch (tree_code_length[(int) code])
        {
        case 1:
          return contains_placeholder_p (TREE_OPERAND (exp, 0));
        case 2:
-         return (code != RTL_EXPR
-                 && code != CONSTRUCTOR
-                 && ! (code == SAVE_EXPR && SAVE_EXPR_RTL (exp) != 0)
-                 && code != WITH_RECORD_EXPR
-                 && (contains_placeholder_p (TREE_OPERAND (exp, 0))
-                     || contains_placeholder_p (TREE_OPERAND (exp, 1))));
-       case 3:
-         return (code == COND_EXPR
-                 && (contains_placeholder_p (TREE_OPERAND (exp, 0))
-                     || contains_placeholder_p (TREE_OPERAND (exp, 1))
-                     || contains_placeholder_p (TREE_OPERAND (exp, 2))));
+         return (contains_placeholder_p (TREE_OPERAND (exp, 0))
+                 || contains_placeholder_p (TREE_OPERAND (exp, 1)));
        }
     }
 
@@ -3162,7 +3369,7 @@ build_type_variant (type, constp, volatilep)
      like the one we need to have.  If so, use that existing one.  We must
      preserve the TYPE_NAME, since there is code that depends on this.  */
 
-  for (t = TYPE_MAIN_VARIANT(type); t; t = TYPE_NEXT_VARIANT (t))
+  for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
     if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t)
        && TYPE_NAME (t) == TYPE_NAME (type))
       return t;
@@ -3176,34 +3383,6 @@ build_type_variant (type, constp, volatilep)
   return t;
 }
 
-/* Give TYPE a new main variant: NEW_MAIN.
-   This is the right thing to do only when something else
-   about TYPE is modified in place.  */
-
-void
-change_main_variant (type, new_main)
-     tree type, new_main;
-{
-  tree t;
-  tree omain = TYPE_MAIN_VARIANT (type);
-
-  /* Remove TYPE from the TYPE_NEXT_VARIANT chain of its main variant.  */
-  if (TYPE_NEXT_VARIANT (omain) == type)
-    TYPE_NEXT_VARIANT (omain) = TYPE_NEXT_VARIANT (type);
-  else
-    for (t = TYPE_NEXT_VARIANT (omain); t && TYPE_NEXT_VARIANT (t);
-        t = TYPE_NEXT_VARIANT (t))
-      if (TYPE_NEXT_VARIANT (t) == type)
-       {
-         TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (type);
-         break;
-       }
-
-  TYPE_MAIN_VARIANT (type) = new_main;
-  TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (new_main);
-  TYPE_NEXT_VARIANT (new_main) = type;
-}
-
 /* Create a new variant of TYPE, equivalent but distinct.
    This is so the caller can modify it.  */
 
@@ -3691,10 +3870,14 @@ build_index_type (maxval)
      tree maxval;
 {
   register tree itype = make_node (INTEGER_TYPE);
+
   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
-  TYPE_MIN_VALUE (itype) = build_int_2 (0, 0);
-  TREE_TYPE (TYPE_MIN_VALUE (itype)) = sizetype;
+  TYPE_MIN_VALUE (itype) = size_zero_node;
+
+  push_obstacks (TYPE_OBSTACK (itype), TYPE_OBSTACK (itype));
   TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
+  pop_obstacks ();
+
   TYPE_MODE (itype) = TYPE_MODE (sizetype);
   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
@@ -3724,12 +3907,17 @@ build_range_type (type, lowval, highval)
      tree type, lowval, highval;
 {
   register tree itype = make_node (INTEGER_TYPE);
+
   TREE_TYPE (itype) = type;
   if (type == NULL_TREE)
     type = sizetype;
-  TYPE_PRECISION (itype) = TYPE_PRECISION (type);
+
+  push_obstacks (TYPE_OBSTACK (itype), TYPE_OBSTACK (itype));
   TYPE_MIN_VALUE (itype) = convert (type, lowval);
   TYPE_MAX_VALUE (itype) = convert (type, highval);
+  pop_obstacks ();
+
+  TYPE_PRECISION (itype) = TYPE_PRECISION (type);
   TYPE_MODE (itype) = TYPE_MODE (type);
   TYPE_SIZE (itype) = TYPE_SIZE (type);
   TYPE_ALIGN (itype) = TYPE_ALIGN (type);
@@ -3817,15 +4005,6 @@ build_array_type (elt_type, index_type)
   hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
   t = type_hash_canon (hashcode, t);
 
-#if 0 /* This led to crashes, because it could put a temporary node
-        on the TYPE_NEXT_VARIANT chain of a permanent one.  */
-  /* The main variant of an array type should always
-     be an array whose element type is the main variant.  */
-  if (elt_type != TYPE_MAIN_VARIANT (elt_type))
-    change_main_variant (t, build_array_type (TYPE_MAIN_VARIANT (elt_type),
-                                             index_type));
-#endif
-
   if (TYPE_SIZE (t) == 0)
     layout_type (t);
   return t;
@@ -4072,7 +4251,9 @@ get_unwidened (op, for_type)
 
   if (TREE_CODE (op) == COMPONENT_REF
       /* Since type_for_size always gives an integer type.  */
-      && TREE_CODE (type) != REAL_TYPE)
+      && TREE_CODE (type) != REAL_TYPE
+      /* Don't crash if field not layed out yet.  */
+      && DECL_SIZE (TREE_OPERAND (op, 1)) != 0)
     {
       unsigned innerprec = TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (op, 1)));
       type = type_for_size (innerprec, TREE_UNSIGNED (TREE_OPERAND (op, 1)));
@@ -4211,12 +4392,18 @@ int_fits_type_p (c, type)
     return (! (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
               && INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c))
            && ! (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
-                 && INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))));
+                 && INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type)))
+           /* Negative ints never fit unsigned types.  */
+           && ! (TREE_INT_CST_HIGH (c) < 0
+                 && ! TREE_UNSIGNED (TREE_TYPE (c))));
   else
     return (! (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
               && INT_CST_LT (TYPE_MAX_VALUE (type), c))
            && ! (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
-                 && INT_CST_LT (c, TYPE_MIN_VALUE (type))));
+                 && INT_CST_LT (c, TYPE_MIN_VALUE (type)))
+           /* Unsigned ints with top bit set never fit signed types.  */
+           && ! (TREE_INT_CST_HIGH (c) < 0
+                 && TREE_UNSIGNED (TREE_TYPE (c))));
 }
 
 /* Return the innermost context enclosing DECL that is
@@ -4239,7 +4426,8 @@ decl_function_context (decl)
   while (context && TREE_CODE (context) != FUNCTION_DECL)
     {
       if (TREE_CODE (context) == RECORD_TYPE
-         || TREE_CODE (context) == UNION_TYPE)
+         || TREE_CODE (context) == UNION_TYPE
+         || TREE_CODE (context) == QUAL_UNION_TYPE)
        context = TYPE_CONTEXT (context);
       else if (TREE_CODE (context) == TYPE_DECL)
        context = DECL_CONTEXT (context);
@@ -4419,8 +4607,8 @@ get_set_constructor_bits (init, buffer, bit_size)
       if (TREE_CODE (TREE_VALUE (vals)) != INTEGER_CST
          || (TREE_PURPOSE (vals) != NULL_TREE
              && TREE_CODE (TREE_PURPOSE (vals)) != INTEGER_CST))
-       non_const_bits =
-         tree_cons (TREE_PURPOSE (vals), TREE_VALUE (vals), non_const_bits);
+       non_const_bits
+         tree_cons (TREE_PURPOSE (vals), TREE_VALUE (vals), non_const_bits);
       else if (TREE_PURPOSE (vals) != NULL_TREE)
        {
          /* Set a range of bits to ones.  */