OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index 61f385d..e9f3fc7 100644 (file)
@@ -470,7 +470,7 @@ composite_type (tree t1, tree t2)
                      {
                        TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
                                                         TREE_VALUE (p2));
-                       pedwarn (OPT_pedantic, 
+                       pedwarn (input_location, OPT_pedantic, 
                                 "function types not truly compatible in ISO C");
                        goto parm_done;
                      }
@@ -495,7 +495,7 @@ composite_type (tree t1, tree t2)
                      {
                        TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
                                                         TREE_VALUE (p1));
-                       pedwarn (OPT_pedantic, 
+                       pedwarn (input_location, OPT_pedantic, 
                                 "function types not truly compatible in ISO C");
                        goto parm_done;
                      }
@@ -1040,7 +1040,7 @@ comp_target_types (tree ttl, tree ttr)
   val = comptypes (mvl, mvr);
 
   if (val == 2)
-    pedwarn (OPT_pedantic, "types are not quite compatible");
+    pedwarn (input_location, OPT_pedantic, "types are not quite compatible");
   return val;
 }
 \f
@@ -1363,7 +1363,7 @@ function_types_compatible_p (const_tree f1, const_tree f2)
   /* 'volatile' qualifiers on a function's return type used to mean
      the function is noreturn.  */
   if (TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
-    pedwarn (0, "function return types not compatible due to %<volatile%>");
+    pedwarn (input_location, 0, "function return types not compatible due to %<volatile%>");
   if (TYPE_VOLATILE (ret1))
     ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
                                 TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
@@ -1967,13 +1967,16 @@ build_component_ref (tree datum, tree component)
 \f
 /* Given an expression PTR for a pointer, return an expression
    for the value pointed to.
-   ERRORSTRING is the name of the operator to appear in error messages.  */
+   ERRORSTRING is the name of the operator to appear in error messages.
+
+   LOC is the location to use for the generated tree.  */
 
 tree
-build_indirect_ref (tree ptr, const char *errorstring)
+build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
 {
   tree pointer = default_conversion (ptr);
   tree type = TREE_TYPE (pointer);
+  tree ref;
 
   if (TREE_CODE (type) == POINTER_TYPE)
     {
@@ -1992,11 +1995,14 @@ build_indirect_ref (tree ptr, const char *errorstring)
       if (TREE_CODE (pointer) == ADDR_EXPR
          && (TREE_TYPE (TREE_OPERAND (pointer, 0))
              == TREE_TYPE (type)))
-       return TREE_OPERAND (pointer, 0);
+       {
+         ref = TREE_OPERAND (pointer, 0);
+         protected_set_expr_location (ref, loc);
+         return ref;
+       }
       else
        {
          tree t = TREE_TYPE (type);
-         tree ref;
 
          ref = build1 (INDIRECT_REF, t, pointer);
 
@@ -2019,6 +2025,7 @@ build_indirect_ref (tree ptr, const char *errorstring)
          TREE_SIDE_EFFECTS (ref)
            = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
          TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
+         protected_set_expr_location (ref, loc);
          return ref;
        }
     }
@@ -2034,11 +2041,14 @@ build_indirect_ref (tree ptr, const char *errorstring)
    If A is a variable or a member, we generate a primitive ARRAY_REF.
    This avoids forcing the array out of registers, and can work on
    arrays that are not lvalues (for example, members of structures returned
-   by functions).  */
+   by functions).
+
+   LOC is the location to use for the returned expression.  */
 
 tree
-build_array_ref (tree array, tree index)
+build_array_ref (tree array, tree index, location_t loc)
 {
+  tree ret;
   bool swapped = false;
   if (TREE_TYPE (array) == error_mark_node
       || TREE_TYPE (index) == error_mark_node)
@@ -2051,7 +2061,7 @@ build_array_ref (tree array, tree index)
       if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
          && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
        {
-         error ("subscripted value is neither array nor pointer");
+         error_at (loc, "subscripted value is neither array nor pointer");
          return error_mark_node;
        }
       temp = array;
@@ -2062,13 +2072,13 @@ build_array_ref (tree array, tree index)
 
   if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
     {
-      error ("array subscript is not an integer");
+      error_at (loc, "array subscript is not an integer");
       return error_mark_node;
     }
 
   if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE)
     {
-      error ("subscripted value is pointer to function");
+      error_at (loc, "subscripted value is pointer to function");
       return error_mark_node;
     }
 
@@ -2115,10 +2125,10 @@ build_array_ref (tree array, tree index)
          while (TREE_CODE (foo) == COMPONENT_REF)
            foo = TREE_OPERAND (foo, 0);
          if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
-           pedwarn (OPT_pedantic, 
+           pedwarn (loc, OPT_pedantic, 
                     "ISO C forbids subscripting %<register%> array");
          else if (!flag_isoc99 && !lvalue_p (foo))
-           pedwarn (OPT_pedantic, 
+           pedwarn (loc, OPT_pedantic, 
                     "ISO C90 forbids subscripting non-lvalue array");
        }
 
@@ -2139,7 +2149,9 @@ build_array_ref (tree array, tree index)
               in an inline function.
               Hope it doesn't break something else.  */
            | TREE_THIS_VOLATILE (array));
-      return require_complete_type (fold (rval));
+      ret = require_complete_type (fold (rval));
+      protected_set_expr_location (ret, loc);
+      return ret;
     }
   else
     {
@@ -2152,7 +2164,7 @@ build_array_ref (tree array, tree index)
       gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
 
       return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
-                                "array indexing");
+                                "array indexing", loc);
     }
 }
 \f
