OSDN Git Service

gcc/fortran:
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index e1f7845..2151f97 100644 (file)
@@ -1,6 +1,6 @@
 /* Build expressions with type checking for C compiler.
    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006  
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -83,14 +83,13 @@ static int function_types_compatible_p (tree, tree);
 static int type_lists_compatible_p (tree, tree);
 static tree decl_constant_value_for_broken_optimization (tree);
 static tree lookup_field (tree, tree);
-static tree convert_arguments (tree, tree, tree, tree);
+static int convert_arguments (int, tree *, tree, tree, tree, tree);
 static tree pointer_diff (tree, tree);
 static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
                                    int);
 static tree valid_compound_expr_initializer (tree, tree);
 static void push_string (const char *);
 static void push_member_name (tree);
-static void push_array_bounds (int);
 static int spelling_length (void);
 static char *print_spelling (char *);
 static void warning_init (const char *);
@@ -118,7 +117,7 @@ null_pointer_constant_p (tree expr)
      yet available everywhere required.  */
   tree type = TREE_TYPE (expr);
   return (TREE_CODE (expr) == INTEGER_CST
-         && !TREE_CONSTANT_OVERFLOW (expr)
+         && !TREE_OVERFLOW (expr)
          && integer_zerop (expr)
          && (INTEGRAL_TYPE_P (type)
              || (TREE_CODE (type) == POINTER_TYPE
@@ -237,8 +236,8 @@ c_type_promotes_to (tree type)
     {
       /* Preserve unsignedness if not really getting any wider.  */
       if (TYPE_UNSIGNED (type)
-          && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
-        return unsigned_type_node;
+         && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+       return unsigned_type_node;
       return integer_type_node;
     }
 
@@ -254,6 +253,17 @@ qualify_type (tree type, tree like)
   return c_build_qualified_type (type,
                                 TYPE_QUALS (type) | TYPE_QUALS (like));
 }
+
+/* Return true iff the given tree T is a variable length array.  */
+
+bool
+c_vla_type_p (tree t)
+{
+  if (TREE_CODE (t) == ARRAY_TYPE
+      && C_TYPE_VARIABLE_SIZE (t))
+    return true;
+  return false;
+}
 \f
 /* Return the composite type of two compatible types.
 
@@ -321,7 +331,7 @@ composite_type (tree t1, tree t2)
 
        /* We should not have any type quals on arrays at all.  */
        gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
-       
+
        d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1);
        d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2);
 
@@ -331,6 +341,8 @@ composite_type (tree t1, tree t2)
        d2_variable = (!d2_zero
                       && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
                           || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+       d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
+       d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
 
        /* Save space: see if the result is identical to one of the args.  */
        if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)
@@ -339,12 +351,12 @@ composite_type (tree t1, tree t2)
        if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)
            && (d1_variable || d1_zero || !d2_variable))
          return build_type_attribute_variant (t2, attributes);
-       
+
        if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
          return build_type_attribute_variant (t1, attributes);
        if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
          return build_type_attribute_variant (t2, attributes);
-       
+
        /* Merge the element types, and have a size if either arg has
           one.  We may have qualifiers on the element types.  To set
           up TYPE_MAIN_VARIANT correctly, we need to form the
@@ -363,6 +375,19 @@ composite_type (tree t1, tree t2)
        return build_type_attribute_variant (t1, attributes);
       }
 
+    case ENUMERAL_TYPE:
+    case RECORD_TYPE:
+    case UNION_TYPE:
+      if (attributes != NULL)
+       {
+         /* Try harder not to create a new aggregate type.  */
+         if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
+           return t1;
+         if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
+           return t2;
+       }
+      return build_type_attribute_variant (t1, attributes);
+
     case FUNCTION_TYPE:
       /* Function types: prefer the one that specified arg types.
         If both do, merge the arg types.  Also merge the return types.  */
@@ -518,7 +543,7 @@ common_pointer_type (tree t1, tree t2)
     return t1;
 
   gcc_assert (TREE_CODE (t1) == POINTER_TYPE
-             && TREE_CODE (t2) == POINTER_TYPE);
+             && TREE_CODE (t2) == POINTER_TYPE);
 
   /* Merge the attributes.  */
   attributes = targetm.merge_type_attributes (t1, t2);
@@ -584,6 +609,29 @@ c_common_type (tree t1, tree t2)
   gcc_assert (code2 == VECTOR_TYPE || code2 == COMPLEX_TYPE
              || code2 == REAL_TYPE || code2 == INTEGER_TYPE);
 
+  /* When one operand is a decimal float type, the other operand cannot be
+     a generic float type or a complex type.  We also disallow vector types
+     here.  */
+  if ((DECIMAL_FLOAT_TYPE_P (t1) || DECIMAL_FLOAT_TYPE_P (t2))
+      && !(DECIMAL_FLOAT_TYPE_P (t1) && DECIMAL_FLOAT_TYPE_P (t2)))
+    {
+      if (code1 == VECTOR_TYPE || code2 == VECTOR_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and vector types");
+         return error_mark_node;
+       }
+      if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and complex types");
+         return error_mark_node;
+       }
+      if (code1 == REAL_TYPE && code2 == REAL_TYPE)
+       {
+         error ("can%'t mix operands of decimal float and other float types");
+         return error_mark_node;
+       }
+    }
+
   /* If one type is a vector type, return that type.  (How the usual
      arithmetic conversions apply to the vector types extension is not
      precisely specified.)  */
@@ -655,7 +703,7 @@ c_common_type (tree t1, tree t2)
       if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
        return long_long_unsigned_type_node;
       else
-        return long_long_integer_type_node;
+       return long_long_integer_type_node;
     }
 
   if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
@@ -725,9 +773,10 @@ comptypes (tree type1, tree type2)
 
   val = comptypes_internal (type1, type2);
   free_all_tagged_tu_seen_up_to (tagged_tu_seen_base1);
-  
+
   return val;
-}\f
+}
+\f
 /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
    or various other operations.  Return 2 if they are compatible
    but a warning may be needed if you use them together.  This
@@ -835,6 +884,8 @@ comptypes_internal (tree type1, tree type2)
        d2_variable = (!d2_zero
                       && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
                           || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+       d1_variable = d1_variable || (d1_zero && c_vla_type_p (t1));
+       d2_variable = d2_variable || (d2_zero && c_vla_type_p (t2));
 
        if (d1_variable || d2_variable)
          break;
@@ -845,14 +896,21 @@ comptypes_internal (tree type1, tree type2)
            || !tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
          val = 0;
 
-        break;
+       break;
       }
 
     case ENUMERAL_TYPE:
     case RECORD_TYPE:
     case UNION_TYPE:
       if (val != 1 && !same_translation_unit_p (t1, t2))
