Patchwork [C++] PR 53158 (EXPR_LOC_OR_HERE version)

login
register
mail settings
Submitter Paolo Carlini
Date May 9, 2012, 6:47 p.m.
Message ID <4FAABBC0.9010000@oracle.com>
Download mbox | patch
Permalink /patch/158033/
State New
Headers show

Comments

Paolo Carlini - May 9, 2012, 6:47 p.m.
Hi again,

thus the below is what I booted and tested. As you can see I had to 
tweak a bit an existing testcase, for which the location is now a bit 
"smaller", 3 chars, in fact is still not perfect, but arguably a tad 
better. Otherwise no issues. Ah, I'm touching also a c-common.c 
function, in fact all the other warning* functions in the same file 
already use the EXPR_LOC_OR_HERE on the expr argument idea.

Tested x86_64-linux.

Thanks,
Paolo.

//////////////////
/cp
2012-05-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/53158
	* cvt.c (ocp_convert): Error out early for void -> bool conversions.
	* typeck.c (decay_conversion): Use error_at.
	* call.c (build_integral_nontype_arg_conv, convert_like_real,
	convert_arg_to_ellipsis, perform_implicit_conversion_flags,
	initialize_reference): Likewise.
	* cvt.c (warn_ref_binding): Add location_t parameter.
	(cp_convert_to_pointer, convert_to_reference, ocp_convert,
	convert_to_void, ): Use error_at and warning_at.

/c-family
2012-05-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/53158
	* c-common.c (warnings_for_convert_and_check): Use warning_at.

/testsuite
2012-05-09  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/53158
	* g++.dg/cpp0x/lambda/lambda-err2.C: New.
	* g++.dg/parse/error26.C: Tweak dg-error column number.