@@ -2233,8 +2245,8 @@ build_external_ref (tree id, int fun, location_t loc)
           && (TREE_CODE (ref) != VAR_DECL || TREE_STATIC (ref))
           && ! TREE_PUBLIC (ref)
           && DECL_CONTEXT (ref) != current_function_decl)
-    pedwarn (0, "%H%qD is static but used in inline function %qD "
-             "which is not static", &loc, ref, current_function_decl);
+    pedwarn (loc, 0, "%qD is static but used in inline function %qD "
+            "which is not static", ref, current_function_decl);
 
   return ref;
 }
@@ -2411,7 +2423,7 @@ build_function_call (tree function, tree params)
       if (warning (0, "function called through a non-compatible type"))
        /* We can, however, treat "undefined" any way we please.
           Call abort to encourage the user to fix the program.  */
-       inform ("if this code is reached, the program will abort");
+       inform (input_location, "if this code is reached, the program will abort");
 
       if (VOID_TYPE_P (return_type))
        return trap;
@@ -2457,7 +2469,7 @@ build_function_call (tree function, tree params)
       if (TREE_CONSTANT (result)
          && (name == NULL_TREE
              || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
-       pedwarn_init (0, "initializer element is not constant");
+       pedwarn_init (input_location, 0, "initializer element is not constant");
     }
   else
     result = fold_build_call_array (TREE_TYPE (fntype),
@@ -2724,16 +2736,20 @@ convert_arguments (int nargs, tree *argarray,
 /* This is the entry point used by the parser to build unary operators
    in the input.  CODE, a tree_code, specifies the unary operator, and
    ARG is the operand.  For unary plus, the C parser currently uses
-   CONVERT_EXPR for code.  */
+   CONVERT_EXPR for code.
+
+   LOC is the location to use for the tree generated.
+*/
 
 struct c_expr
-parser_build_unary_op (enum tree_code code, struct c_expr arg)
+parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
 {
   struct c_expr result;
 
   result.original_code = ERROR_MARK;
   result.value = build_unary_op (code, arg.value, 0);
-  
+  protected_set_expr_location (result.value, loc);
+
   if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
     overflow_warning (result.value);
 
@@ -2802,10 +2818,10 @@ pointer_diff (tree op0, tree op1)
   tree orig_op1 = op1;
 
   if (TREE_CODE (target_type) == VOID_TYPE)
-    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+    pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
             "pointer of type %<void *%> used in subtraction");
   if (TREE_CODE (target_type) == FUNCTION_TYPE)
-    pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+    pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
             "pointer to a function used in subtraction");
 
   /* If the conversion to ptrdiff_type does anything like widening or
@@ -2948,7 +2964,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
       else if (typecode == COMPLEX_TYPE)
        {
          code = CONJ_EXPR;
-         pedwarn (OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic, 
                   "ISO C does not support %<~%> for complex conjugation");
          if (!noconvert)
            arg = default_conversion (arg);
@@ -3020,8 +3036,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
        {
          tree real, imag;
 
-         pedwarn (OPT_pedantic, "ISO C does not support %<++%> and %<--%>"
-                  " on complex types");
+         pedwarn (input_location, OPT_pedantic, 
+                  "ISO C does not support %<++%> and %<--%> on complex types");
 
          arg = stabilize_reference (arg);
          real = build_unary_op (REALPART_EXPR, arg, 1);
@@ -3070,10 +3086,10 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
                     || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
              {
                if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
-                 pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+                 pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
                           "wrong type argument to increment");
                else
-                 pedwarn (pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
+                 pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith, 
                           "wrong type argument to decrement");
              }
 
@@ -3349,7 +3365,7 @@ c_mark_addressable (tree exp)
                  ("global register variable %qD used in nested function", x);
                return false;
              }
-           pedwarn (0, "register variable %qD used in nested function", x);
+           pedwarn (input_location, 0, "register variable %qD used in nested function", x);
          }
        else if (C_DECL_REGISTER (x))
          {
@@ -3457,7 +3473,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
   else if (code1 == VOID_TYPE || code2 == VOID_TYPE)
     {
       if (code1 != VOID_TYPE || code2 != VOID_TYPE)
-       pedwarn (OPT_pedantic, 
+       pedwarn (input_location, OPT_pedantic, 
                 "ISO C forbids conditional expr with only one void side");
       result_type = void_type_node;
     }
@@ -3472,7 +3488,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
       else if (VOID_TYPE_P (TREE_TYPE (type1)))
        {
          if (TREE_CODE (TREE_TYPE (type2)) == FUNCTION_TYPE)
-           pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
+           pedwarn (input_location, OPT_pedantic, 
+                    "ISO C forbids conditional expr between "
                     "%<void *%> and function pointer");
          result_type = build_pointer_type (qualify_type (TREE_TYPE (type1),
                                                          TREE_TYPE (type2)));
@@ -3480,21 +3497,24 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
       else if (VOID_TYPE_P (TREE_TYPE (type2)))
        {
          if (TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)
-           pedwarn (OPT_pedantic, "ISO C forbids conditional expr between "
+           pedwarn (input_location, OPT_pedantic, 
+                    "ISO C forbids conditional expr between "
                     "%<void *%> and function pointer");
          result_type = build_pointer_type (qualify_type (TREE_TYPE (type2),
                                                          TREE_TYPE (type1)));
        }
       else
        {
-         pedwarn (0, "pointer type mismatch in conditional expression");
+         pedwarn (input_location, 0, 
+                  "pointer type mismatch in conditional expression");
          result_type = build_pointer_type (void_type_node);
        }
     }
   else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op2))
-       pedwarn (0, "pointer/integer type mismatch in conditional expression");
+       pedwarn (input_location, 0, 
+                "pointer/integer type mismatch in conditional expression");
       else
        {
          op2 = null_pointer_node;
@@ -3504,7 +3524,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
   else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE)
     {
       if (!null_pointer_constant_p (orig_op1))
-       pedwarn (0, "pointer/integer type mismatch in conditional expression");
+       pedwarn (input_location, 0, 
+                "pointer/integer type mismatch in conditional expression");
       else
        {
          op1 = null_pointer_node;
@@ -3617,7 +3638,7 @@ build_c_cast (tree type, tree expr)
     {
       if (TREE_CODE (type) == RECORD_TYPE
          || TREE_CODE (type) == UNION_TYPE)
-       pedwarn (OPT_pedantic, 
+       pedwarn (input_location, OPT_pedantic, 
                 "ISO C forbids casting nonscalar to the same type");
     }
   else if (TREE_CODE (type) == UNION_TYPE)
@@ -3634,7 +3655,8 @@ build_c_cast (tree type, tree expr)
        {
          tree t;
 
-         pedwarn (OPT_pedantic, "ISO C forbids casts to union type");
+         pedwarn (input_location, OPT_pedantic,
+                  "ISO C forbids casts to union type");
          t = digest_init (type,
                           build_constructor_single (type, field, value),
                           true, 0);
@@ -3745,7 +3767,7 @@ build_c_cast (tree type, tree expr)
          && TREE_CODE (otype) == POINTER_TYPE
          && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
          && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
-       pedwarn (OPT_pedantic, "ISO C forbids "
+       pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                 "conversion of function pointer to object pointer type");
 
       if (pedantic
@@ -3754,7 +3776,7 @@ build_c_cast (tree type, tree expr)
          && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
          && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
          && !null_pointer_constant_p (value))
-       pedwarn (OPT_pedantic, "ISO C forbids "
+       pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                 "conversion of object pointer to function pointer type");
 
       ovalue = value;
@@ -3946,28 +3968,31 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
   /* This macro is used to emit diagnostics to ensure that all format
      strings are complete sentences, visible to gettext and checked at
      compile time.  */
-#define WARN_FOR_ASSIGNMENT(AR, AS, IN, RE)    \
-  do {                                         \
-    switch (errtype)                           \
-      {                                                \
-      case ic_argpass:                         \
-       pedwarn (0, AR, parmnum, rname);        \
-       break;                                  \
-      case ic_argpass_nonproto:                        \
-       warning (0, AR, parmnum, rname);        \
-       break;                                  \
-      case ic_assign:                          \
-       pedwarn (0, AS);                        \
-       break;                                  \
-      case ic_init:                            \
-       pedwarn (0, IN);                        \
-       break;                                  \
-      case ic_return:                          \
-       pedwarn (0, RE);                        \
-       break;                                  \
-      default:                                 \
-       gcc_unreachable ();                     \
-      }                                                \
+#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE)               \
+  do {                                                                   \
+    switch (errtype)                                                     \
+      {                                                                  \
+      case ic_argpass:                                                   \
+        if (pedwarn (LOCATION, OPT, AR, parmnum, rname))                 \
+          inform (fundecl ? DECL_SOURCE_LOCATION (fundecl) : LOCATION,   \
+                  "expected %qT but argument is of type %qT",            \
+                  type, rhstype);                                        \
+        break;                                                           \
+      case ic_argpass_nonproto:                                          \
+        warning (OPT, AR, parmnum, rname);                               \
+        break;                                                           \
+      case ic_assign:                                                    \
+        pedwarn (LOCATION, OPT, AS);                                     \
+        break;                                                           \
+      case ic_init:                                                      \
+        pedwarn (LOCATION, OPT, IN);                                     \
+        break;                                                           \
+      case ic_return:                                                    \
+        pedwarn (LOCATION, OPT, RE);                                     \
+        break;                                                           \
+      default:                                                           \
+        gcc_unreachable ();                                              \
+      }                                                                  \
   } while (0)
 
   STRIP_TYPE_NOPS (rhs);
@@ -4145,7 +4170,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                     function where an ordinary one is wanted, but not
                     vice-versa.  */
                  if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
-                   WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE "
+                   WARN_FOR_ASSIGNMENT (input_location, 0,
+                                        G_("passing argument %d of %qE "
                                            "makes qualified function "
                                            "pointer from unqualified"),
                                         G_("assignment makes qualified "
@@ -4158,7 +4184,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                                            "pointer from unqualified"));
                }
              else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
-               WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE discards "
+               WARN_FOR_ASSIGNMENT (input_location, 0,
+                                    G_("passing argument %d of %qE discards "
                                        "qualifiers from pointer target type"),
                                     G_("assignment discards qualifiers "
                                        "from pointer target type"),
@@ -4171,7 +4198,7 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
            }
 
          if (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl))
-           pedwarn (OPT_pedantic, 
+           pedwarn (input_location, OPT_pedantic, 
                     "ISO C prohibits argument conversion to union type");
 
          rhs = fold_convert (TREE_TYPE (memb), rhs);
@@ -4257,7 +4284,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                  (VOID_TYPE_P (ttr)
                   && !null_pointer_constant_p (rhs)
                   && TREE_CODE (ttl) == FUNCTION_TYPE)))