-        {
+       {
+         tree a1 = TYPE_ATTRIBUTES (t1);
+         tree a2 = TYPE_ATTRIBUTES (t2);
+
+         if (! attribute_list_contained (a1, a2)
+             && ! attribute_list_contained (a2, a1))
+           break;
+
          if (attrval != 2)
            return tagged_types_tu_compatible_p (t1, t2);
          val = tagged_types_tu_compatible_p (t1, t2);
@@ -939,9 +997,9 @@ alloc_tagged_tu_seen_cache (tree t1, tree t2)
   tu->next = tagged_tu_seen_base;
   tu->t1 = t1;
   tu->t2 = t2;
-  
+
   tagged_tu_seen_base = tu;
-  
+
   /* The C standard says that two structures in different translation
      units are compatible with each other only if the types of their
      fields are compatible (among other things).  We assume that they
@@ -1024,31 +1082,31 @@ tagged_types_tu_compatible_p (tree t1, tree t2)
     case ENUMERAL_TYPE:
       {
        struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
-        /* Speed up the case where the type values are in the same order.  */
-        tree tv1 = TYPE_VALUES (t1);
-        tree tv2 = TYPE_VALUES (t2);
+       /* Speed up the case where the type values are in the same order.  */
+       tree tv1 = TYPE_VALUES (t1);
+       tree tv2 = TYPE_VALUES (t2);
 
-        if (tv1 == tv2)
+       if (tv1 == tv2)
          {
            return 1;
          }
 
-        for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
-          {
-            if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
-              break;
-            if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
+       for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
+         {
+           if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
+             break;
+           if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
              {
-               tu->val = 0;
+               tu->val = 0;
                return 0;
              }
-          }
+         }
 
-        if (tv1 == NULL_TREE && tv2 == NULL_TREE)
+       if (tv1 == NULL_TREE && tv2 == NULL_TREE)
          {
            return 1;
          }
-        if (tv1 == NULL_TREE || tv2 == NULL_TREE)
+       if (tv1 == NULL_TREE || tv2 == NULL_TREE)
          {
            tu->val = 0;
            return 0;
@@ -1081,16 +1139,16 @@ tagged_types_tu_compatible_p (tree t1, tree t2)
            tu->val = 0;
            return 0;
          }
-       
+
        /*  Speed up the common case where the fields are in the same order. */
        for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); s1 && s2;
             s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
          {
            int result;
-           
-           
+
+
            if (DECL_NAME (s1) == NULL
-               || DECL_NAME (s1) != DECL_NAME (s2))
+               || DECL_NAME (s1) != DECL_NAME (s2))
              break;
            result = comptypes_internal (TREE_TYPE (s1), TREE_TYPE (s2));
            if (result == 0)
@@ -1153,7 +1211,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2)
 
     case RECORD_TYPE:
       {
-        struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
+       struct tagged_tu_seen_cache *tu = alloc_tagged_tu_seen_cache (t1, t2);
 
        for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
             s1 && s2;
@@ -1771,11 +1829,17 @@ build_component_ref (tree datum, tree component)
       do
        {
          tree subdatum = TREE_VALUE (field);
+         int quals;
+         tree subtype;
 
          if (TREE_TYPE (subdatum) == error_mark_node)
            return error_mark_node;
 
-         ref = build3 (COMPONENT_REF, TREE_TYPE (subdatum), datum, subdatum,
+         quals = TYPE_QUALS (strip_array_types (TREE_TYPE (subdatum)));
+         quals |= TYPE_QUALS (TREE_TYPE (datum));
+         subtype = c_build_qualified_type (TREE_TYPE (subdatum), quals);
+
+         ref = build3 (COMPONENT_REF, subtype, datum, subdatum,
                        NULL_TREE);
          if (TREE_READONLY (datum) || TREE_READONLY (subdatum))
            TREE_READONLY (ref) = 1;
@@ -1812,6 +1876,19 @@ build_indirect_ref (tree ptr, const char *errorstring)
 
   if (TREE_CODE (type) == POINTER_TYPE)
     {
+      if (TREE_CODE (pointer) == CONVERT_EXPR
+          || TREE_CODE (pointer) == NOP_EXPR
+          || TREE_CODE (pointer) == VIEW_CONVERT_EXPR)
+       {
+         /* If a warning is issued, mark it to avoid duplicates from
+            the backend.  This only needs to be done at
+            warn_strict_aliasing > 2.  */
+         if (warn_strict_aliasing > 2)
+           if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)),
+                                        type, TREE_OPERAND (pointer, 0)))
+             TREE_NO_WARNING (pointer) = 1;
+       }
+
       if (TREE_CODE (pointer) == ADDR_EXPR
          && (TREE_TYPE (TREE_OPERAND (pointer, 0))
              == TREE_TYPE (type)))
@@ -1846,7 +1923,7 @@ build_indirect_ref (tree ptr, const char *errorstring)
        }
     }
   else if (TREE_CODE (pointer) != ERROR_MARK)
-    error ("invalid type argument of %qs", errorstring);
+    error ("invalid type argument of %qs (have %qT)", errorstring, type);
   return error_mark_node;
 }
 
@@ -1948,7 +2025,7 @@ build_array_ref (tree array, tree index)
        type = TYPE_MAIN_VARIANT (type);
       rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
       /* Array ref is const/volatile if the array elements are
-         or if the array is.  */
+        or if the array is.  */
       TREE_READONLY (rval)
        |= (TYPE_READONLY (TREE_TYPE (TREE_TYPE (array)))
            | TREE_READONLY (array));
@@ -2013,9 +2090,13 @@ build_external_ref (tree id, int fun, location_t loc)
   if (TREE_DEPRECATED (ref))
     warn_deprecated_use (ref);
 
-  if (!skip_evaluation)
-    assemble_external (ref);
-  TREE_USED (ref) = 1;
+  /* Recursive call does not count as usage.  */
+  if (ref != current_function_decl) 
+    {
+      if (!skip_evaluation)
+       assemble_external (ref);
+      TREE_USED (ref) = 1;
+    }
 
   if (TREE_CODE (ref) == FUNCTION_DECL && !in_alignof)
     {
@@ -2029,6 +2110,7 @@ build_external_ref (tree id, int fun, location_t loc)
 
   if (TREE_CODE (ref) == CONST_DECL)
     {
+      used_types_insert (TREE_TYPE (ref));
       ref = DECL_INITIAL (ref);
       TREE_CONSTANT (ref) = 1;
       TREE_INVARIANT (ref) = 1;
@@ -2044,6 +2126,17 @@ build_external_ref (tree id, int fun, location_t loc)
       if (context != 0 && context != current_function_decl)
        DECL_NONLOCAL (ref) = 1;
     }
+  /* C99 6.7.4p3: An inline definition of a function with external
+     linkage ... shall not contain a reference to an identifier with
+     internal linkage.  */
+  else if (current_function_decl != 0
+          && DECL_DECLARED_INLINE_P (current_function_decl)
+          && DECL_EXTERNAL (current_function_decl)
+          && VAR_OR_FUNCTION_DECL_P (ref)
+          && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
+          && ! TREE_PUBLIC (ref))
+    pedwarn ("%H%qD is static but used in inline function %qD "
+            "which is not static", &loc, ref, current_function_decl);
 
   return ref;
 }
@@ -2117,6 +2210,11 @@ c_expr_sizeof_expr (struct c_expr expr)
     {
       ret.value = c_sizeof (TREE_TYPE (expr.value));
       ret.original_code = ERROR_MARK;
+      if (c_vla_type_p (TREE_TYPE (expr.value)))
+       {
+         /* sizeof is evaluated when given a vla (C99 6.5.3.4p2).  */
+         ret.value = build2 (COMPOUND_EXPR, TREE_TYPE (ret.value), expr.value, ret.value);
+       }
       pop_maybe_used (C_TYPE_VARIABLE_SIZE (TREE_TYPE (expr.value)));
     }
   return ret;
@@ -2133,7 +2231,8 @@ c_expr_sizeof_type (struct c_type_name *t)
   type = groktypename (t);
   ret.value = c_sizeof (type);
   ret.original_code = ERROR_MARK;
-  pop_maybe_used (C_TYPE_VARIABLE_SIZE (type));
+  pop_maybe_used (type != error_mark_node
+                 ? C_TYPE_VARIABLE_SIZE (type) : false);
   return ret;
 }
 