Jason Merrill - May 10, 2012, 2:49 p.m.
On 05/09/2012 02:47 PM, Paolo Carlini wrote:
> +		  error_at(loc, "cannot bind bitfield %qE to %qT",

Missing a space.

OK with that change.

Jason

Patch

Index: c-family/c-common.c
===================================================================
--- c-family/c-common.c	(revision 187335)
+++ c-family/c-common.c	(working copy)
@@ -2329,6 +2329,8 @@  conversion_warning (tree type, tree expr)
 void
 warnings_for_convert_and_check (tree type, tree expr, tree result)
 {
+  location_t loc = EXPR_LOC_OR_HERE (expr);
+
   if (TREE_CODE (expr) == INTEGER_CST
       && (TREE_CODE (type) == INTEGER_TYPE
           || TREE_CODE (type) == ENUMERAL_TYPE)
@@ -2344,8 +2346,8 @@  warnings_for_convert_and_check (tree type, tree ex
           /* This detects cases like converting -129 or 256 to
              unsigned char.  */
           if (!int_fits_type_p (expr, c_common_signed_type (type)))
-            warning (OPT_Woverflow,
-                     "large integer implicitly truncated to unsigned type");
+            warning_at (loc, OPT_Woverflow,
+			"large integer implicitly truncated to unsigned type");
           else
             conversion_warning (type, expr);
         }
@@ -2357,16 +2359,16 @@  warnings_for_convert_and_check (tree type, tree ex
 	       && (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE
 		   || TYPE_PRECISION (TREE_TYPE (expr))
 		   != TYPE_PRECISION (type)))
-	warning (OPT_Woverflow,
-		 "overflow in implicit constant conversion");
+	warning_at (loc, OPT_Woverflow,
+		    "overflow in implicit constant conversion");
 
       else
 	conversion_warning (type, expr);
     }
   else if ((TREE_CODE (result) == INTEGER_CST
 	    || TREE_CODE (result) == FIXED_CST) && TREE_OVERFLOW (result))
-    warning (OPT_Woverflow,
-             "overflow in implicit constant conversion");
+    warning_at (loc, OPT_Woverflow,
+		"overflow in implicit constant conversion");
   else
     conversion_warning (type, expr);
 }
Index: testsuite/g++.dg/parse/error26.C
===================================================================
--- testsuite/g++.dg/parse/error26.C	(revision 187335)
+++ testsuite/g++.dg/parse/error26.C	(working copy)
@@ -4,7 +4,7 @@ 
 void foo()
 {
   if (({int c[2];})) ; // { dg-error "7:ISO C.. forbids" "7" }
-  // { dg-error "20:could not convert" "20" { target *-*-* } 6 }
+  // { dg-error "17:could not convert" "17" { target *-*-* } 6 }
 }
 
 void bar()
Index: testsuite/g++.dg/cpp0x/lambda/lambda-err2.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-err2.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-err2.C	(revision 0)
@@ -0,0 +1,12 @@ 
+// PR c++/53158
+// { dg-do compile { target c++11 } }
+
+int main()
+{
+  auto a = []() { return true; };
+  auto b = []() { return a(); };  // { dg-error "'a' is not captured" }
+  int c, d;
+  while (b() && c < d) // { dg-error "could not convert" }
+    {
+    }
+}
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 187335)
+++ cp/typeck.c	(working copy)
@@ -1822,6 +1822,7 @@  decay_conversion (tree exp, tsubst_flags_t complai
 {
   tree type;
   enum tree_code code;
+  location_t loc = EXPR_LOC_OR_HERE (exp);
 
   type = TREE_TYPE (exp);
   if (type == error_mark_node)
@@ -1853,7 +1854,7 @@  decay_conversion (tree exp, tsubst_flags_t complai
   if (code == VOID_TYPE)
     {
       if (complain & tf_error)
-	error ("void value not ignored as it ought to be");
+	error_at (loc, "void value not ignored as it ought to be");
       return error_mark_node;
     }
   if (invalid_nonstatic_memfn_p (exp, complain))
@@ -1882,7 +1883,7 @@  decay_conversion (tree exp, tsubst_flags_t complai
 	  && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp)))
 	{
 	  if (complain & tf_error)
-	    error ("invalid use of non-lvalue array");
+	    error_at (loc, "invalid use of non-lvalue array");
 	  return error_mark_node;
 	}
 
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 187335)
+++ cp/call.c	(working copy)
@@ -3692,6 +3692,7 @@  build_integral_nontype_arg_conv (tree type, tree e
   conversion *conv;
   void *p;
   tree t;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (error_operand_p (expr))
     return error_mark_node;
@@ -3727,8 +3728,8 @@  build_integral_nontype_arg_conv (tree type, tree e
 	  break;
 
 	if (complain & tf_error)
-	  error ("conversion from %qT to %qT not considered for "
-		 "non-type template argument", t, type);
+	  error_at (loc, "conversion from %qT to %qT not considered for "
+		    "non-type template argument", t, type);
 	/* and fall through.  */
 
       default:
@@ -5648,6 +5649,7 @@  convert_like_real (conversion *convs, tree expr, t
   tree totype = convs->type;
   diagnostic_t diag_kind;
   int flags;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (convs->bad_p && !(complain & tf_error))
     return error_mark_node;
@@ -5668,13 +5670,13 @@  convert_like_real (conversion *convs, tree expr, t
 	  && SCALAR_TYPE_P (totype)
 	  && CONSTRUCTOR_NELTS (expr) > 0
 	  && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
-	permerror (input_location, "too many braces around initializer for %qT", totype);
+	permerror (loc, "too many braces around initializer for %qT", totype);
 
       for (; t ; t = next_conversion (t))
 	{
 	  if (t->kind == ck_user && t->cand->reason)
 	    {
-	      permerror (input_location, "invalid user-defined conversion "
+	      permerror (loc, "invalid user-defined conversion "
 			 "from %qT to %qT", TREE_TYPE (expr), totype);
 	      print_z_candidate ("candidate is:", t->cand);
 	      expr = convert_like_real (t, expr, fn, argnum, 1,
@@ -5704,7 +5706,7 @@  convert_like_real (conversion *convs, tree expr, t
 	    break;
 	}
 
-      permerror (input_location, "invalid conversion from %qT to %qT",
+      permerror (loc, "invalid conversion from %qT to %qT",
 		 TREE_TYPE (expr), totype);
       if (fn)
 	permerror (DECL_SOURCE_LOCATION (fn),
@@ -5937,8 +5939,8 @@  convert_like_real (conversion *convs, tree expr, t
 	    gcc_assert (TYPE_REF_IS_RVALUE (ref_type)
 			&& real_lvalue_p (expr));
 
-	    error ("cannot bind %qT lvalue to %qT",
-		   TREE_TYPE (expr), totype);
+	    error_at (loc, "cannot bind %qT lvalue to %qT",
+		      TREE_TYPE (expr), totype);
 	    if (fn)
 	      error ("  initializing argument %P of %q+D", argnum, fn);
 	    return error_mark_node;
@@ -5969,13 +5971,14 @@  convert_like_real (conversion *convs, tree expr, t
 		/* If the reference is volatile or non-const, we
 		   cannot create a temporary.  */
 		if (lvalue & clk_bitfield)
-		  error ("cannot bind bitfield %qE to %qT",
-			 expr, ref_type);
+		  error_at(loc, "cannot bind bitfield %qE to %qT",
+			   expr, ref_type);
 		else if (lvalue & clk_packed)
-		  error ("cannot bind packed field %qE to %qT",
-			 expr, ref_type);
+		  error_at (loc, "cannot bind packed field %qE to %qT",
+			    expr, ref_type);
 		else
-		  error ("cannot bind rvalue %qE to %qT", expr, ref_type);
+		  error_at (loc, "cannot bind rvalue %qE to %qT",
+			    expr, ref_type);
 		return error_mark_node;
 	      }
 	    /* If the source is a packed field, and we must use a copy
@@ -5988,8 +5991,8 @@  convert_like_real (conversion *convs, tree expr, t
 		&& CLASS_TYPE_P (type)
 		&& type_has_nontrivial_copy_init (type))
 	      {
-		error ("cannot bind packed field %qE to %qT",
-		       expr, ref_type);
+		error_at (loc, "cannot bind packed field %qE to %qT",
+			  expr, ref_type);
 		return error_mark_node;
 	      }
 	    if (lvalue & clk_bitfield)
@@ -6055,6 +6058,7 @@  tree
 convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
 {
   tree arg_type;
+  location_t loc = EXPR_LOC_OR_HERE (arg);
 
   /* [expr.call]
 
@@ -6076,10 +6080,10 @@  convert_arg_to_ellipsis (tree arg, tsubst_flags_t
     {
       if ((complain & tf_warning)
 	  && warn_double_promotion && !c_inhibit_evaluation_warnings)
-	warning (OPT_Wdouble_promotion,
-		 "implicit conversion from %qT to %qT when passing "
-		 "argument to function",
-		 arg_type, double_type_node);
+	warning_at (loc, OPT_Wdouble_promotion,
+		    "implicit conversion from %qT to %qT when passing "
+		    "argument to function",
+		    arg_type, double_type_node);
       arg = convert_to_real (double_type_node, arg);
     }
   else if (NULLPTR_TYPE_P (arg_type))
@@ -6089,8 +6093,8 @@  convert_arg_to_ellipsis (tree arg, tsubst_flags_t
       if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
 	{
 	  if (complain & tf_warning)
-	    warning (OPT_Wabi, "scoped enum %qT will not promote to an "
-		     "integral type in a future version of GCC", arg_type);
+	    warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an "
+			"integral type in a future version of GCC", arg_type);
 	  arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg);
 	}
       arg = perform_integral_promotions (arg);
@@ -6126,8 +6130,8 @@  convert_arg_to_ellipsis (tree arg, tsubst_flags_t
 	      || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type)))
 	{
 	  if (complain & tf_error)
-	    error ("cannot pass objects of non-trivially-copyable "
-		   "type %q#T through %<...%>", arg_type);
+	    error_at (loc, "cannot pass objects of non-trivially-copyable "
+		      "type %q#T through %<...%>", arg_type);
 	  else
 	    return error_mark_node;
 	}
@@ -8532,6 +8536,7 @@  perform_implicit_conversion_flags (tree type, tree
 {
   conversion *conv;
   void *p;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (error_operand_p (expr))
     return error_mark_node;
@@ -8554,8 +8559,8 @@  perform_implicit_conversion_flags (tree type, tree
 	  else if (invalid_nonstatic_memfn_p (expr, complain))
 	    /* We gave an error.  */;
 	  else
-	    error ("could not convert %qE from %qT to %qT", expr,
-		   TREE_TYPE (expr), type);
+	    error_at (loc, "could not convert %qE from %qT to %qT", expr,
+		      TREE_TYPE (expr), type);
 	}
       expr = error_mark_node;
     }
@@ -8833,6 +8838,7 @@  initialize_reference (tree type, tree expr,
 {
   conversion *conv;
   void *p;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (type == error_mark_node || error_operand_p (expr))
     return error_mark_node;
@@ -8851,13 +8857,13 @@  initialize_reference (tree type, tree expr,
 	  else if (!CP_TYPE_CONST_P (TREE_TYPE (type))
 		   && !TYPE_REF_IS_RVALUE (type)
 		   && !real_lvalue_p (expr))
-	    error ("invalid initialization of non-const reference of "
-		   "type %qT from an rvalue of type %qT",
-		   type, TREE_TYPE (expr));
+	    error_at (loc, "invalid initialization of non-const reference of "
+		      "type %qT from an rvalue of type %qT",
+		      type, TREE_TYPE (expr));
 	  else
-	    error ("invalid initialization of reference of type "
-		   "%qT from expression of type %qT", type,
-		   TREE_TYPE (expr));
+	    error_at (loc, "invalid initialization of reference of type "
+		      "%qT from expression of type %qT", type,
+		      TREE_TYPE (expr));
 	}
       return error_mark_node;
     }
Index: cp/cvt.c
===================================================================
--- cp/cvt.c	(revision 187335)
+++ cp/cvt.c	(working copy)
@@ -42,7 +42,7 @@  static tree cp_convert_to_pointer (tree, tree);
 static tree convert_to_pointer_force (tree, tree);
 static tree build_type_conversion (tree, tree);
 static tree build_up_reference (tree, tree, int, tree);
-static void warn_ref_binding (tree, tree, tree);
+static void warn_ref_binding (location_t, tree, tree, tree);
 
 /* Change of width--truncation and extension of integers or reals--
    is represented with NOP_EXPR.  Proper functioning of many things
@@ -79,6 +79,8 @@  cp_convert_to_pointer (tree type, tree expr)
   tree intype = TREE_TYPE (expr);
   enum tree_code form;
   tree rval;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
+
   if (intype == error_mark_node)
     return error_mark_node;
 
@@ -87,8 +89,8 @@  cp_convert_to_pointer (tree type, tree expr)
       intype = complete_type (intype);
       if (!COMPLETE_TYPE_P (intype))
 	{
-	  error ("can%'t convert from incomplete type %qT to %qT",
-		 intype, type);
+	  error_at (loc, "can%'t convert from incomplete type %qT to %qT",
+		    intype, type);
 	  return error_mark_node;
 	}
 
@@ -96,8 +98,8 @@  cp_convert_to_pointer (tree type, tree expr)
       if (rval)
 	{
 	  if (rval == error_mark_node)
-	    error ("conversion of %qE from %qT to %qT is ambiguous",
-		   expr, intype, type);
+	    error_at (loc, "conversion of %qE from %qT to %qT is ambiguous",
+		      expr, intype, type);
 	  return rval;
 	}
     }
@@ -166,8 +168,8 @@  cp_convert_to_pointer (tree type, tree expr)
 
       if (TYPE_PTRMEMFUNC_P (type))
 	{
-	  error ("cannot convert %qE from type %qT to type %qT",
-		 expr, intype, type);
+	  error_at (loc, "cannot convert %qE from type %qT to type %qT",
+		    expr, intype, type);
 	  return error_mark_node;
 	}
 
@@ -192,8 +194,8 @@  cp_convert_to_pointer (tree type, tree expr)
 						       tf_warning_or_error);
 	    }
 	}
-      error ("cannot convert %qE from type %qT to type %qT",
-	     expr, intype, type);
+      error_at (loc, "cannot convert %qE from type %qT to type %qT",
+		expr, intype, type);
       return error_mark_node;
     }
 
@@ -201,8 +203,8 @@  cp_convert_to_pointer (tree type, tree expr)
     {
       if (c_inhibit_evaluation_warnings == 0
 	  && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
-	warning (OPT_Wzero_as_null_pointer_constant,
-		 "zero as null pointer constant");
+	warning_at (loc, OPT_Wzero_as_null_pointer_constant,
+		    "zero as null pointer constant");
 
       if (TYPE_PTRMEMFUNC_P (type))
 	return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
@@ -221,7 +223,7 @@  cp_convert_to_pointer (tree type, tree expr)
     }
   else if (TYPE_PTR_TO_MEMBER_P (type) && INTEGRAL_CODE_P (form))
     {
-      error ("invalid conversion from %qT to %qT", intype, type);
+      error_at (loc, "invalid conversion from %qT to %qT", intype, type);
       return error_mark_node;
     }
 
@@ -242,8 +244,8 @@  cp_convert_to_pointer (tree type, tree expr)
   if (type_unknown_p (expr))
     return instantiate_type (type, expr, tf_warning_or_error);
 
-  error ("cannot convert %qE from type %qT to type %qT",
-	 expr, intype, type);
+  error_at (loc, "cannot convert %qE from type %qT to type %qT",
+	    expr, intype, type);
   return error_mark_node;
 }
 
@@ -367,7 +369,7 @@  build_up_reference (tree type, tree arg, int flags
    non-volatile const type.  */
 
 static void
-warn_ref_binding (tree reftype, tree intype, tree decl)
+warn_ref_binding (location_t loc, tree reftype, tree intype, tree decl)
 {
   tree ttl = TREE_TYPE (reftype);
 
@@ -388,7 +390,7 @@  static void
 	msg = G_("conversion to non-const reference type %q#T from "
 	         "rvalue of type %qT");
 
-      permerror (input_location, msg, reftype, intype);
+      permerror (loc, msg, reftype, intype);
     }
 }
 
@@ -410,6 +412,7 @@  convert_to_reference (tree reftype, tree expr, int
   bool can_convert_intype_to_type;
   tsubst_flags_t complain = ((flags & LOOKUP_COMPLAIN)
 			     ? tf_warning_or_error : tf_none);
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (TREE_CODE (type) == FUNCTION_TYPE
       && TREE_TYPE (expr) == unknown_type_node)
@@ -455,11 +458,11 @@  convert_to_reference (tree reftype, tree expr, int
 	  tree ttr = lvalue_type (expr);
 
 	  if (! real_lvalue_p (expr))
-	    warn_ref_binding (reftype, intype, decl);
+	    warn_ref_binding (loc, reftype, intype, decl);
 
 	  if (! (convtype & CONV_CONST)
 		   && !at_least_as_qualified_p (ttl, ttr))
-	    permerror (input_location, "conversion from %qT to %qT discards qualifiers",
+	    permerror (loc, "conversion from %qT to %qT discards qualifiers",
 		       ttr, reftype);
 	}
 
@@ -477,8 +480,8 @@  convert_to_reference (tree reftype, tree expr, int
       if (TREE_CODE (intype) == POINTER_TYPE
 	  && (comptypes (TREE_TYPE (intype), type,
 			 COMPARE_BASE | COMPARE_DERIVED)))
-	warning (0, "casting %qT to %qT does not dereference pointer",
-		 intype, reftype);
+	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
+		    intype, reftype);
 
       rval = cp_build_addr_expr (expr, tf_warning_or_error);
       if (rval != error_mark_node)
@@ -494,7 +497,7 @@  convert_to_reference (tree reftype, tree expr, int
                                          tf_warning_or_error);
       if (rval == NULL_TREE || rval == error_mark_node)
 	return rval;
-      warn_ref_binding (reftype, intype, decl);
+      warn_ref_binding (loc, reftype, intype, decl);
       rval = build_up_reference (reftype, rval, flags, decl);
     }
 
@@ -505,7 +508,7 @@  convert_to_reference (tree reftype, tree expr, int
     }
 
   if (flags & LOOKUP_COMPLAIN)
-    error ("cannot convert type %qT to type %qT", intype, reftype);
+    error_at (loc, "cannot convert type %qT to type %qT", intype, reftype);
 
   return error_mark_node;
 }
@@ -633,6 +636,7 @@  ocp_convert (tree type, tree expr, int convtype, i
   enum tree_code code = TREE_CODE (type);
   const char *invalid_conv_diag;
   tree e1;
+  location_t loc = EXPR_LOC_OR_HERE (expr);
 
   if (error_operand_p (e) || type == error_mark_node)
     return error_mark_node;
@@ -711,8 +715,7 @@  ocp_convert (tree type, tree expr, int convtype, i
 	      || TREE_CODE (intype) == POINTER_TYPE)
 	    {
 	      if (flags & LOOKUP_COMPLAIN)
-		permerror (input_location, "conversion from %q#T to %q#T", intype, type);
-
+		permerror (loc, "conversion from %q#T to %q#T", intype, type);
 	      if (!flag_permissive)
 		return error_mark_node;
 	    }
@@ -726,10 +729,10 @@  ocp_convert (tree type, tree expr, int convtype, i
 	     unspecified.  */
 	  if (TREE_CODE (expr) == INTEGER_CST
 	      && !int_fits_type_p (expr, ENUM_UNDERLYING_TYPE (type)))
-	    warning (OPT_Wconversion, 
-		     "the result of the conversion is unspecified because "
-		     "%qE is outside the range of type %qT",
-		     expr, type);
+	    warning_at (loc, OPT_Wconversion, 
+			"the result of the conversion is unspecified because "
+			"%qE is outside the range of type %qT",
+			expr, type);
 	}
       if (MAYBE_CLASS_TYPE_P (intype))
 	{
@@ -738,11 +741,18 @@  ocp_convert (tree type, tree expr, int convtype, i
 	  if (rval)
 	    return rval;
 	  if (flags & LOOKUP_COMPLAIN)
-	    error ("%q#T used where a %qT was expected", intype, type);
+	    error_at (loc, "%q#T used where a %qT was expected", intype, type);
 	  return error_mark_node;
 	}
       if (code == BOOLEAN_TYPE)
 	{
+	  if (TREE_CODE (intype) == VOID_TYPE)
+	    {
+	      error_at (loc, "could not convert %qE from %<void%> to %<bool%>",
+			expr);
+	      return error_mark_node;
+	    }
+
 	  /* We can't implicitly convert a scoped enum to bool, so convert
 	     to the underlying type first.  */
 	  if (SCOPED_ENUM_P (intype) && (convtype & CONV_STATIC))
@@ -769,7 +779,7 @@  ocp_convert (tree type, tree expr, int convtype, i
 	  if (ret_val)
 	    return ret_val;
 	  if (flags & LOOKUP_COMPLAIN)
-	    error ("%q#T used where a %qT was expected", in_vtype, type);
+	    error_at (loc, "%q#T used where a %qT was expected", in_vtype, type);
 	  return error_mark_node;
 	}
       return fold_if_not_in_template (convert_to_vector (type, e));
@@ -784,7 +794,7 @@  ocp_convert (tree type, tree expr, int convtype, i
 	    return rval;
 	  else
 	    if (flags & LOOKUP_COMPLAIN)
-	      error ("%q#T used where a floating point value was expected",
+	      error_at (loc, "%q#T used where a floating point value was expected",
 			TREE_TYPE (e));
 	}
       if (code == REAL_TYPE)
@@ -845,8 +855,8 @@  ocp_convert (tree type, tree expr, int convtype, i
       if (invalid_nonstatic_memfn_p (expr, tf_warning_or_error))
 	/* We displayed the error message.  */;
       else
-	error ("conversion from %qT to non-scalar type %qT requested",
-	       TREE_TYPE (expr), type);
+	error_at (loc, "conversion from %qT to non-scalar type %qT requested",
+		  TREE_TYPE (expr), type);
     }
   return error_mark_node;
 }
@@ -873,6 +883,8 @@  ocp_convert (tree type, tree expr, int convtype, i
 tree
 convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
 {
+  location_t loc = EXPR_LOC_OR_HERE (expr);
+
   if (expr == error_mark_node
       || TREE_TYPE (expr) == error_mark_node)
     return error_mark_node;
@@ -903,7 +915,7 @@  convert_to_void (tree expr, impl_conv_void implici
   if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
     {
       if (complain & tf_error)
-        error ("pseudo-destructor is not called");
+        error_at (loc, "pseudo-destructor is not called");
       return error_mark_node;
     }
   if (VOID_TYPE_P (TREE_TYPE (expr)))
@@ -980,35 +992,35 @@  convert_to_void (tree expr, impl_conv_void implici
 	      switch (implicit)
 		{
 	      	  case ICV_CAST:
-		    warning (0, "conversion to void will not access "
+		    warning_at (loc, 0, "conversion to void will not access "
 				"object of incomplete type %qT", type);
 		    break;
 		  case ICV_SECOND_OF_COND:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in second operand "
 				"of conditional expression", type);
 		    break;
 		  case ICV_THIRD_OF_COND:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in third operand "
 				"of conditional expression", type);
 		    break;
 		  case ICV_RIGHT_OF_COMMA:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in right operand of "
 				"comma operator", type);
 		    break;
 		  case ICV_LEFT_OF_COMMA:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in left operand of "
 				"comma operator", type);
 		    break;
 		  case ICV_STATEMENT:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in statement", type);
 		     break;
 		  case ICV_THIRD_IN_FOR:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"incomplete type %qT in for increment "
 				"expression", type);
 		    break;
@@ -1024,37 +1036,37 @@  convert_to_void (tree expr, impl_conv_void implici
 	      switch (implicit)
 		{
 	      	  case ICV_CAST:
-		    warning (0, "conversion to void will not access "
+		    warning_at (loc, 0, "conversion to void will not access "
 				"object of type %qT", type);
 		    break;
 		  case ICV_SECOND_OF_COND:
-		    warning (0, "implicit dereference will not access object "
-				"of type %qT in second operand of "
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in second operand of "
 				"conditional expression", type);
 		    break;
 		  case ICV_THIRD_OF_COND:
-		    warning (0, "implicit dereference will not access object "
-		  	      	"of type %qT in third operand of "
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in third operand of "
 				"conditional expression", type);
 		    break;
 		  case ICV_RIGHT_OF_COMMA:
-		    warning (0, "implicit dereference will not access object "
-		    		"of type %qT in right operand of "
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in right operand of "
 				"comma operator", type);
 		    break;
 		  case ICV_LEFT_OF_COMMA:
-		    warning (0, "implicit dereference will not access object "
-		    		"of type %qT in left operand of comma operator",
-			     type);
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in left operand of comma "
+				"operator", type);
 		    break;
 		  case ICV_STATEMENT:
-		    warning (0, "implicit dereference will not access object "
-		     		"of type %qT in statement",  type);
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in statement",  type);
 		     break;
 		  case ICV_THIRD_IN_FOR:
-		    warning (0, "implicit dereference will not access object "
-		    		"of type %qT in for increment expression",
-			     type);
+		    warning_at (loc, 0, "implicit dereference will not access "
+				"object of type %qT in for increment expression",
+				type);
 		    break;
 		  default:
 		    gcc_unreachable ();
@@ -1066,37 +1078,37 @@  convert_to_void (tree expr, impl_conv_void implici
 	      switch (implicit)
 		{
 	      	  case ICV_CAST:
-		    warning (0, "conversion to void will not access "
+		    warning_at (loc, 0, "conversion to void will not access "
 				"object of non-trivially-copyable type %qT",
-			     type);
+				type);
 		    break;
 		  case ICV_SECOND_OF_COND:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 				"non-trivially-copyable type %qT in second "
 				"operand of conditional expression", type);
 		    break;
 		  case ICV_THIRD_OF_COND:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 		  	      	"non-trivially-copyable type %qT in third "
 				"operand of conditional expression", type);
 		    break;
 		  case ICV_RIGHT_OF_COMMA:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 		    		"non-trivially-copyable type %qT in right "
 				"operand of comma operator", type);
 		    break;
 		  case ICV_LEFT_OF_COMMA:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 		    		"non-trivially-copyable type %qT in left "
 				"operand of comma operator", type);
 		    break;
 		  case ICV_STATEMENT:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 		     		"non-trivially-copyable type %qT in statement",
-			      type);
+				type);
 		     break;
 		  case ICV_THIRD_IN_FOR:
-		    warning (0, "indirection will not access object of "
+		    warning_at (loc, 0, "indirection will not access object of "
 		    		"non-trivially-copyable type %qT in for "
 				"increment expression", type);
 		    break;
@@ -1117,7 +1129,7 @@  convert_to_void (tree expr, impl_conv_void implici
                 && (complain & tf_warning)
                 && !TREE_NO_WARNING (expr)
                 && !is_reference)
-              warning (OPT_Wunused_value, "value computed is not used");
+              warning_at (loc, OPT_Wunused_value, "value computed is not used");
             expr = TREE_OPERAND (expr, 0);
           }
 
@@ -1134,37 +1146,37 @@  convert_to_void (tree expr, impl_conv_void implici
 	  switch (implicit)
 	    {
 	      case ICV_CAST:
-		warning (0, "conversion to void will not access "
+		warning_at (loc, 0, "conversion to void will not access "
 			    "object %qE of incomplete type %qT", expr, type);
 		break;
 	      case ICV_SECOND_OF_COND:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-			    "be accessed in second operand of "
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in second operand of "
 			    "conditional expression", expr, type);
 		break;
 	      case ICV_THIRD_OF_COND:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-			    "be accessed in third operand of "
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in third operand of "
 			    "conditional expression", expr, type);
 		break;
 	      case ICV_RIGHT_OF_COMMA:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-			    "be accessed in right operand of comma operator",
-			 expr, type);
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in right operand of comma operator",
+			    expr, type);
 		break;
 	      case ICV_LEFT_OF_COMMA:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-			    "be accessed in left operand of comma operator",
-			 expr, type);
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in left operand of comma operator",
+			    expr, type);
 		break;
 	      case ICV_STATEMENT:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-		            "be accessed in statement", expr, type);
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in statement", expr, type);
 		break;
 	      case ICV_THIRD_IN_FOR:
-	        warning (0, "variable %qE of incomplete type %qT will not "
-			    "be accessed in for increment expression",
-		         expr, type);
+	        warning_at (loc, 0, "variable %qE of incomplete type %qT will "
+			    "not be accessed in for increment expression",
+			    expr, type);
 		break;
 	      default:
 	        gcc_unreachable ();
@@ -1211,32 +1223,32 @@  convert_to_void (tree expr, impl_conv_void implici
 	  switch (implicit)
 	    {
 	      case ICV_CAST:
-		error ("conversion to void "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "conversion to void "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_SECOND_OF_COND:
-		error ("second operand of conditional expression "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "second operand of conditional expression "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_THIRD_OF_COND:
-		error ("third operand of conditional expression "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "third operand of conditional expression "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_RIGHT_OF_COMMA:
-		error ("right operand of comma operator "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "right operand of comma operator "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_LEFT_OF_COMMA:
-		error ("left operand of comma operator "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "left operand of comma operator "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_STATEMENT:
-		error ("statement "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "statement "
+			  "cannot resolve address of overloaded function");
 		break;
 	      case ICV_THIRD_IN_FOR:
-		error ("for increment expression "
-		       "cannot resolve address of overloaded function");
+		error_at (loc, "for increment expression "
+			  "cannot resolve address of overloaded function");
 		break;
 	    }
 	else
@@ -1250,34 +1262,34 @@  convert_to_void (tree expr, impl_conv_void implici
 	  switch (implicit)
 	    {
 	      case ICV_SECOND_OF_COND:
-	        warning (OPT_Waddress,
-			 "second operand of conditional expression "
-			 "is a reference, not call, to function %qE", expr);
+	        warning_at (loc, OPT_Waddress,
+			    "second operand of conditional expression "
+			    "is a reference, not call, to function %qE", expr);
 		break;
 	      case ICV_THIRD_OF_COND:
-	        warning (OPT_Waddress,
-			 "third operand of conditional expression "
-			 "is a reference, not call, to function %qE", expr);
+	        warning_at (loc, OPT_Waddress,
+			    "third operand of conditional expression "
+			    "is a reference, not call, to function %qE", expr);
 		break;
 	      case ICV_RIGHT_OF_COMMA:
-	        warning (OPT_Waddress,
-			 "right operand of comma operator "
-			 "is a reference, not call, to function %qE", expr);
+		warning_at (loc, OPT_Waddress,
+			    "right operand of comma operator "
+			    "is a reference, not call, to function %qE", expr);
 		break;
 	      case ICV_LEFT_OF_COMMA:
-	        warning (OPT_Waddress,
-			 "left operand of comma operator "
-			 "is a reference, not call, to function %qE", expr);
+	        warning_at (loc, OPT_Waddress,
+			    "left operand of comma operator "
+			    "is a reference, not call, to function %qE", expr);
 		break;
 	      case ICV_STATEMENT:
-	        warning (OPT_Waddress,
-			 "statement is a reference, not call, to function %qE",
-			 expr);
+	        warning_at (loc, OPT_Waddress,
+			    "statement is a reference, not call, to function %qE",
+			    expr);
 		break;
 	      case ICV_THIRD_IN_FOR:
-	        warning (OPT_Waddress,
-			 "for increment expression "
-			 "is a reference, not call, to function %qE", expr);
+	        warning_at (loc, OPT_Waddress,
+			    "for increment expression "
+			    "is a reference, not call, to function %qE", expr);
 		break;
 	      default:
 	        gcc_unreachable ();
@@ -1302,28 +1314,30 @@  convert_to_void (tree expr, impl_conv_void implici
 	      switch (implicit)
 		{
 		  case ICV_SECOND_OF_COND:
-		    warning (OPT_Wunused_value,
-			     "second operand of conditional expression has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"second operand of conditional expression "
+				"has no effect");
 		    break;
 		  case ICV_THIRD_OF_COND:
-		    warning (OPT_Wunused_value,
-		    	     "third operand of conditional expression has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"third operand of conditional expression "
+				"has no effect");
 		    break;
 		  case ICV_RIGHT_OF_COMMA:
-		    warning (OPT_Wunused_value,
-		    	     "right operand of comma operator has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"right operand of comma operator has no effect");
 		    break;
 		  case ICV_LEFT_OF_COMMA:
-		    warning (OPT_Wunused_value,
-		    	     "left operand of comma operator has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"left operand of comma operator has no effect");
 		    break;
 		  case ICV_STATEMENT:
-		    warning (OPT_Wunused_value,
-		    	     "statement has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"statement has no effect");
 		    break;
 		  case ICV_THIRD_IN_FOR:
-		    warning (OPT_Wunused_value,
-		    	     "for increment expression has no effect");
+		    warning_at (loc, OPT_Wunused_value,
+				"for increment expression has no effect");
 		    break;
 		  default:
 		    gcc_unreachable ();
@@ -1361,7 +1375,7 @@  convert_to_void (tree expr, impl_conv_void implici
 			    || code == POSTDECREMENT_EXPR
 			    || code == POSTINCREMENT_EXPR)))
                   && (complain & tf_warning))
-		warning (OPT_Wunused_value, "value computed is not used");
+		warning_at (loc, OPT_Wunused_value, "value computed is not used");
 	    }
 	}
       expr = build1 (CONVERT_EXPR, void_type_node, expr);