-           WARN_FOR_ASSIGNMENT (G_("ISO C forbids passing argument %d of "
+           WARN_FOR_ASSIGNMENT (input_location, OPT_pedantic,
+                                G_("ISO C forbids passing argument %d of "
                                    "%qE between function pointer "
                                    "and %<void *%>"),
                                 G_("ISO C forbids assignment between "
@@ -4277,7 +4305,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                     qualifier are acceptable if the 'volatile' has been added
                     in by the Objective-C EH machinery.  */
                  if (!objc_type_quals_match (ttl, ttr))
-                   WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE discards "
+                   WARN_FOR_ASSIGNMENT (input_location, 0,
+                                        G_("passing argument %d of %qE discards "
                                            "qualifiers from pointer target type"),
                                         G_("assignment discards qualifiers "
                                            "from pointer target type"),
@@ -4293,7 +4322,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                ;
              /* If there is a mismatch, do warn.  */
              else if (warn_pointer_sign)
-               WARN_FOR_ASSIGNMENT (G_("pointer targets in passing argument "
+               WARN_FOR_ASSIGNMENT (input_location, OPT_Wpointer_sign,
+                                    G_("pointer targets in passing argument "
                                        "%d of %qE differ in signedness"),
                                     G_("pointer targets in assignment "
                                        "differ in signedness"),
@@ -4310,7 +4340,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
                 it is okay to use a const or volatile function
                 where an ordinary one is wanted, but not vice-versa.  */
              if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
-               WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes "
+               WARN_FOR_ASSIGNMENT (input_location, 0,
+                                    G_("passing argument %d of %qE makes "
                                        "qualified function pointer "
                                        "from unqualified"),
                                     G_("assignment makes qualified function "
@@ -4324,7 +4355,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
       else
        /* Avoid warning about the volatile ObjC EH puts on decls.  */
        if (!objc_ok)
-         WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE from "
+         WARN_FOR_ASSIGNMENT (input_location, 0,
+                              G_("passing argument %d of %qE from "
                                  "incompatible pointer type"),
                               G_("assignment from incompatible pointer type"),
                               G_("initialization from incompatible "
@@ -4346,7 +4378,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
         or one that results from arithmetic, even including
         a cast to integer type.  */
       if (!null_pointer_constant_p (rhs))
-       WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes "
+       WARN_FOR_ASSIGNMENT (input_location, 0,
+                            G_("passing argument %d of %qE makes "
                                "pointer from integer without a cast"),
                             G_("assignment makes pointer from integer "
                                "without a cast"),
@@ -4359,7 +4392,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
     }
   else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
     {
-      WARN_FOR_ASSIGNMENT (G_("passing argument %d of %qE makes integer "
+      WARN_FOR_ASSIGNMENT (input_location, 0,
+                          G_("passing argument %d of %qE makes integer "
                              "from pointer without a cast"),
                           G_("assignment makes integer from pointer "
                              "without a cast"),
@@ -4623,14 +4657,14 @@ error_init (const char *msgid)
    component name is taken from the spelling stack.  */
 
 void
-pedwarn_init (int opt, const char *msgid)
+pedwarn_init (location_t location, int opt, const char *msgid)
 {
   char *ofwhat;
 
-  pedwarn (opt, "%s", _(msgid));
+  pedwarn (location, opt, "%s", _(msgid));
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
   if (*ofwhat)
-    pedwarn (opt, "(near initialization for %qs)", ofwhat);
+    pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
 }
 
 /* Issue a warning for a bad initializer component.  
@@ -4661,7 +4695,7 @@ maybe_warn_string_init (tree type, struct c_expr expr)
       && TREE_CODE (type) == ARRAY_TYPE
       && TREE_CODE (expr.value) == STRING_CST
       && expr.original_code != STRING_CST)
-    pedwarn_init (OPT_pedantic, 
+    pedwarn_init (input_location, OPT_pedantic, 
                  "array initialized from parenthesized string constant");
 }
 
@@ -4755,7 +4789,8 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
                                       TREE_STRING_LENGTH (inside_init)
                                       - (TYPE_PRECISION (typ1)
                                          / BITS_PER_UNIT)))
-           pedwarn_init (0, "initializer-string for array of chars is too long");
+           pedwarn_init (input_location, 0, 
+                         "initializer-string for array of chars is too long");
 
          return inside_init;
        }
@@ -4801,6 +4836,9 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
        }
     }
 
+  if (warn_sequence_point)
+    verify_sequence_points (inside_init);
+
   /* Any type can be initialized
      from an expression of the same type, optionally with braces.  */
 
@@ -4870,7 +4908,8 @@ digest_init (tree type, tree init, bool strict_string, int require_constant)
          if (inside_init == error_mark_node)
            error_init ("initializer element is not constant");
          else
-           pedwarn_init (OPT_pedantic, "initializer element is not constant");
+           pedwarn_init (input_location, OPT_pedantic,
+                         "initializer element is not constant");
          if (flag_pedantic_errors)
            inside_init = error_mark_node;
        }
@@ -5544,7 +5583,8 @@ pop_init_level (int implicit)
          if (constructor_depth > 2)
            error_init ("initialization of flexible array member in a nested context");
          else
-           pedwarn_init (OPT_pedantic, "initialization of a flexible array member");
+           pedwarn_init (input_location, OPT_pedantic,
+                         "initialization of a flexible array member");
 
          /* We have already issued an error message for the existence
             of a flexible array member not at the end of the structure.
@@ -6281,7 +6321,8 @@ output_init_element (tree value, bool strict_string, tree type, tree field,
          value = error_mark_node;
        }
       else if (require_constant_elements)
-       pedwarn (0, "initializer element is not computable at load time");
+       pedwarn (input_location, 0,
+                "initializer element is not computable at load time");
     }
 
   /* If this field is empty (and not at the end of structure),
@@ -6608,7 +6649,8 @@ process_init_element (struct c_expr value)
 
          if (constructor_fields == 0)
            {
-             pedwarn_init (0, "excess elements in struct initializer");
+             pedwarn_init (input_location, 0,
+                           "excess elements in struct initializer");
              break;
            }
 
@@ -6691,7 +6733,8 @@ process_init_element (struct c_expr value)
 
          if (constructor_fields == 0)
            {
-             pedwarn_init (0, "excess elements in union initializer");
+             pedwarn_init (input_location, 0,
+                           "excess elements in union initializer");
              break;
            }
 
@@ -6778,7 +6821,8 @@ process_init_element (struct c_expr value)
              && (tree_int_cst_lt (constructor_max_index, constructor_index)
                  || integer_all_onesp (constructor_max_index)))
            {
-             pedwarn_init (0, "excess elements in array initializer");
+             pedwarn_init (input_location, 0,
+                           "excess elements in array initializer");
              break;
            }
 
@@ -6808,7 +6852,8 @@ process_init_element (struct c_expr value)
            always have a fixed size derived from their type.  */
          if (tree_int_cst_lt (constructor_max_index, constructor_index))
            {
-             pedwarn_init (0, "excess elements in vector initializer");
+             pedwarn_init (input_location, 0,
+                           "excess elements in vector initializer");
              break;
            }
 
@@ -6832,7 +6877,8 @@ process_init_element (struct c_expr value)
       else if (constructor_type != error_mark_node
               && constructor_fields == 0)
        {
-         pedwarn_init (0, "excess elements in scalar initializer");
+         pedwarn_init (input_location, 0,
+                       "excess elements in scalar initializer");
          break;
        }
       else
@@ -7063,7 +7109,7 @@ c_finish_goto_label (tree label)
 tree
 c_finish_goto_ptr (tree expr)
 {
-  pedwarn (OPT_pedantic, "ISO C forbids %<goto *expr;%>");
+  pedwarn (input_location, OPT_pedantic, "ISO C forbids %<goto *expr;%>");
   expr = convert (ptr_type_node, expr);
   return add_stmt (build1 (GOTO_EXPR, void_type_node, expr));
 }
@@ -7086,7 +7132,7 @@ c_finish_return (tree retval)
       if ((warn_return_type || flag_isoc99)
          && valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
        {
-         pedwarn_c99 (flag_isoc99 ? 0 : OPT_Wreturn_type, 
+         pedwarn_c99 (input_location, flag_isoc99 ? 0 : OPT_Wreturn_type, 
                       "%<return%> with no value, in "
                       "function returning non-void");
          no_warning = true;
@@ -7096,9 +7142,10 @@ c_finish_return (tree retval)
     {
       current_function_returns_null = 1;
       if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
-       pedwarn (0, "%<return%> with a value, in function returning void");
+       pedwarn (input_location, 0, 
+                "%<return%> with a value, in function returning void");
       else 
-       pedwarn (OPT_pedantic, "ISO C forbids "
+       pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                 "%<return%> with expression, in function returning void");
     }
   else
@@ -7166,6 +7213,9 @@ c_finish_return (tree retval)
        }
 
       retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
+
+      if (warn_sequence_point)
+       verify_sequence_points (retval);
     }
 
   ret_stmt = build_stmt (RETURN_EXPR, retval);
@@ -7243,6 +7293,9 @@ c_start_case (tree exp)
                     "converted to %<int%> in ISO C");
 
          exp = default_conversion (exp);
+
+         if (warn_sequence_point)
+           verify_sequence_points (exp);
        }
     }
 
@@ -8169,20 +8222,21 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
                 whose value is 0 but which isn't a valid null ptr const.  */
              if (pedantic && !null_pointer_constant_p (orig_op0)
                  && TREE_CODE (tt1) == FUNCTION_TYPE)
-               pedwarn (OPT_pedantic, "ISO C forbids "
+               pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                         "comparison of %<void *%> with function pointer");
            }
          else if (VOID_TYPE_P (tt1))
            {
              if (pedantic && !null_pointer_constant_p (orig_op1)
                  && TREE_CODE (tt0) == FUNCTION_TYPE)
-               pedwarn (OPT_pedantic, "ISO C forbids "
+               pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                         "comparison of %<void *%> with function pointer");
            }
          else
            /* Avoid warning about the volatile ObjC EH puts on decls.  */
            if (!objc_ok)
-             pedwarn (0, "comparison of distinct pointer types lacks a cast");
+             pedwarn (input_location, 0,
+                      "comparison of distinct pointer types lacks a cast");
 
          if (result_type == NULL_TREE)
            result_type = ptr_type_node;
@@ -8206,12 +8260,12 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
-         pedwarn (0, "comparison between pointer and integer");
+         pedwarn (input_location, 0, "comparison between pointer and integer");
        }
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
        {
          result_type = type1;
-         pedwarn (0, "comparison between pointer and integer");
+         pedwarn (input_location, 0, "comparison between pointer and integer");
        }
       break;
 
@@ -8232,22 +8286,24 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
              result_type = common_pointer_type (type0, type1);
              if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
                  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
-               pedwarn (0, "comparison of complete and incomplete pointers");
+               pedwarn (input_location, 0,
+                        "comparison of complete and incomplete pointers");
              else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
-               pedwarn (OPT_pedantic, "ISO C forbids "
+               pedwarn (input_location, OPT_pedantic, "ISO C forbids "
                         "ordered comparisons of pointers to functions");
            }
          else
            {
              result_type = ptr_type_node;
-             pedwarn (0, "comparison of distinct pointer types lacks a cast");
+             pedwarn (input_location, 0,
+                      "comparison of distinct pointer types lacks a cast");
            }
        }
       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
        {
          result_type = type0;
          if (pedantic)
-           pedwarn (OPT_pedantic, 
+           pedwarn (input_location, OPT_pedantic, 
                     "ordered comparison of pointer with integer zero");
          else if (extra_warnings)
            warning (OPT_Wextra,
@@ -8256,18 +8312,18 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
       else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
        {
          result_type = type1;
-         pedwarn (OPT_pedantic, 
+         pedwarn (input_location, OPT_pedantic, 
                   "ordered comparison of pointer with integer zero");
        }
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
-         pedwarn (0, "comparison between pointer and integer");
+         pedwarn (input_location, 0, "comparison between pointer and integer");
        }
       else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
        {
          result_type = type1;
-         pedwarn (0, "comparison between pointer and integer");
+         pedwarn (input_location, 0, "comparison between pointer and integer");
        }
       break;