@@ -2146,9 +2245,11 @@ tree
 build_function_call (tree function, tree params)
 {
   tree fntype, fundecl = 0;
-  tree coerced_params;
   tree name = NULL_TREE, result;
   tree tem;
+  int nargs;
+  tree *argarray;
+  
 
   /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue.  */
   STRIP_TYPE_NOPS (function);
@@ -2235,30 +2336,30 @@ build_function_call (tree function, tree params)
   /* Convert the parameters to the types declared in the
      function prototype, or apply default promotions.  */
 
-  coerced_params
-    = convert_arguments (TYPE_ARG_TYPES (fntype), params, function, fundecl);
-
-  if (coerced_params == error_mark_node)
+  nargs = list_length (params);
+  argarray = (tree *) alloca (nargs * sizeof (tree));
+  nargs = convert_arguments (nargs, argarray, TYPE_ARG_TYPES (fntype), 
+                            params, function, fundecl);
+  if (nargs < 0)
     return error_mark_node;
 
   /* Check that the arguments to the function are valid.  */
 
-  check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
+  check_function_arguments (TYPE_ATTRIBUTES (fntype), nargs, argarray,
                            TYPE_ARG_TYPES (fntype));
 
   if (require_constant_value)
     {
-      result = fold_build3_initializer (CALL_EXPR, TREE_TYPE (fntype),
-                                       function, coerced_params, NULL_TREE);
-
+      result = fold_build_call_array_initializer (TREE_TYPE (fntype),
+                                                 function, nargs, argarray);
       if (TREE_CONSTANT (result)
          && (name == NULL_TREE
              || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
        pedwarn_init ("initializer element is not constant");
     }
   else
-    result = fold_build3 (CALL_EXPR, TREE_TYPE (fntype),
-                         function, coerced_params, NULL_TREE);
+    result = fold_build_call_array (TREE_TYPE (fntype),
+                                   function, nargs, argarray);
 
   if (VOID_TYPE_P (TREE_TYPE (result)))
     return result;
@@ -2266,9 +2367,8 @@ build_function_call (tree function, tree params)
 }
 \f
 /* Convert the argument expressions in the list VALUES
-   to the types in the list TYPELIST.  The result is a list of converted
-   argument expressions, unless there are too few arguments in which
-   case it is error_mark_node.
+   to the types in the list TYPELIST.  The resulting arguments are
+   stored in the array ARGARRAY which has size NARGS.
 
    If TYPELIST is exhausted, or when an element has NULL as its type,
    perform the default conversions.
@@ -2282,15 +2382,20 @@ build_function_call (tree function, tree params)
 
    This is also where warnings about wrong number of args are generated.
 
-   Both VALUES and the returned value are chains of TREE_LIST nodes
-   with the elements of the list in the TREE_VALUE slots of those nodes.  */
+   VALUES is a chain of TREE_LIST nodes with the elements of the list
+   in the TREE_VALUE slots of those nodes.
 
-static tree
-convert_arguments (tree typelist, tree values, tree function, tree fundecl)
+   Returns the actual number of arguments processed (which may be less
+   than NARGS in some error situations), or -1 on failure.  */
+
+static int
+convert_arguments (int nargs, tree *argarray,
+                  tree typelist, tree values, tree function, tree fundecl)
 {
   tree typetail, valtail;
-  tree result = NULL;
   int parmnum;
+  const bool type_generic = fundecl
+    && lookup_attribute ("type generic", TYPE_ATTRIBUTES(TREE_TYPE (fundecl)));
   tree selector;
 
   /* Change pointer to function to the function itself for
@@ -2303,7 +2408,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
   selector = objc_message_selector ();
 
   /* Scan the given expressions and types, producing individual
-     converted arguments and pushing them on RESULT in reverse order.  */
+     converted arguments and storing them in ARGARRAY.  */
 
   for (valtail = values, typetail = typelist, parmnum = 0;
        valtail;
@@ -2318,7 +2423,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
       if (type == void_type_node)
        {
          error ("too many arguments to function %qE", function);
-         break;
+         return parmnum;
        }
 
       if (selector && argnum > 2)
@@ -2345,7 +2450,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
            {
              /* Optionally warn about conversions that
                 differ from the default conversions.  */
-             if (warn_conversion || warn_traditional)
+             if (warn_traditional_conversion || warn_traditional)
                {
                  unsigned int formal_prec = TYPE_PRECISION (type);
 
@@ -2400,16 +2505,16 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
                      else if (type != TREE_TYPE (val)
                               && (type == dfloat32_type_node
                                   || type == dfloat64_type_node
-                                  || type == dfloat128_type_node 
+                                  || type == dfloat128_type_node
                                   || TREE_TYPE (val) == dfloat32_type_node
                                   || TREE_TYPE (val) == dfloat64_type_node
                                   || TREE_TYPE (val) == dfloat128_type_node)
-                              && (formal_prec 
+                              && (formal_prec
                                   <= TYPE_PRECISION (TREE_TYPE (val))
                                   || (type == dfloat128_type_node
                                       && (TREE_TYPE (val)
-                                          != dfloat64_type_node 
-                                          && (TREE_TYPE (val) 
+                                          != dfloat64_type_node
+                                          && (TREE_TYPE (val)
                                               != dfloat32_type_node)))
                                   || (type == dfloat64_type_node
                                       && (TREE_TYPE (val)
@@ -2421,8 +2526,8 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
                    }
                  /* Detect integer changing in width or signedness.
                     These warnings are only activated with
-                    -Wconversion, not with -Wtraditional.  */
-                 else if (warn_conversion && INTEGRAL_TYPE_P (type)
+                    -Wtraditional-conversion, not with -Wtraditional.  */
+                 else if (warn_traditional_conversion && INTEGRAL_TYPE_P (type)
                           && INTEGRAL_TYPE_P (TREE_TYPE (val)))
                    {
                      tree would_have_been = default_conversion (val);
@@ -2435,7 +2540,7 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
                           and the actual arg is that enum type.  */
                        ;
                      else if (formal_prec != TYPE_PRECISION (type1))
-                       warning (OPT_Wconversion, "passing argument %d of %qE "
+                       warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
                                 "with different width due to prototype",
                                 argnum, rname);
                      else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
@@ -2458,11 +2563,11 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
                               && TYPE_UNSIGNED (TREE_TYPE (val)))
                        ;
                      else if (TYPE_UNSIGNED (type))
-                       warning (OPT_Wconversion, "passing argument %d of %qE "
+                       warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
                                 "as unsigned due to prototype",
                                 argnum, rname);
                      else
-                       warning (OPT_Wconversion, "passing argument %d of %qE "
+                       warning (OPT_Wtraditional_conversion, "passing argument %d of %qE "
                                 "as signed due to prototype", argnum, rname);
                    }
                }
@@ -2476,35 +2581,42 @@ convert_arguments (tree typelist, tree values, tree function, tree fundecl)
                  && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
                parmval = default_conversion (parmval);
            }
-         result = tree_cons (NULL_TREE, parmval, result);
+         argarray[parmnum] = parmval;
        }
       else if (TREE_CODE (TREE_TYPE (val)) == REAL_TYPE
-               && (TYPE_PRECISION (TREE_TYPE (val))
-                  < TYPE_PRECISION (double_type_node))
+              && (TYPE_PRECISION (TREE_TYPE (val))
+                  < TYPE_PRECISION (double_type_node))
               && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (val))))
-       /* Convert `float' to `double'.  */
-       result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
-      else if ((invalid_func_diag = 
-               targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
+        {
+         if (type_generic)
+           argarray[parmnum] = val;
+         else
+           /* Convert `float' to `double'.  */
+           argarray[parmnum] = convert (double_type_node, val);
+       }
+      else if ((invalid_func_diag =
+               targetm.calls.invalid_arg_for_unprototyped_fn (typelist, fundecl, val)))
        {
          error (invalid_func_diag);
-         return error_mark_node; 
+         return -1;
        }
       else
        /* Convert `short' and `char' to full-size `int'.  */
-       result = tree_cons (NULL_TREE, default_conversion (val), result);
+       argarray[parmnum] = default_conversion (val);
 
       if (typetail)
        typetail = TREE_CHAIN (typetail);
     }
 
+  gcc_assert (parmnum == nargs);
+
   if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
     {
       error ("too few arguments to function %qE", function);
-      return error_mark_node;
+      return -1;
     }
 
-  return nreverse (result);
+  return parmnum;
 }
 \f
 /* This is the entry point used by the parser to build unary operators
@@ -2519,7 +2631,10 @@ parser_build_unary_op (enum tree_code code, struct c_expr arg)
 
   result.original_code = ERROR_MARK;
   result.value = build_unary_op (code, arg.value, 0);
-  overflow_warning (result.value);
+  
+  if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
+    overflow_warning (result.value);
+
   return result;
 }
 
@@ -2547,73 +2662,10 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
   /* Check for cases such as x+y<<z which users are likely
      to misinterpret.  */
   if (warn_parentheses)
-    {
-      if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
-       {
-         if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
-             || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around + or - inside shift");
-       }
+    warn_about_parentheses (code, code1, code2);
 
-      if (code == TRUTH_ORIF_EXPR)
-       {
-         if (code1 == TRUTH_ANDIF_EXPR
-             || code2 == TRUTH_ANDIF_EXPR)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around && within ||");
-       }
-
-      if (code == BIT_IOR_EXPR)
-       {
-         if (code1 == BIT_AND_EXPR || code1 == BIT_XOR_EXPR
-             || code1 == PLUS_EXPR || code1 == MINUS_EXPR
-             || code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
-             || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around arithmetic in operand of |");
-         /* Check cases like x|y==z */
-         if (TREE_CODE_CLASS (code1) == tcc_comparison
-             || TREE_CODE_CLASS (code2) == tcc_comparison)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around comparison in operand of |");
-       }
-
-      if (code == BIT_XOR_EXPR)
-       {
-         if (code1 == BIT_AND_EXPR
-             || code1 == PLUS_EXPR || code1 == MINUS_EXPR
-             || code2 == BIT_AND_EXPR
-             || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around arithmetic in operand of ^");
-         /* Check cases like x^y==z */
-         if (TREE_CODE_CLASS (code1) == tcc_comparison
-             || TREE_CODE_CLASS (code2) == tcc_comparison)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around comparison in operand of ^");
-       }
-
-      if (code == BIT_AND_EXPR)
-       {
-         if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
-             || code2 == PLUS_EXPR || code2 == MINUS_EXPR)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around + or - in operand of &");
-         /* Check cases like x&y==z */
-         if (TREE_CODE_CLASS (code1) == tcc_comparison
-             || TREE_CODE_CLASS (code2) == tcc_comparison)
-           warning (OPT_Wparentheses,
-                    "suggest parentheses around comparison in operand of &");
-       }
-      /* Similarly, check for cases like 1<=i<=10 that are probably errors.  */
-      if (TREE_CODE_CLASS (code) == tcc_comparison
-         && (TREE_CODE_CLASS (code1) == tcc_comparison
-             || TREE_CODE_CLASS (code2) == tcc_comparison))
-       warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
-                "have their mathematical meaning");
-
-    }
+  if (code1 != tcc_comparison)
+    warn_logical_operator (code, arg1.value, arg2.value);
 
   /* Warn about comparisons against string literals, with the exception
      of testing for equality or inequality of a string literal with NULL.  */
@@ -2621,17 +2673,16 @@ parser_build_binary_op (enum tree_code code, struct c_expr arg1,
     {
       if ((code1 == STRING_CST && !integer_zerop (arg2.value))
          || (code2 == STRING_CST && !integer_zerop (arg1.value)))
-       warning (OPT_Wstring_literal_comparison,
-                "comparison with string literal");
+       warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
     }
   else if (TREE_CODE_CLASS (code) == tcc_comparison
           && (code1 == STRING_CST || code2 == STRING_CST))
-    warning (OPT_Wstring_literal_comparison,
-            "comparison with string literal");
+    warning (OPT_Waddress, "comparison with string literal results in unspecified behavior");
 
-  unsigned_conversion_warning (result.value, arg1.value);
-  unsigned_conversion_warning (result.value, arg2.value);
-  overflow_warning (result.value);
+  if (TREE_OVERFLOW_P (result.value) 
+      && !TREE_OVERFLOW_P (arg1.value) 
+      && !TREE_OVERFLOW_P (arg2.value))
+    overflow_warning (result.value);
 
   return result;
 }
@@ -2868,8 +2919,11 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
          arg = stabilize_reference (arg);
          real = build_unary_op (REALPART_EXPR, arg, 1);
          imag = build_unary_op (IMAGPART_EXPR, arg, 1);
+         real = build_unary_op (code, real, 1);
+         if (real == error_mark_node || imag == error_mark_node)
+           return error_mark_node;
          return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
-                        build_unary_op (code, real, 1), imag);
+                        real, imag);
        }
 
       /* Report invalid types.  */
@@ -2878,9 +2932,9 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
          && typecode != INTEGER_TYPE && typecode != REAL_TYPE)
        {
          if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-            error ("wrong type argument to increment");
-          else
-            error ("wrong type argument to decrement");
+           error ("wrong type argument to increment");
+         else
+           error ("wrong type argument to decrement");
 
          return error_mark_node;
        }
@@ -2908,7 +2962,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
            else if ((pedantic || warn_pointer_arith)
                     && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
                         || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE))
-              {
+             {
                if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
                  pedwarn ("wrong type argument to increment");
                else
@@ -2916,11 +2970,13 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
              }
 
            inc = c_size_in_bytes (TREE_TYPE (result_type));
+           inc = fold_convert (sizetype, inc);
          }
        else
-         inc = integer_one_node;
-
-       inc = convert (argtype, inc);
+         {
+           inc = integer_one_node;
+           inc = convert (argtype, inc);
+         }
 
        /* Complain about anything else that is not a true lvalue.  */
        if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
@@ -2985,7 +3041,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       argtype = TREE_TYPE (arg);
 
       /* If the lvalue is const or volatile, merge that into the type
-         to which the address will point.  Note that you can't get a
+        to which the address will point.  Note that you can't get a
         restricted pointer by taking the address of something, so we
         only have to deal with `const' and `volatile' here.  */
       if ((DECL_P (arg) || REFERENCE_CLASS_P (arg))
@@ -3008,10 +3064,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       if (val && TREE_CODE (val) == INDIRECT_REF
           && TREE_CONSTANT (TREE_OPERAND (val, 0)))
        {
-         tree op0 = fold_convert (argtype, fold_offsetof (arg)), op1;
+         tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
 
          op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
-         return fold_build2 (PLUS_EXPR, argtype, op0, op1);
+         return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
        }
 
       val = build1 (ADDR_EXPR, argtype, arg);
@@ -3025,7 +3081,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
   if (argtype == 0)
     argtype = TREE_TYPE (arg);
   return require_constant_value ? fold_build1_initializer (code, argtype, arg)
-                               : fold_build1 (code, argtype, arg);
+                               : fold_build1 (code, argtype, arg);
 }
 
 /* Return nonzero if REF is an lvalue valid for this language.
@@ -3076,7 +3132,7 @@ readonly_error (tree arg, enum lvalue_use use)
      ensures that all the format strings are checked at compile
      time.  */
 #define READONLY_MSG(A, I, D, AS) (use == lv_assign ? (A)              \
-                                  : (use == lv_increment ? (I)         \
+                                  : (use == lv_increment ? (I)         \
                                   : (use == lv_decrement ? (D) : (AS))))
   if (TREE_CODE (arg) == COMPONENT_REF)
     {
@@ -3232,9 +3288,9 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
        result_type = TYPE_MAIN_VARIANT (type1);
     }
   else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE
-            || code1 == COMPLEX_TYPE)
-           && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
-               || code2 == COMPLEX_TYPE))
+           || code1 == COMPLEX_TYPE)
+          && (code2 == INTEGER_TYPE || code2 == REAL_TYPE
+              || code2 == COMPLEX_TYPE))
     {
       result_type = c_common_type (type1, type2);
 
@@ -3250,6 +3306,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
 
          if (unsigned_op1 ^ unsigned_op2)
            {
+             bool ovf;
+
              /* Do not warn if the result type is signed, since the
                 signed type will only be chosen if it can represent
                 all the values of the unsigned type.  */
@@ -3258,8 +3316,10 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
              /* Do not warn if the signed quantity is an unsuffixed
                 integer literal (or some static constant expression
                 involving such literals) and it is non-negative.  */
-             else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
-                      || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
+             else if ((unsigned_op2
+                       && tree_expr_nonnegative_warnv_p (op1, &ovf))
+                      || (unsigned_op1
+                          && tree_expr_nonnegative_warnv_p (op2, &ovf)))
                /* OK */;
              else
                warning (0, "signed and unsigned type in conditional expression");
@@ -3357,7 +3417,7 @@ build_compound_expr (tree expr1, tree expr2)
   if (!TREE_SIDE_EFFECTS (expr1))
     {
       /* The left-hand operand of a comma expression is like an expression
-         statement: with -Wextra or -Wunused, we should warn if it doesn't have
+        statement: with -Wextra or -Wunused, we should warn if it doesn't have
         any side-effects, unless it was explicitly cast to (void).  */
       if (warn_unused_value)
        {
@@ -3371,7 +3431,8 @@ build_compound_expr (tree expr1, tree expr2)
                       || TREE_CODE (TREE_OPERAND (expr1, 1)) == NOP_EXPR))
            ; /* (void) a, (void) b, c */
          else
-           warning (0, "left-hand operand of comma expression has no effect");
+           warning (OPT_Wunused_value, 
+                    "left-hand operand of comma expression has no effect");
        }
     }
 
@@ -3382,6 +3443,9 @@ build_compound_expr (tree expr1, tree expr2)
   else if (warn_unused_value)
     warn_if_unused_value (expr1, input_location);
 
+  if (expr2 == error_mark_node)
+    return error_mark_node;
+
   return build2 (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
 }
 
@@ -3518,10 +3582,10 @@ build_c_cast (tree type, tree expr)
       if (TREE_CODE (type) == INTEGER_TYPE
          && TREE_CODE (otype) == POINTER_TYPE
          && TYPE_PRECISION (type) != TYPE_PRECISION (otype))
-      /* Unlike conversion of integers to pointers, where the 
-         warning is disabled for converting constants because 
-         of cases such as SIG_*, warn about converting constant 
-         pointers to integers. In some cases it may cause unwanted 
+      /* Unlike conversion of integers to pointers, where the
+         warning is disabled for converting constants because
+         of cases such as SIG_*, warn about converting constant
+         pointers to integers. In some cases it may cause unwanted
          sign extension, and a warning is appropriate.  */
        warning (OPT_Wpointer_to_int_cast,
                 "cast from pointer to integer of different size");
@@ -3539,7 +3603,8 @@ build_c_cast (tree type, tree expr)
        warning (OPT_Wint_to_pointer_cast, "cast to pointer from integer "
                 "of different size");
 
-      strict_aliasing_warning (otype, type, expr);
+      if (warn_strict_aliasing <= 2)
+        strict_aliasing_warning (otype, type, expr);
 
       /* If pedantic, warn for conversions between function and object
         pointer types, except for converting a null pointer constant
@@ -3565,15 +3630,16 @@ build_c_cast (tree type, tree expr)
       /* Ignore any integer overflow caused by the cast.  */
       if (TREE_CODE (value) == INTEGER_CST)
        {
-         if (CONSTANT_CLASS_P (ovalue)
-             && (TREE_OVERFLOW (ovalue) || TREE_CONSTANT_OVERFLOW (ovalue)))
+         if (CONSTANT_CLASS_P (ovalue) && TREE_OVERFLOW (ovalue))
            {
-             /* Avoid clobbering a shared constant.  */
-             value = copy_node (value);
-             TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
-             TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue);
+             if (!TREE_OVERFLOW (value))
+               {
+                 /* Avoid clobbering a shared constant.  */
+                 value = copy_node (value);
+                 TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue);
+               }
            }
-         else if (TREE_OVERFLOW (value) || TREE_CONSTANT_OVERFLOW (value))
+         else if (TREE_OVERFLOW (value))
            /* Reset VALUE's overflow flags, ensuring constant sharing.  */
            value = build_int_cst_wide (TREE_TYPE (value),
                                        TREE_INT_CST_LOW (value),
@@ -3604,7 +3670,6 @@ c_cast_expr (struct c_type_name *type_name, tree expr)
 
   return build_c_cast (type, expr);
 }
-
 \f
 /* Build an assignment expression of lvalue LHS from value RHS.
    MODIFYCODE is the code for a binary operator that we use
@@ -3626,6 +3691,9 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
   if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
     return error_mark_node;
 
+  if (!lvalue_or_else (lhs, lv_assign))
+    return error_mark_node;
+
   STRIP_TYPE_NOPS (rhs);
 
   newrhs = rhs;
@@ -3639,9 +3707,6 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
       newrhs = build_binary_op (modifycode, lhs, rhs, 1);
     }
 
-  if (!lvalue_or_else (lhs, lv_assign))
-    return error_mark_node;
-
   /* Give an error for storing in something that is 'const'.  */
 
   if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
@@ -3811,10 +3876,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
     }
 
   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
-    {
-      overflow_warning (rhs);
-      return rhs;
-    }
+    return rhs;
 
   if (coder == VOID_TYPE)
     {
@@ -3854,7 +3916,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
     }
   /* Some types can interconvert without explicit casts.  */
   else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
-           && vector_types_convertible_p (type, TREE_TYPE (rhs)))
+          && vector_types_convertible_p (type, TREE_TYPE (rhs), true))
     return convert (type, rhs);
   /* Arithmetic types all interconvert, and enum is treated like int.  */
   else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
@@ -3865,10 +3927,16 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
               || coder == BOOLEAN_TYPE))
     return convert_and_check (type, rhs);
 
+  /* Aggregates in different TUs might need conversion.  */
+  if ((codel == RECORD_TYPE || codel == UNION_TYPE)
+      && codel == coder
+      && comptypes (type, rhstype))
+    return convert_and_check (type, rhs);
+
   /* Conversion to a transparent union from its member types.
      This applies only to function arguments.  */
-  else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
-          && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
+  if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
+      && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
     {
       tree memb, marginal_memb = NULL_TREE;
 
@@ -3988,26 +4056,26 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
        mvr = TYPE_MAIN_VARIANT (mvr);
       /* Opaque pointers are treated like void pointers.  */
       is_opaque_pointer = (targetm.vector_opaque_p (type)
-                           || targetm.vector_opaque_p (rhstype))
-        && TREE_CODE (ttl) == VECTOR_TYPE
-        && TREE_CODE (ttr) == VECTOR_TYPE;
-      
+                          || targetm.vector_opaque_p (rhstype))
+       && TREE_CODE (ttl) == VECTOR_TYPE
+       && TREE_CODE (ttr) == VECTOR_TYPE;
+
       /* C++ does not allow the implicit conversion void* -> T*.  However,
-         for the purpose of reducing the number of false positives, we
-         tolerate the special case of
+        for the purpose of reducing the number of false positives, we
+        tolerate the special case of
 
-                int *p = NULL;
+               int *p = NULL;
 
-         where NULL is typically defined in C to be '(void *) 0'.  */
+        where NULL is typically defined in C to be '(void *) 0'.  */
       if (VOID_TYPE_P (ttr) && rhs != null_pointer_node && !VOID_TYPE_P (ttl))
-        warning (OPT_Wc___compat, "request for implicit conversion from "
-                 "%qT to %qT not permitted in C++", rhstype, type);
+       warning (OPT_Wc___compat, "request for implicit conversion from "
+                "%qT to %qT not permitted in C++", rhstype, type);
 
       /* Check if the right-hand side has a format attribute but the
         left-hand side doesn't.  */
       if (warn_missing_format_attribute
          && check_missing_format_attribute (type, rhstype))
-        {
+       {
          switch (errtype)
          {
          case ic_argpass:
@@ -4036,7 +4104,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
            gcc_unreachable ();
          }
        }
-      
+
       /* Any non-function converts to a [const][volatile] void *
         and vice versa; otherwise, targets must be the same.
         Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
@@ -4190,31 +4258,6 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
 
   return error_mark_node;
 }
-
-/* Convert VALUE for assignment into inlined parameter PARM.  ARGNUM
-   is used for error and waring reporting and indicates which argument
-   is being processed.  */
-
-tree
-c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
-{
-  tree ret, type;
-
-  /* If FN was prototyped, the value has been converted already
-     in convert_arguments.  */
-  if (!value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
-    return value;
-
-  type = TREE_TYPE (parm);
-  ret = convert_for_assignment (type, value,
-                               ic_argpass_nonproto, fn,
-                               fn, argnum);
-  if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
-      && INTEGRAL_TYPE_P (type)
-      && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
-    ret = default_conversion (ret);
-  return ret;
-}
 \f
 /* If VALUE is a compound expr all of whose expressions are constant, then
    return its value.  Otherwise, return error_mark_node.
@@ -4270,7 +4313,8 @@ store_init_value (tree decl, tree init)
 
   /* ANSI wants warnings about out-of-range constant initializers.  */
   STRIP_TYPE_NOPS (value);
-  constant_expression_warning (value);
+  if (TREE_STATIC (decl)) 
+    constant_expression_warning (value);
 
   /* Check if we need to set array size from compound literal size.  */
   if (TREE_CODE (type) == ARRAY_TYPE
@@ -4284,16 +4328,18 @@ store_init_value (tree decl, tree init)
 
       if (TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
        {
-         tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
+         tree cldecl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
 
-         if (TYPE_DOMAIN (TREE_TYPE (decl)))
+         if (TYPE_DOMAIN (TREE_TYPE (cldecl)))
            {
              /* For int foo[] = (int [3]){1}; we need to set array size
                 now since later on array initializer will be just the
                 brace enclosed list of the compound literal.  */
-             TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (decl));
+             type = build_distinct_type_copy (TYPE_MAIN_VARIANT (type));
+             TREE_TYPE (decl) = type;
+             TYPE_DOMAIN (type) = TYPE_DOMAIN (TREE_TYPE (cldecl));
              layout_type (type);
-             layout_decl (decl, 0);
+             layout_decl (cldecl, 0);
            }
        }
     }
@@ -4309,7 +4355,7 @@ struct spelling
   int kind;
   union
     {
-      int i;
+      unsigned HOST_WIDE_INT i;
       const char *s;
     } u;
 };
@@ -4369,7 +4415,7 @@ push_member_name (tree decl)
 /* Push an array bounds on the stack.  Printed as [BOUNDS].  */
 
 static void
-push_array_bounds (int bounds)
+push_array_bounds (unsigned HOST_WIDE_INT bounds)
 {
   PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
 }
@@ -4404,7 +4450,7 @@ print_spelling (char *buffer)
   for (p = spelling_base; p < spelling; p++)
     if (p->kind == SPELLING_BOUNDS)
       {
-       sprintf (d, "[%d]", p->u.i);
+       sprintf (d, "[" HOST_WIDE_INT_PRINT_UNSIGNED "]", p->u.i);
        d += strlen (d);
       }
     else
@@ -4495,6 +4541,7 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
   tree inside_init = init;
 
   if (type == error_mark_node
+      || !init
       || init == error_mark_node
       || TREE_TYPE (init) == error_mark_node)
     return error_mark_node;
@@ -4575,7 +4622,7 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
      below and handle as a constructor.  */
   if (code == VECTOR_TYPE
       && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE
-      && vector_types_convertible_p (TREE_TYPE (inside_init), type)
+      && vector_types_convertible_p (TREE_TYPE (inside_init), type, true)
       && TREE_CONSTANT (inside_init))
     {
       if (TREE_CODE (inside_init) == VECTOR_CST
@@ -4639,12 +4686,14 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
           conversion.  */
        inside_init = convert (type, inside_init);
 
-      if (require_constant && !flag_isoc99
+      if (require_constant
+         && (code == VECTOR_TYPE || !flag_isoc99)
          && TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
        {
          /* As an extension, allow initializing objects with static storage
             duration with compound literals (which are then treated just as
-            the brace enclosed list they contain).  */
+            the brace enclosed list they contain).  Also allow this for
+            vectors, as we can only assign them with compound literals.  */
          tree decl = COMPOUND_LITERAL_EXPR_DECL (inside_init);
          inside_init = DECL_INITIAL (decl);
        }
@@ -5082,7 +5131,7 @@ really_start_incremental_init (tree type)
       /* Vectors are like simple fixed-size arrays.  */
       constructor_max_index =
        build_int_cst (NULL_TREE, TYPE_VECTOR_SUBPARTS (constructor_type) - 1);
-      constructor_index = convert (bitsizetype, bitsize_zero_node);
+      constructor_index = bitsize_zero_node;
       constructor_unfilled_index = constructor_index;
     }
   else
@@ -5199,7 +5248,7 @@ push_init_level (int implicit)
   else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
     {
       constructor_type = TREE_TYPE (constructor_type);
-      push_array_bounds (tree_low_cst (constructor_index, 0));
+      push_array_bounds (tree_low_cst (constructor_index, 1));
       constructor_depth++;
     }
 
@@ -5341,7 +5390,7 @@ pop_init_level (int implicit)
       else
        {
          gcc_assert (!TYPE_SIZE (constructor_type));
-         
+
          if (constructor_depth > 2)
            error_init ("initialization of flexible array member in a nested context");
          else if (pedantic)
@@ -5442,15 +5491,8 @@ pop_init_level (int implicit)
   constructor_stack = p->next;
   free (p);
 
-  if (ret.value == 0)
-    {
-      if (constructor_stack == 0)
-       {
-         ret.value = error_mark_node;
-         return ret;
-       }
-      return ret;
-    }
+  if (ret.value == 0 && constructor_stack == 0)
+    ret.value = error_mark_node;
   return ret;
 }
 
@@ -5664,6 +5706,8 @@ add_pending_init (tree purpose, tree value)
            {
              if (TREE_SIDE_EFFECTS (p->value))
                warning_init ("initialized field with side-effects overwritten");
+             else if (warn_override_init)
+               warning_init ("initialized field overwritten");
              p->value = value;
              return;
            }
@@ -5685,6 +5729,8 @@ add_pending_init (tree purpose, tree value)
            {
              if (TREE_SIDE_EFFECTS (p->value))
                warning_init ("initialized field with side-effects overwritten");
+             else if (warn_override_init)
+               warning_init ("initialized field overwritten");
              p->value = value;
              return;
            }
@@ -5958,7 +6004,7 @@ set_nonincremental_init_from_string (tree str)
          else if (bitpos == HOST_BITS_PER_WIDE_INT)
            {
              if (val[1] < 0)
-               val[0] = -1;
+               val[0] = -1;
            }
          else if (val[0] & (((HOST_WIDE_INT) 1)
                             << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
@@ -6157,6 +6203,8 @@ output_init_element (tree value, bool strict_string, tree type, tree field,
       if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
                                       constructor_elements)->value))
        warning_init ("initialized field with side-effects overwritten");
+      else if (warn_override_init)
+       warning_init ("initialized field overwritten");
 
       /* We can have just one union field set.  */
       constructor_elements = 0;
@@ -6364,7 +6412,7 @@ process_init_element (struct c_expr value)
       && integer_zerop (constructor_unfilled_index))
     {
       if (constructor_stack->replacement_value.value)
-        error_init ("excess elements in char array initializer");
+       error_init ("excess elements in char array initializer");
       constructor_stack->replacement_value = value;
       return;
     }
@@ -6467,10 +6515,10 @@ process_init_element (struct c_expr value)
            {
              /* For a record, keep track of end position of last field.  */
              if (DECL_SIZE (constructor_fields))
-               constructor_bit_index
+               constructor_bit_index
                  = size_binop (PLUS_EXPR,
-                               bit_position (constructor_fields),
-                               DECL_SIZE (constructor_fields));
+                               bit_position (constructor_fields),
+                               DECL_SIZE (constructor_fields));
 
              /* If the current field was the first one not yet written out,
                 it isn't now, so update.  */
@@ -6594,7 +6642,7 @@ process_init_element (struct c_expr value)
          /* Now output the actual element.  */
          if (value.value)
            {
-             push_array_bounds (tree_low_cst (constructor_index, 0));
+             push_array_bounds (tree_low_cst (constructor_index, 1));
              output_init_element (value.value, strict_string,
                                   elttype, constructor_index, 1);
              RESTORE_SPELLING_DEPTH (constructor_depth);
@@ -6613,8 +6661,8 @@ process_init_element (struct c_expr value)
        {
          tree elttype = TYPE_MAIN_VARIANT (TREE_TYPE (constructor_type));
 
-         /* Do a basic check of initializer size.  Note that vectors
-            always have a fixed size derived from their type.  */
+        /* Do a basic check of initializer size.  Note that vectors
+           always have a fixed size derived from their type.  */
          if (tree_int_cst_lt (constructor_max_index, constructor_index))
            {
              pedwarn_init ("excess elements in vector initializer");
@@ -6777,7 +6825,7 @@ build_asm_expr (tree string, tree outputs, tree inputs, tree clobbers,
            output = error_mark_node;
        }
       else
-        output = error_mark_node;
+       output = error_mark_node;
 
       TREE_VALUE (tail) = output;
     }
@@ -6904,8 +6952,10 @@ c_finish_return (tree retval)
   else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
     {
       current_function_returns_null = 1;
-      if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
+      if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
        pedwarn ("%<return%> with a value, in function returning void");
+      else if (pedantic)
+       pedwarn ("ISO C forbids %<return%> with expression, in function returning void");
     }
   else
     {
@@ -6955,7 +7005,7 @@ c_finish_return (tree retval)
              inner = TREE_OPERAND (inner, 0);
 
              while (REFERENCE_CLASS_P (inner)
-                    && TREE_CODE (inner) != INDIRECT_REF)
+                    && TREE_CODE (inner) != INDIRECT_REF)
                inner = TREE_OPERAND (inner, 0);
 
              if (DECL_P (inner)
@@ -7023,25 +7073,25 @@ struct c_switch *c_switch_stack;
 tree
 c_start_case (tree exp)
 {
-  enum tree_code code;
-  tree type, orig_type = error_mark_node;
+  tree orig_type = error_mark_node;
   struct c_switch *cs;
 
   if (exp != error_mark_node)
     {
-      code = TREE_CODE (TREE_TYPE (exp));
       orig_type = TREE_TYPE (exp);
 
-      if (!INTEGRAL_TYPE_P (orig_type)
-         && code != ERROR_MARK)
+      if (!INTEGRAL_TYPE_P (orig_type))
        {
-         error ("switch quantity not an integer");
+         if (orig_type != error_mark_node)
+           {
+             error ("switch quantity not an integer");
+             orig_type = error_mark_node;
+           }
          exp = integer_zero_node;
-         orig_type = error_mark_node;
        }
       else
        {
-         type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+         tree type = TYPE_MAIN_VARIANT (orig_type);
 
          if (!in_system_header
              && (type == long_integer_type_node
@@ -7050,7 +7100,6 @@ c_start_case (tree exp)
                     "converted to %<int%> in ISO C");
 
          exp = default_conversion (exp);
-         type = TREE_TYPE (exp);
        }
     }
 
@@ -7186,7 +7235,7 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
                  &if_locus);
     }
 
-  empty_body_warning (then_block, else_block);
+  empty_if_body_warning (then_block, else_block);
 
   stmt = build3 (COND_EXPR, void_type_node, cond, then_block, else_block);
   SET_EXPR_LOCATION (stmt, if_locus);
@@ -7218,41 +7267,41 @@ c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
   else
     {
       tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+
       /* If we have an exit condition, then we build an IF with gotos either
-         out of the loop, or to the top of it.  If there's no exit condition,
-         then we just build a jump back to the top.  */
+        out of the loop, or to the top of it.  If there's no exit condition,
+        then we just build a jump back to the top.  */
       exit = build_and_jump (&LABEL_EXPR_LABEL (top));
+
       if (cond && !integer_nonzerop (cond))
-        {
-          /* Canonicalize the loop condition to the end.  This means
-             generating a branch to the loop condition.  Reuse the
-             continue label, if possible.  */
-          if (cond_is_first)
-            {
-              if (incr || !clab)
-                {
-                  entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
-                  t = build_and_jump (&LABEL_EXPR_LABEL (entry));
-                }
-              else
-                t = build1 (GOTO_EXPR, void_type_node, clab);
+       {
+         /* Canonicalize the loop condition to the end.  This means
+            generating a branch to the loop condition.  Reuse the
+            continue label, if possible.  */
+         if (cond_is_first)
+           {
+             if (incr || !clab)
+               {
+                 entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+                 t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+               }
+             else
+               t = build1 (GOTO_EXPR, void_type_node, clab);
              SET_EXPR_LOCATION (t, start_locus);
-              add_stmt (t);
-            }
+             add_stmt (t);
+           }
+
          t = build_and_jump (&blab);
-          exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
+         exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
          if (cond_is_first)
-            SET_EXPR_LOCATION (exit, start_locus);
+           SET_EXPR_LOCATION (exit, start_locus);
          else
-            SET_EXPR_LOCATION (exit, input_location);
-        }
+           SET_EXPR_LOCATION (exit, input_location);
+       }
+
       add_stmt (top);
     }
+
   if (body)
     add_stmt (body);
   if (clab)
@@ -7295,7 +7344,7 @@ c_finish_bc_stmt (tree *label_p, bool is_break)
       if (is_break)
        error ("break statement not within loop or switch");
       else
-        error ("continue statement not within a loop");
+       error ("continue statement not within a loop");
       return NULL_TREE;
 
     case 1:
@@ -7323,10 +7372,10 @@ emit_side_effect_warnings (tree expr)
   else if (!TREE_SIDE_EFFECTS (expr))
     {
       if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr))
-       warning (0, "%Hstatement with no effect",
+       warning (OPT_Wunused_value, "%Hstatement with no effect",
                 EXPR_HAS_LOCATION (expr) ? EXPR_LOCUS (expr) : &input_location);
     }
-  else if (warn_unused_value)
+  else
     warn_if_unused_value (expr, input_location);
 }
 
@@ -7351,7 +7400,7 @@ c_process_expr_stmt (tree expr)
      Warnings for statement expressions will be emitted later, once we figure
      out which is the result.  */
   if (!STATEMENT_LIST_STMT_EXPR (cur_stmt_list)
-      && (extra_warnings || warn_unused_value))
+      && warn_unused_value)
     emit_side_effect_warnings (expr);
 
   /* If the expression is not of a type to which we cannot assign a line
@@ -7359,7 +7408,7 @@ c_process_expr_stmt (tree expr)
   if (DECL_P (expr) || CONSTANT_CLASS_P (expr))
     expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr);
 
-  if (EXPR_P (expr))
+  if (CAN_HAVE_LOCATION_P (expr))
     SET_EXPR_LOCATION (expr, input_location);
 
   return expr;
@@ -7467,7 +7516,7 @@ c_finish_stmt_expr (tree body)
 
       /* If we're supposed to generate side effects warnings, process
         all of the statements except the last.  */
-      if (extra_warnings || warn_unused_value)
+      if (warn_unused_value)
        {
          for (i = tsi_start (last); !tsi_one_before_end_p (i); tsi_next (&i))
            emit_side_effect_warnings (tsi_stmt (i));
@@ -7496,7 +7545,7 @@ c_finish_stmt_expr (tree body)
     {
       /* Do not warn if the return value of a statement expression is
         unused.  */
-      if (EXPR_P (last))
+      if (CAN_HAVE_LOCATION_P (last))
        TREE_NO_WARNING (last) = 1;
       return last;
     }
@@ -7538,6 +7587,11 @@ c_begin_vm_scope (unsigned int scope)
   struct c_label_list *glist;
 
   gcc_assert (scope > 0);
+
+  /* At file_scope, we don't have to do any processing.  */
+  if (label_context_stack_vm == NULL)
+    return;
+
   if (c_switch_stack && !c_switch_stack->blocked_vm)
     c_switch_stack->blocked_vm = scope;
   for (glist = label_context_stack_vm->labels_used;
@@ -7800,10 +7854,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     case FLOOR_DIV_EXPR:
     case ROUND_DIV_EXPR:
     case EXACT_DIV_EXPR:
-      /* Floating point division by zero is a legitimate way to obtain
-        infinities and NaNs.  */
-      if (skip_evaluation == 0 && integer_zerop (op1))
-       warning (OPT_Wdiv_by_zero, "division by zero");
+      warn_for_div_by_zero (op1);
 
       if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
           || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
@@ -7843,8 +7894,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
 
     case TRUNC_MOD_EXPR:
     case FLOOR_MOD_EXPR:
-      if (skip_evaluation == 0 && integer_zerop (op1))
-       warning (OPT_Wdiv_by_zero, "division by zero");
+      warn_for_div_by_zero (op1);
 
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
        {
@@ -7983,18 +8033,16 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
        {
          if (TREE_CODE (op0) == ADDR_EXPR
-             && DECL_P (TREE_OPERAND (op0, 0)) 
-             && !DECL_WEAK (TREE_OPERAND (op0, 0)))
-           warning (OPT_Walways_true, "the address of %qD will never be NULL",
+             && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+           warning (OPT_Waddress, "the address of %qD will never be NULL",
                     TREE_OPERAND (op0, 0));
          result_type = type0;
        }
       else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
        {
-         if (TREE_CODE (op1) == ADDR_EXPR 
-             && DECL_P (TREE_OPERAND (op1, 0))
-             && !DECL_WEAK (TREE_OPERAND (op1, 0)))
-           warning (OPT_Walways_true, "the address of %qD will never be NULL",
+         if (TREE_CODE (op1) == ADDR_EXPR
+             && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+           warning (OPT_Waddress, "the address of %qD will never be NULL",
                     TREE_OPERAND (op1, 0));
          result_type = type1;
        }
@@ -8072,7 +8120,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
          || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
                                                    TREE_TYPE (type1))))
     {
-      binary_op_error (code);
+      binary_op_error (code, type0, type1);
       return error_mark_node;
     }
 
@@ -8085,7 +8133,11 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
 
       if (shorten || common || short_compare)
-       result_type = c_common_type (type0, type1);
+       {
+         result_type = c_common_type (type0, type1);
+         if (result_type == error_mark_node)
+           return error_mark_node;
+       }
 
       /* For certain operations (which identify themselves by shorten != 0)
         if both args were extended from the same smaller type,
@@ -8101,12 +8153,35 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       if (shorten && none_complex)
        {
          int unsigned0, unsigned1;
-         tree arg0 = get_narrower (op0, &unsigned0);
-         tree arg1 = get_narrower (op1, &unsigned1);
-         /* UNS is 1 if the operation to be done is an unsigned one.  */
-         int uns = TYPE_UNSIGNED (result_type);
+         tree arg0, arg1;
+         int uns;
          tree type;
 
+         /* Cast OP0 and OP1 to RESULT_TYPE.  Doing so prevents
+            excessive narrowing when we call get_narrower below.  For
+            example, suppose that OP0 is of unsigned int extended
+            from signed char and that RESULT_TYPE is long long int.
+            If we explicitly cast OP0 to RESULT_TYPE, OP0 would look
+            like
+
+              (long long int) (unsigned int) signed_char
+
+            which get_narrower would narrow down to
+
+              (unsigned int) signed char
+
+            If we do not cast OP0 first, get_narrower would return
+            signed_char, which is inconsistent with the case of the
+            explicit cast.  */
+         op0 = convert (result_type, op0);
+         op1 = convert (result_type, op1);
+
+         arg0 = get_narrower (op0, &unsigned0);
+         arg1 = get_narrower (op1, &unsigned1);
+
+         /* UNS is 1 if the operation to be done is an unsigned one.  */
+         uns = TYPE_UNSIGNED (result_type);
+
          final_type = result_type;
 
          /* Handle the case that OP0 (or OP1) does not *contain* a conversion
@@ -8239,12 +8314,13 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                 all the values of the unsigned type.  */
              if (!TYPE_UNSIGNED (result_type))
                /* OK */;
-              /* Do not warn if both operands are the same signedness.  */
-              else if (op0_signed == op1_signed)
-                /* OK */;
+             /* Do not warn if both operands are the same signedness.  */
+             else if (op0_signed == op1_signed)
+               /* OK */;
              else
                {
                  tree sop, uop;
+                 bool ovf;
 
                  if (op0_signed)
                    sop = xop0, uop = xop1;
@@ -8256,7 +8332,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                     constant expression involving such literals or a
                     conditional expression involving such literals)
                     and it is non-negative.  */
-                 if (tree_expr_nonnegative_p (sop))
+                 if (tree_expr_nonnegative_warnv_p (sop, &ovf))
                    /* OK */;
                  /* Do not warn if the comparison is an equality operation,
                     the unsigned quantity is an integral constant, and it
@@ -8344,16 +8420,16 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
 
   if (!result_type)
     {
-      binary_op_error (code);
+      binary_op_error (code, TREE_TYPE (op0), TREE_TYPE (op1));
       return error_mark_node;
     }
 
   if (!converted)
     {
       if (TREE_TYPE (op0) != result_type)
-       op0 = convert (result_type, op0);
+       op0 = convert_and_check (result_type, op0);
       if (TREE_TYPE (op1) != result_type)
-       op1 = convert (result_type, op1);
+       op1 = convert_and_check (result_type, op1);
 
       /* This can happen if one operand has a vector type, and the other
         has a different type.  */
@@ -8431,9 +8507,8 @@ c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
   else
     return expr;
 }
-
 \f
-/* Like c_begin_compound_stmt, except force the retension of the BLOCK.  */
+/* Like c_begin_compound_stmt, except force the retention of the BLOCK.  */
 
 tree
 c_begin_omp_parallel (void)