diff mbox series

[C++] Improve build_*_cast locations

Message ID 0866f8ec-c037-ea07-064f-eb3b9e2dbaf5@oracle.com
State New
Headers show
Series [C++] Improve build_*_cast locations | expand

Commit Message

Paolo Carlini Dec. 6, 2019, 4:14 p.m. UTC
Hi,

as promised, the below takes care of the various remaining casts. It's 
mostly mechanical, follows the same approach used for 
build_functional_cast. Tested x86_64-linux.

Thanks, Paolo.

////////////////////
gcc/cp
2019-12-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck.c (check_for_casting_away_constness): Add location_t
	parameter and use it.
	(maybe_warn_about_useless_cast): Likewise.
	(maybe_warn_about_cast_ignoring_quals): Likewise.
	(build_static_cast_1): Likewise.
	(build_static_cast): Likewise.
	(build_reinterpret_cast_1): Likewise.
	(build_reinterpret_cast): Likewise.
	(build_const_cast_1): Likewise.
	(build_const_cast): Likewise.
	(cp_build_c_cast): Likewise.
	(build_c_cast): Adjust.
	(build_ptrmemfunc): Adjust calls.
	(cp_build_unary_op): Pass the location to invert_truthvalue_loc.
	* rtti.c (build_dynamic_cast_1): Add location_t parameter and
	use it.
	(build_dynamic_cast): Likewise.
	* cp-tree.h: Adjust declarations.
	* parser.c (cp_parser_postfix_expression): Pass cp_cast_loc to
	the various build_*_cast functions.
	(get_cast_suggestion): Adjust calls.
	(cp_parser_builtin_offsetof): Likewise.
	* decl.c (reshape_init): Adjust call.
	* method.c (forward_parm): Likewise.
	(build_comparison_op): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* semantics.c (finish_omp_reduction_clause): Likewise.
	(cp_omp_finish_iterators): Likewise.
	* tree.c (cp_stabilize_reference): Likewise.
	(move): Likewise.
	* typeck2.c (build_functional_cast): Likewise.

/libcc1
2019-12-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* libcp1plugin.cc (plugin_build_cast_expr): Adjust build_cast
	declaration.

gcc/testsuite
2019-12-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* c-c++-common/Wcast-align.c: Check location(s) too.
	* c-c++-common/Wcast-function-type.c: Likewise.
	* c-c++-common/Wint-to-pointer-cast-1.c: Likewise.
	* c-c++-common/Wint-to-pointer-cast-2.c: Likewise.
	* c-c++-common/Wint-to-pointer-cast-3.c: Likewise.
	* g++.dg/Wcast-function-type.C: Likewise.
	* g++.dg/addr_builtin-1.C: Likewise.
	* g++.dg/conversion/const2.C: Likewise.
	* g++.dg/conversion/dynamic1.C: Likewise.
	* g++.dg/conversion/ptrmem2.C: Likewise.
	* g++.dg/conversion/ptrmem3.C: Likewise.
	* g++.dg/conversion/qual3.C: Likewise.
	* g++.dg/conversion/reinterpret3.C: Likewise.
	* g++.dg/cpp0x/lambda/lambda-conv11.C: Likewise.
	* g++.dg/cpp0x/nullptr04.C: Likewise.
	* g++.dg/cpp0x/reinterpret_cast2.C: Likewise.
	* g++.dg/cpp0x/rv-cast2.C: Likewise.
	* g++.dg/cpp1y/lambda-conv1.C: Likewise.
	* g++.dg/cpp1z/noexcept-type7.C: Likewise.
	* g++.dg/cpp2a/array-conv9.C: Likewise.
	* g++.dg/expr/cast11.C: Likewise.
	* g++.dg/expr/static_cast8.C: Likewise.
	* g++.dg/ext/vector6.C: Likewise.
	* g++.dg/other/conversion1.C: Likewise.
	* g++.dg/parse/pr26997.C: Likewise.
	* g++.dg/rtti/no-rtti.C: Likewise.
	* g++.dg/tc1/dr137.C: Likewise.
	* g++.dg/template/cast4.C: Likewise.
	* g++.dg/warn/Wcast-qual1.C: Likewise.
	* g++.dg/warn/Wcast-qual2.C: Likewise.
	* g++.dg/warn/Wconditionally-supported-1.C: Likewise.
	* g++.dg/warn/Wuseless-cast.C: Likewise.
	* g++.dg/warn/pr35711.C: Likewise.
	* g++.old-deja/g++.bugs/900227_01.C: Likewise.
	* g++.old-deja/g++.bugs/900404_07.C: Likewise.
	* g++.old-deja/g++.jason/overload1.C: Likewise.
	* g++.old-deja/g++.jason/rfg26.C: Likewise.
	* g++.old-deja/g++.jason/rvalue3.C: Likewise.
	* g++.old-deja/g++.jason/warning2.C: Likewise.
	* g++.old-deja/g++.mike/dyncast4.C: Likewise.
	* g++.old-deja/g++.mike/dyncast6.C: Likewise.
	* g++.old-deja/g++.mike/p11482.C: Likewise.
	* g++.old-deja/g++.mike/p2573.C: Likewise.
	* g++.old-deja/g++.mike/p2855.C: Likewise.
	* g++.old-deja/g++.mike/p7476.C: Likewise.
	* g++.old-deja/g++.mike/p8039.C: Likewise.
	* g++.old-deja/g++.other/cast2.C: Likewise.
	* g++.old-deja/g++.other/cast3.C: Likewise.
	* g++.old-deja/g++.other/dcast1.C: Likewise.
	* g++.old-deja/g++.other/dcast2.C: Likewise.

Comments

Jason Merrill Dec. 6, 2019, 5:53 p.m. UTC | #1
On 12/6/19 11:14 AM, Paolo Carlini wrote:
> Hi,
> 
> as promised, the below takes care of the various remaining casts. It's 
> mostly mechanical, follows the same approach used for 
> build_functional_cast. Tested x86_64-linux.

It occurs to me that once we're passing the location into the build_* 
functions, we can apply it to the expression there rather than in the 
parser.

Jason
Paolo Carlini Dec. 6, 2019, 9:36 p.m. UTC | #2
Hi,

On 06/12/19 18:53, Jason Merrill wrote:
> On 12/6/19 11:14 AM, Paolo Carlini wrote:
>> Hi,
>>
>> as promised, the below takes care of the various remaining casts. 
>> It's mostly mechanical, follows the same approach used for 
>> build_functional_cast. Tested x86_64-linux.
>
> It occurs to me that once we're passing the location into the build_* 
> functions, we can apply it to the expression there rather than in the 
> parser.

In fact that occurred to me too ;) but at first I didn't like the idea 
of multiplying the set_location calls... Anyway, in practice for the 
casts of this last patch the idea works reasonably well, because most of 
the complexity is encapsulated in the *_1 versions of the functions and 
the build_* functions proper have only a couple of returns. I wanted to 
send those changes... But then my build failed in the libcp1plugin.cc 
bits because the switch also includes c_cast and all the functions must 
return the same type. And then for consistency we want also to adjust 
functional_cast (which allows to remove the set_location in the parser 
which also remained after my previous patch). Those two cast however are 
more annoying, because there aren't *_1 counterparts and the functions 
have *lots* of returns, are complicated. Thus for those I'm proposing to 
create ad hoc *_1 identical to the current functions in order to have 
single set_location in cp_build_c_cast and build_functional_cast. All in 
all, I don't have better ideas... I'm finishing testing the below.

Thanks, Paolo.

//////////////////
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 279041)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -6998,7 +6998,8 @@ extern tree build_typeid			(tree, tsubst_flags_t);
 extern tree get_tinfo_decl			(tree);
 extern tree get_typeid				(tree, tsubst_flags_t);
 extern tree build_headof			(tree);
-extern tree build_dynamic_cast			(tree, tree, tsubst_flags_t);
+extern cp_expr build_dynamic_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
 extern void emit_support_tinfos			(void);
 extern bool emit_tinfo_decl			(tree);
 
@@ -7547,13 +7548,17 @@ extern tree build_x_compound_expr		(location_t, tr
 						 tsubst_flags_t);
 extern tree build_compound_expr                 (location_t, tree, tree);
 extern tree cp_build_compound_expr		(tree, tree, tsubst_flags_t);
-extern tree build_static_cast			(tree, tree, tsubst_flags_t);
-extern tree build_reinterpret_cast		(tree, tree, tsubst_flags_t);
-extern tree build_const_cast			(tree, tree, tsubst_flags_t);
+extern cp_expr build_static_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
+extern cp_expr build_reinterpret_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
+extern cp_expr build_const_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree build_c_cast			(location_t, tree, tree);
 extern cp_expr build_c_cast			(location_t loc, tree type,
 						 cp_expr expr);
-extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
+extern cp_expr cp_build_c_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern cp_expr build_x_modify_expr		(location_t, tree,
 						 enum tree_code, tree,
 						 tsubst_flags_t);
@@ -7613,7 +7618,8 @@ extern int lvalue_or_else			(tree, enum lvalue_use
 extern void check_template_keyword		(tree);
 extern bool check_raw_literal_operator		(const_tree decl);
 extern bool check_literal_operator_args		(const_tree, bool *, bool *);
-extern void maybe_warn_about_useless_cast       (tree, tree, tsubst_flags_t);
+extern void maybe_warn_about_useless_cast       (location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
 extern tree finish_left_unary_fold_expr      (tree, int);
@@ -7681,7 +7687,7 @@ extern tree build_scoped_ref			(tree, tree, tree *
 extern tree build_x_arrow			(location_t, tree,
 						 tsubst_flags_t);
 extern tree build_m_component_ref		(tree, tree, tsubst_flags_t);
-extern tree build_functional_cast		(location_t, tree, tree,
+extern cp_expr build_functional_cast		(location_t, tree, tree,
 						 tsubst_flags_t);
 extern tree add_exception_specifier		(tree, tree, tsubst_flags_t);
 extern tree merge_exception_specifiers		(tree, tree);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 279041)
+++ gcc/cp/decl.c	(working copy)
@@ -6483,7 +6483,8 @@ reshape_init (tree type, tree init, tsubst_flags_t
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  return cp_build_c_cast (type, elt, tf_warning_or_error);
+	  return cp_build_c_cast (input_location, type, elt,
+				  tf_warning_or_error);
 	}
       else
 	return error_mark_node;
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 279041)
+++ gcc/cp/method.c	(working copy)
@@ -474,7 +474,8 @@ forward_parm (tree parm)
   if (!TYPE_REF_P (type))
     type = cp_build_reference_type (type, /*rval=*/true);
   warning_sentinel w (warn_useless_cast);
-  exp = build_static_cast (type, exp, tf_warning_or_error);
+  exp = build_static_cast (input_location, type, exp,
+			   tf_warning_or_error);
   if (DECL_PACK_P (parm))
     exp = make_pack_expansion (exp);
   return exp;
@@ -1361,7 +1362,8 @@ build_comparison_op (tree fndecl, tsubst_flags_t c
 	      if (TREE_CODE (comp) == SPACESHIP_EXPR)
 		TREE_TYPE (comp) = rettype;
 	      else
-		comp = build_static_cast (rettype, comp, complain);
+		comp = build_static_cast (input_location, rettype, comp,
+					  complain);
 	      info.check (comp);
 	      if (info.defining)
 		{
@@ -1395,7 +1397,8 @@ build_comparison_op (tree fndecl, tsubst_flags_t c
 	    {
 	      tree seql = lookup_comparison_result (cc_strong_ordering,
 						    "equal", complain);
-	      val = build_static_cast (rettype, seql, complain);
+	      val = build_static_cast (input_location, rettype, seql,
+				       complain);
 	    }
 	  finish_return_stmt (val);
 	}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 279041)
+++ gcc/cp/parser.c	(working copy)
@@ -6895,36 +6895,38 @@ cp_parser_postfix_expression (cp_parser *parser, b
 	    break;
 	  }
 
+	/* Construct a location e.g. :
+	     reinterpret_cast <int *> (expr)
+	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	   ranging from the start of the "*_cast" token to the final closing
+	   paren, with the caret at the start.  */
+	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
+
 	switch (keyword)
 	  {
 	  case RID_DYNCAST:
 	    postfix_expression
-	      = build_dynamic_cast (type, expression, tf_warning_or_error);
+	      = build_dynamic_cast (cp_cast_loc, type, expression,
+				    tf_warning_or_error);
 	    break;
 	  case RID_STATCAST:
 	    postfix_expression
-	      = build_static_cast (type, expression, tf_warning_or_error);
+	      = build_static_cast (cp_cast_loc, type, expression,
+				   tf_warning_or_error);
 	    break;
 	  case RID_REINTCAST:
 	    postfix_expression
-	      = build_reinterpret_cast (type, expression,
+	      = build_reinterpret_cast (cp_cast_loc, type, expression,
                                         tf_warning_or_error);
 	    break;
 	  case RID_CONSTCAST:
 	    postfix_expression
-	      = build_const_cast (type, expression, tf_warning_or_error);
+	      = build_const_cast (cp_cast_loc, type, expression,
+				  tf_warning_or_error);
 	    break;
 	  default:
 	    gcc_unreachable ();
 	  }
-
-	/* Construct a location e.g. :
-	     reinterpret_cast <int *> (expr)
-	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	   ranging from the start of the "*_cast" token to the final closing
-	   paren, with the caret at the start.  */
-	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
-	postfix_expression.set_location (cp_cast_loc);
       }
       break;
 
@@ -9150,17 +9152,18 @@ get_cast_suggestion (tree dst_type, tree orig_expr
     return NULL;
 
   /* First try const_cast.  */
-  trial = build_const_cast (dst_type, orig_expr, tf_none);
+  trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "const_cast";
 
   /* If that fails, try static_cast.  */
-  trial = build_static_cast (dst_type, orig_expr, tf_none);
+  trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "static_cast";
 
   /* Finally, try reinterpret_cast.  */
-  trial = build_reinterpret_cast (dst_type, orig_expr, tf_none);
+  trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
+				  tf_none);
   if (trial != error_mark_node)
     return "reinterpret_cast";
 
@@ -10148,8 +10151,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
 
   /* Build the (type *)null that begins the traditional offsetof macro.  */
   tree object_ptr
-    = build_static_cast (build_pointer_type (type), null_pointer_node,
-			 tf_warning_or_error);
+    = build_static_cast (input_location, build_pointer_type (type),
+			 null_pointer_node, tf_warning_or_error);
 
   /* Parse the offsetof-member-designator.  We begin as if we saw "expr->".  */
   expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, object_ptr,
@@ -29277,8 +29280,7 @@ cp_parser_functional_cast (cp_parser* parser, tree
 					   parser->lexer);
   cast = build_functional_cast (combined_loc, type, expression_list,
                                 tf_warning_or_error);
-  cast.set_location (combined_loc);
-  
+
   /* [expr.const]/1: In an integral constant expression "only type
      conversions to integral or enumeration type can be used".  */
   if (TREE_CODE (type) == TYPE_DECL)
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 279041)
+++ gcc/cp/pt.c	(working copy)
@@ -19020,16 +19020,16 @@ tsubst_copy_and_build (tree t,
 	    r = build_functional_cast (input_location, type, op, complain);
 	    break;
 	  case REINTERPRET_CAST_EXPR:
-	    r = build_reinterpret_cast (type, op, complain);
+	    r = build_reinterpret_cast (input_location, type, op, complain);
 	    break;
 	  case CONST_CAST_EXPR:
-	    r = build_const_cast (type, op, complain);
+	    r = build_const_cast (input_location, type, op, complain);
 	    break;
 	  case DYNAMIC_CAST_EXPR:
-	    r = build_dynamic_cast (type, op, complain);
+	    r = build_dynamic_cast (input_location, type, op, complain);
 	    break;
 	  case STATIC_CAST_EXPR:
-	    r = build_static_cast (type, op, complain);
+	    r = build_static_cast (input_location, type, op, complain);
 	    break;
 	  default:
 	    gcc_unreachable ();
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c	(revision 279041)
+++ gcc/cp/rtti.c	(working copy)
@@ -123,7 +123,7 @@ static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
 
 static tree ifnonnull (tree, tree, tsubst_flags_t);
 static tree tinfo_name (tree, bool);
-static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
+static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
 static tree throw_bad_typeid (void);
 static tree get_tinfo_ptr (tree);
@@ -548,7 +548,8 @@ ifnonnull (tree test, tree result, tsubst_flags_t
    paper.  */
 
 static tree
-build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
+build_dynamic_cast_1 (location_t loc, tree type, tree expr,
+		      tsubst_flags_t complain)
 {
   enum tree_code tc = TREE_CODE (type);
   tree exprtype;
@@ -646,7 +647,7 @@ static tree
     tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
 			      ba_check, NULL, complain);
     if (binfo)
-      return build_static_cast (type, expr, complain);
+      return build_static_cast (loc, type, expr, complain);
   }
 
   /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
@@ -691,8 +692,9 @@ static tree
 		{
 		  tree expr = throw_bad_cast ();
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, old_expr);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, old_expr);
 		  /* Bash it to the expected type.  */
 		  TREE_TYPE (expr) = type;
 		  return expr;
@@ -706,8 +708,9 @@ static tree
 		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
 		{
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, op);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, op);
 		  retval = build_int_cst (type, 0);
 		  return retval;
 		}
@@ -717,7 +720,8 @@ static tree
 	  if (!flag_rtti)
 	    {
               if (complain & tf_error)
-		error ("%<dynamic_cast%> not permitted with %<-fno-rtti%>");
+		error_at (loc,
+			  "%<dynamic_cast%> not permitted with %<-fno-rtti%>");
 	      return error_mark_node;
 	    }
 
@@ -796,15 +800,17 @@ static tree
 
  fail:
   if (complain & tf_error)
-    error ("cannot %<dynamic_cast%> %qE (of type %q#T) to type %q#T (%s)",
-           old_expr, TREE_TYPE (old_expr), type, errstr);
+    error_at (loc, "cannot %<dynamic_cast%> %qE (of type %q#T) "
+	      "to type %q#T (%s)",
+	      old_expr, TREE_TYPE (old_expr), type, errstr);
   return error_mark_node;
 }
 
-tree
-build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_expr
+build_dynamic_cast (location_t loc, tree type, tree expr,
+		    tsubst_flags_t complain)
 {
-  tree r;
+  cp_expr r;
 
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
@@ -813,12 +819,18 @@ static tree
     {
       expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
       TREE_SIDE_EFFECTS (expr) = 1;
-      return convert_from_reference (expr);
+
+      r = convert_from_reference (expr);
+      r.set_location (loc);
+      return r;
     }
 
-  r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
+  r = convert_from_reference (build_dynamic_cast_1 (loc, type, expr,
+						    complain));
+  r.set_location (loc);
+
   if (r != error_mark_node)
-    maybe_warn_about_useless_cast (type, expr, complain);
+    maybe_warn_about_useless_cast (loc, type, expr, complain);
   return r;
 }
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 279041)
+++ gcc/cp/semantics.c	(working copy)
@@ -5918,9 +5918,11 @@ finish_omp_reduction_clause (tree c, bool *need_de
 	      if (need_static_cast)
 		{
 		  tree rtype = build_reference_type (atype);
-		  omp_out = build_static_cast (rtype, omp_out,
+		  omp_out = build_static_cast (input_location,
+					       rtype, omp_out,
 					       tf_warning_or_error);
-		  omp_in = build_static_cast (rtype, omp_in,
+		  omp_in = build_static_cast (input_location,
+					      rtype, omp_in,
 					      tf_warning_or_error);
 		  if (omp_out == error_mark_node || omp_in == error_mark_node)
 		    return true;
@@ -5955,9 +5957,11 @@ finish_omp_reduction_clause (tree c, bool *need_de
 		      return true;
 		    }
 		  tree rtype = build_reference_type (atype);
-		  omp_priv = build_static_cast (rtype, omp_priv,
+		  omp_priv = build_static_cast (input_location,
+						rtype, omp_priv,
 						tf_warning_or_error);
-		  omp_orig = build_static_cast (rtype, omp_orig,
+		  omp_orig = build_static_cast (input_location,
+						rtype, omp_orig,
 						tf_warning_or_error);
 		  if (omp_priv == error_mark_node
 		      || omp_orig == error_mark_node)
@@ -6138,13 +6142,16 @@ cp_omp_finish_iterators (tree iter)
       begin = mark_rvalue_use (begin);
       end = mark_rvalue_use (end);
       step = mark_rvalue_use (step);
-      begin = cp_build_c_cast (type, begin, tf_warning_or_error);
-      end = cp_build_c_cast (type, end, tf_warning_or_error);
+      begin = cp_build_c_cast (input_location, type, begin,
+			       tf_warning_or_error);
+      end = cp_build_c_cast (input_location, type, end,
+			     tf_warning_or_error);
       orig_step = step;
       if (!processing_template_decl)
 	step = orig_step = save_expr (step);
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
-      step = cp_build_c_cast (stype, step, tf_warning_or_error);
+      step = cp_build_c_cast (input_location, stype, step,
+			      tf_warning_or_error);
       if (POINTER_TYPE_P (type) && !processing_template_decl)
 	{
 	  begin = save_expr (begin);
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 279041)
+++ gcc/cp/tree.c	(working copy)
@@ -425,7 +425,8 @@ cp_stabilize_reference (tree ref)
 	  /* This inhibits warnings in, eg, cxx_mark_addressable
 	     (c++/60955).  */
 	  warning_sentinel s (extra_warnings);
-	  ref = build_static_cast (type, ref, tf_error);
+	  ref = build_static_cast (input_location, type, ref,
+				   tf_error);
 	}
     }
 
@@ -1222,7 +1223,8 @@ move (tree expr)
   tree type = TREE_TYPE (expr);
   gcc_assert (!TYPE_REF_P (type));
   type = cp_build_reference_type (type, /*rval*/true);
-  return build_static_cast (type, expr, tf_warning_or_error);
+  return build_static_cast (input_location, type, expr,
+			    tf_warning_or_error);
 }
 
 /* Used by the C++ front end to build qualified array types.  However,
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 279041)
+++ gcc/cp/typeck.c	(working copy)
@@ -6446,7 +6446,7 @@ cp_build_unary_op (enum tree_code code, tree xarg,
 				   build_zero_cst (TREE_TYPE (arg)), complain);
       arg = perform_implicit_conversion (boolean_type_node, arg,
 					 complain);
-      val = invert_truthvalue_loc (input_location, arg);
+      val = invert_truthvalue_loc (location, arg);
       if (arg != error_mark_node)
 	return val;
       errstring = _("in argument to unary !");
@@ -7075,8 +7075,9 @@ cp_build_compound_expr (tree lhs, tree rhs, tsubst
 */
 
 static bool
-check_for_casting_away_constness (tree src_type, tree dest_type,
-				  enum tree_code cast, tsubst_flags_t complain)
+check_for_casting_away_constness (location_t loc, tree src_type,
+				  tree dest_type, enum tree_code cast,
+				  tsubst_flags_t complain)
 {
   /* C-style casts are allowed to cast away constness.  With
      WARN_CAST_QUAL, we still want to issue a warning.  */
@@ -7090,23 +7091,23 @@ static bool
     {
     case CAST_EXPR:
       if (complain & tf_warning)
-	warning (OPT_Wcast_qual,
-		 "cast from type %qT to type %qT casts away qualifiers",
-		 src_type, dest_type);
+	warning_at (loc, OPT_Wcast_qual,
+		    "cast from type %qT to type %qT casts away qualifiers",
+		    src_type, dest_type);
       return false;
-      
+
     case STATIC_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<static_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
+		  "away qualifiers",
+		  src_type, dest_type);
       return true;
-      
+
     case REINTERPRET_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<reinterpret_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
+		  "casts away qualifiers",
+		  src_type, dest_type);
       return true;
 
     default:
@@ -7116,7 +7117,8 @@ static bool
 
 /* Warns if the cast from expression EXPR to type TYPE is useless.  */
 void
-maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
+maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
+			       tsubst_flags_t complain)
 {
   if (warn_useless_cast
       && complain & tf_warning)
@@ -7126,22 +7128,22 @@ void
 	       ? xvalue_p (expr) : lvalue_p (expr))
 	   && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
 	  || same_type_p (TREE_TYPE (expr), type))
-	warning (OPT_Wuseless_cast, "useless cast to type %q#T", type);
+	warning_at (loc, OPT_Wuseless_cast,
+		    "useless cast to type %q#T", type);
     }
 }
 
 /* Warns if the cast ignores cv-qualifiers on TYPE.  */
-void
-maybe_warn_about_cast_ignoring_quals (tree type, tsubst_flags_t complain)
+static void
+maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
+				      tsubst_flags_t complain)
 {
   if (warn_ignored_qualifiers
       && complain & tf_warning
       && !CLASS_TYPE_P (type)
       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
-    {
-      warning (OPT_Wignored_qualifiers, "type qualifiers ignored on cast "
-	       "result type");
-    }
+    warning_at (loc, OPT_Wignored_qualifiers,
+		"type qualifiers ignored on cast result type");
 }
 
 /* Convert EXPR (an expression with pointer-to-member type) to TYPE
@@ -7200,7 +7202,7 @@ convert_ptrmem (tree type, tree expr, bool allow_i
    indicate whether or not the cast was valid.  */
 
 static tree
-build_static_cast_1 (tree type, tree expr, bool c_cast_p,
+build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
 		     bool *valid_p, tsubst_flags_t complain)
 {
   tree intype;
@@ -7269,7 +7271,7 @@ static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7427,7 +7429,8 @@ static tree
 	return expr;
 
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
@@ -7439,7 +7442,7 @@ static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7476,7 +7479,7 @@ static tree
       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
 	{
 	  if (!c_cast_p
-	      && check_for_casting_away_constness (intype, type,
+	      && check_for_casting_away_constness (loc, intype, type,
 						   STATIC_CAST_EXPR,
 						   complain))
 	    return error_mark_node;
@@ -7498,7 +7501,8 @@ static tree
       && TYPE_PTROB_P (type))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       if (processing_template_decl)
@@ -7512,11 +7516,12 @@ static tree
 
 /* Return an expression representing static_cast<TYPE>(EXPR).  */
 
-tree
-build_static_cast (tree type, tree oexpr, tsubst_flags_t complain)
+cp_expr
+build_static_cast (location_t loc, tree type, tree oexpr,
+		   tsubst_flags_t complain)
 {
   tree expr = oexpr;
-  tree result;
+  cp_expr result;
   bool valid_p;
 
   if (type == error_mark_node || expr == error_mark_node)
@@ -7530,7 +7535,10 @@ static tree
       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
       /* We don't know if it will or will not have side effects.  */
       TREE_SIDE_EFFECTS (expr) = 1;
-      return convert_from_reference (expr);
+
+      result = convert_from_reference (expr);
+      result.set_location (loc);
+      return result;
     }
   else if (processing_template_decl)
     expr = build_non_dependent_expr (expr);
@@ -7542,14 +7550,16 @@ static tree
       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
     expr = TREE_OPERAND (expr, 0);
 
-  result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
-                                complain);
+  result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
+				&valid_p, complain);
+  result.set_location (loc);
+
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, expr, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, expr, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       if (processing_template_decl)
 	goto tmpl;
@@ -7558,8 +7568,8 @@ static tree
 
   if (complain & tf_error)
     {
-      error ("invalid %<static_cast%> from type %qT to type %qT",
-	     TREE_TYPE (expr), type);
+      error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
+		TREE_TYPE (expr), type);
       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
 	  && CLASS_TYPE_P (TREE_TYPE (type))
 	    && !COMPLETE_TYPE_P (TREE_TYPE (type)))
@@ -7633,8 +7643,9 @@ build_nop_reinterpret (tree type, tree expr)
    indicate whether or not reinterpret_cast was valid.  */
 
 static tree
-build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
-			  bool *valid_p, tsubst_flags_t complain)
+build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
+			  bool c_cast_p, bool *valid_p,
+			  tsubst_flags_t complain)
 {
   tree intype;
 
@@ -7670,9 +7681,9 @@ static tree
       else if (!lvalue_p (expr))
 	{
           if (complain & tf_error)
-            error ("invalid cast of an rvalue expression of type "
-                   "%qT to type %qT",
-                   intype, type);
+            error_at (loc, "invalid cast of an rvalue expression of type "
+		      "%qT to type %qT",
+		      intype, type);
 	  return error_mark_node;
 	}
 
@@ -7683,8 +7694,8 @@ static tree
           && (complain & tf_warning)
 	  && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
 			 COMPARE_BASE | COMPARE_DERIVED)))
-	warning (0, "casting %qT to %qT does not dereference pointer",
-		 intype, type);
+	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
+		    intype, type);
 
       expr = cp_build_addr_expr (expr, complain);
 
@@ -7693,7 +7704,7 @@ static tree
 
       if (expr != error_mark_node)
 	expr = build_reinterpret_cast_1
-	  (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+	  (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
 	   valid_p, complain);
       if (expr != error_mark_node)
 	/* cp_build_indirect_ref isn't right for rvalue refs.  */
@@ -7740,7 +7751,7 @@ static tree
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            permerror (input_location, "cast from %qH to %qI loses precision",
+            permerror (loc, "cast from %qH to %qI loses precision",
                        intype, type);
           else
             return error_mark_node;
@@ -7764,9 +7775,9 @@ static tree
       if ((complain & tf_warning)
 	  && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
 					     TREE_TYPE (intype)))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible function types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible function types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
@@ -7775,9 +7786,9 @@ static tree
 	  && !cxx_safe_function_type_cast_p
 		(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
 		 TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible pointer to member types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible pointer to member types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
@@ -7784,7 +7795,7 @@ static tree
 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type,
+	  && check_for_casting_away_constness (loc, intype, type,
 					       REINTERPRET_CAST_EXPR,
 					       complain))
 	return error_mark_node;
@@ -7797,8 +7808,9 @@ static tree
 	  && COMPLETE_TYPE_P (TREE_TYPE (intype))
 	  && min_align_of_type (TREE_TYPE (type))
 	     > min_align_of_type (TREE_TYPE (intype)))
-	warning (OPT_Wcast_align, "cast from %qH to %qI "
-		 "increases required alignment of target type", intype, type);
+	warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+		    "increases required alignment of target type",
+		    intype, type);
 
       if (warn_strict_aliasing <= 2)
 	/* strict_aliasing_warning STRIP_NOPs its expr.  */
@@ -7812,9 +7824,9 @@ static tree
       if (complain & tf_warning)
 	/* C++11 5.2.10 p8 says that "Converting a function pointer to an
 	   object pointer type or vice versa is conditionally-supported."  */
-	warning (OPT_Wconditionally_supported,
-		 "casting between pointer-to-function and pointer-to-object "
-		 "is conditionally-supported");
+	warning_at (loc, OPT_Wconditionally_supported,
+		    "casting between pointer-to-function and "
+		    "pointer-to-object is conditionally-supported");
       return build_nop_reinterpret (type, expr);
     }
   else if (gnu_vector_type_p (type))
@@ -7827,7 +7839,8 @@ static tree
       if (valid_p)
 	*valid_p = false;
       if (complain & tf_error)
-        error ("invalid cast from type %qT to type %qT", intype, type);
+        error_at (loc, "invalid cast from type %qT to type %qT",
+		  intype, type);
       return error_mark_node;
     }
 
@@ -7838,10 +7851,11 @@ static tree
   return expr;
 }
 
-tree
-build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_expr
+build_reinterpret_cast (location_t loc, tree type, tree expr,
+			tsubst_flags_t complain)
 {
-  tree r;
+  cp_expr r;
 
   if (type == error_mark_node || expr == error_mark_node)
     return error_mark_node;
@@ -7854,15 +7868,20 @@ static tree
 	  && type_dependent_expression_p (expr))
 	/* There might turn out to be side effects inside expr.  */
 	TREE_SIDE_EFFECTS (t) = 1;
-      return convert_from_reference (t);
+
+      r = convert_from_reference (t);
+      r.set_location (loc);
+      return r;
     }
 
-  r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+  r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
 				/*valid_p=*/NULL, complain);
+  r.set_location (loc);
+
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
   return r;
 }
@@ -7875,8 +7894,8 @@ static tree
    whether or not the conversion succeeded.  */
 
 static tree
-build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
-		    bool *valid_p)
+build_const_cast_1 (location_t loc, tree dst_type, tree expr,
+		    tsubst_flags_t complain, bool *valid_p)
 {
   tree src_type;
   tree reference_type;
@@ -7895,9 +7914,9 @@ static tree
   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is not a pointer, "
-	       "reference, nor a pointer-to-data-member type", dst_type);
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is not a pointer, reference, "
+		  "nor a pointer-to-data-member type", dst_type);
       return error_mark_node;
     }
 
@@ -7904,10 +7923,10 @@ static tree
   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is a pointer or reference to a function type",
-	       dst_type);
-      return error_mark_node;
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is a pointer or reference to a function type",
+		  dst_type);
+       return error_mark_node;
     }
 
   /* A prvalue of non-class type is cv-unqualified.  */
@@ -7946,10 +7965,10 @@ static tree
       else
 	{
 	  if (complain & tf_error)
-	    error ("invalid %<const_cast%> of an rvalue of type %qT "
-		   "to type %qT",
-		   src_type, dst_type);
-	  return error_mark_node;
+	    error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
+		      "to type %qT",
+		      src_type, dst_type);
+ 	  return error_mark_node;
 	}
       dst_type = build_pointer_type (TREE_TYPE (dst_type));
       src_type = build_pointer_type (src_type);
@@ -7974,7 +7993,7 @@ static tree
 	      *valid_p = true;
 	      /* This cast is actually a C-style cast.  Issue a warning if
 		 the user is making a potentially unsafe cast.  */
-	      check_for_casting_away_constness (src_type, dst_type,
+	      check_for_casting_away_constness (loc, src_type, dst_type,
 						CAST_EXPR, complain);
 	      /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
 	      if ((STRICT_ALIGNMENT || warn_cast_align == 2)
@@ -7981,9 +8000,9 @@ static tree
 		  && (complain & tf_warning)
 		  && min_align_of_type (TREE_TYPE (dst_type))
 		     > min_align_of_type (TREE_TYPE (src_type)))
-		warning (OPT_Wcast_align, "cast from %qH to %qI "
-			 "increases required alignment of target type",
-			 src_type, dst_type);
+		warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+			    "increases required alignment of target type",
+			    src_type, dst_type);
 	    }
 	  if (reference_type)
 	    {
@@ -8011,20 +8030,21 @@ static tree
       else if (valid_p
 	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
 					    TREE_TYPE (src_type)))
-	check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
-					  complain);
+	check_for_casting_away_constness (loc, src_type, dst_type,
+					  CAST_EXPR, complain);
     }
 
   if (complain & tf_error)
-    error ("invalid %<const_cast%> from type %qT to type %qT",
-	   src_type, dst_type);
+    error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
+	      src_type, dst_type);
   return error_mark_node;
 }
 
-tree
-build_const_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_expr
+build_const_cast (location_t loc, tree type, tree expr,
+		  tsubst_flags_t complain)
 {
-  tree r;
+  cp_expr r;
 
   if (type == error_mark_node || error_operand_p (expr))
     return error_mark_node;
@@ -8037,14 +8057,19 @@ static tree
 	  && type_dependent_expression_p (expr))
 	/* There might turn out to be side effects inside expr.  */
 	TREE_SIDE_EFFECTS (t) = 1;
-      return convert_from_reference (t);
+
+      r = convert_from_reference (t);
+      r.set_location (loc);
+      return r;
     }
 
-  r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL);
+  r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
+  r.set_location (loc);
+
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
   return r;
 }
@@ -8052,9 +8077,9 @@ static tree
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (location_t /*loc*/, tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
 {
-  return cp_build_c_cast (type, expr, tf_warning_or_error);
+  return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
 }
 
 /* Like the "build_c_cast" used for c-common, but using cp_expr to
@@ -8064,7 +8089,7 @@ tree
 cp_expr
 build_c_cast (location_t loc, tree type, cp_expr expr)
 {
-  cp_expr result = cp_build_c_cast (type, expr, tf_warning_or_error);
+  cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
   result.set_location (loc);
   return result;
 }
@@ -8072,8 +8097,9 @@ build_c_cast (location_t loc, tree type, cp_expr e
 /* Build an expression representing an explicit C-style cast to type
    TYPE of expression EXPR.  */
 
-tree
-cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
+static tree
+cp_build_c_cast_1 (location_t loc, tree type, tree expr,
+		   tsubst_flags_t complain)
 {
   tree value = expr;
   tree result;
@@ -8112,7 +8138,8 @@ build_c_cast (location_t loc, tree type, cp_expr e
       if (TYPE_PTR_P (TREE_TYPE (expr)))
 	{
           if (complain & tf_error)
-            permerror (input_location, "ISO C++ forbids casting to an array type %qT", type);
+            permerror (loc, "ISO C++ forbids casting to an array type %qT",
+		       type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
@@ -8120,7 +8147,8 @@ build_c_cast (location_t loc, tree type, cp_expr e
       else
 	{
           if (complain & tf_error)
-            error ("ISO C++ forbids casting to an array type %qT", type);
+            error_at (loc, "ISO C++ forbids casting to an array type %qT",
+		      type);
 	  return error_mark_node;
 	}
     }
@@ -8128,7 +8156,7 @@ build_c_cast (location_t loc, tree type, cp_expr e
   if (FUNC_OR_METHOD_TYPE_P (type))
     {
       if (complain & tf_error)
-        error ("invalid cast to function type %qT", type);
+        error_at (loc, "invalid cast to function type %qT", type);
       return error_mark_node;
     }
 
@@ -8138,28 +8166,28 @@ build_c_cast (location_t loc, tree type, cp_expr e
       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
       /* Don't warn about converting any constant.  */
       && !TREE_CONSTANT (value))
-    warning_at (input_location, OPT_Wint_to_pointer_cast, 
+    warning_at (loc, OPT_Wint_to_pointer_cast, 
 		"cast to pointer from integer of different size");
 
   /* A C-style cast can be a const_cast.  */
-  result = build_const_cast_1 (type, value, complain & tf_warning,
+  result = build_const_cast_1 (loc, type, value, complain & tf_warning,
 			       &valid_p);
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, value, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, value, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       return result;
     }
 
   /* Or a static cast.  */
-  result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
+  result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				&valid_p, complain);
   /* Or a reinterpret_cast.  */
   if (!valid_p)
-    result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+    result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				       &valid_p, complain);
   /* The static_cast or reinterpret_cast may be followed by a
      const_cast.  */
@@ -8170,8 +8198,8 @@ build_c_cast (location_t loc, tree type, cp_expr e
     {
       tree result_type;
 
-      maybe_warn_about_useless_cast (type, value, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, value, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 
       /* Non-class rvalues always have cv-unqualified type.  */
       if (!CLASS_TYPE_P (type))
@@ -8186,7 +8214,7 @@ build_c_cast (location_t loc, tree type, cp_expr e
 	 to succeed.  */
       if (!same_type_p (non_reference (type), non_reference (result_type)))
 	{
-	  result = build_const_cast_1 (type, result, false, &valid_p);
+	  result = build_const_cast_1 (loc, type, result, false, &valid_p);
 	  gcc_assert (valid_p);
 	}
       return result;
@@ -8194,6 +8222,16 @@ build_c_cast (location_t loc, tree type, cp_expr e
 
   return error_mark_node;
 }
+
+cp_expr
+cp_build_c_cast (location_t loc, tree type, tree expr,
+		 tsubst_flags_t complain)
+{
+  cp_expr result = cp_build_c_cast_1 (loc, type, expr, complain);
+  result.set_location (loc);
+  return result;
+}
+
 
 /* For use from the C common bits.  */
 tree
@@ -8878,7 +8916,7 @@ build_ptrmemfunc (tree type, tree pfn, int force,
 	  if (same_type_p (to_type, pfn_type))
 	    return pfn;
 	  else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
-	    return build_reinterpret_cast (to_type, pfn, 
+	    return build_reinterpret_cast (input_location, to_type, pfn, 
                                            complain);
 	}
 
@@ -8912,7 +8950,7 @@ build_ptrmemfunc (tree type, tree pfn, int force,
   /* Handle null pointer to member function conversions.  */
   if (null_ptr_cst_p (pfn))
     {
-      pfn = cp_build_c_cast (type, pfn, complain);
+      pfn = cp_build_c_cast (input_location, type, pfn, complain);
       return build_ptrmemfunc1 (to_type,
 				integer_zero_node,
 				pfn);
@@ -9067,7 +9105,7 @@ convert_for_assignment (tree type, tree rhs,
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  rhs = cp_build_c_cast (type, elt, complain);
+	  rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
 	}
       else
 	rhs = error_mark_node;
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 279041)
+++ gcc/cp/typeck2.c	(working copy)
@@ -2227,9 +2227,9 @@ build_m_component_ref (tree datum, tree component,
 
 /* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
 
-tree
-build_functional_cast (location_t loc, tree exp, tree parms,
-		       tsubst_flags_t complain)
+static tree
+build_functional_cast_1 (location_t loc, tree exp, tree parms,
+			 tsubst_flags_t complain)
 {
   /* This is either a call to a constructor,
      or a C cast in C++'s `functional' notation.  */
@@ -2318,7 +2318,7 @@ build_m_component_ref (tree datum, tree component,
 
       /* This must build a C cast.  */
       parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
-      return cp_build_c_cast (type, parms, complain);
+      return cp_build_c_cast (loc, type, parms, complain);
     }
 
   /* Prepare to evaluate as a call to a constructor.  If this expression
@@ -2339,7 +2339,7 @@ build_m_component_ref (tree datum, tree component,
      conversion is equivalent (in definedness, and if defined in
      meaning) to the corresponding cast expression.  */
   if (parms && TREE_CHAIN (parms) == NULL_TREE)
-    return cp_build_c_cast (type, TREE_VALUE (parms), complain);
+    return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);
 
   /* [expr.type.conv]
 
@@ -2367,6 +2367,16 @@ build_m_component_ref (tree datum, tree component,
 
   return build_cplus_new (type, exp, complain);
 }
+
+cp_expr
+build_functional_cast (location_t loc, tree exp, tree parms,
+		       tsubst_flags_t complain)
+{
+  cp_expr result = build_functional_cast_1 (loc, exp, parms, complain);
+  result.set_location (loc);
+  return result;  
+}
+
 
 
 /* Add new exception specifier SPEC, to the LIST we currently have.
Index: gcc/testsuite/c-c++-common/Wcast-align.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-align.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-align.c	(working copy)
@@ -16,8 +16,8 @@ struct t { double x; } *q;
 void
 foo (void)
 {
-  y = (c *) x;  /* { dg-warning "alignment" } */
-  z = (d *) x;  /* { dg-warning "alignment" } */
+  y = (c *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
+  z = (d *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
   (long long *) p;  /* { dg-bogus "alignment" } */
   (double *) q;     /* { dg-bogus "alignment" } */
 }
Index: gcc/testsuite/c-c++-common/Wcast-function-type.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-function-type.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-function-type.c	(working copy)
@@ -24,8 +24,8 @@ void
 foo (void)
 {
   a = (f1 *) f; /* { dg-bogus   "incompatible function types" } */
-  b = (f2 *) f; /* { dg-warning "incompatible function types" } */
+  b = (f2 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   c = (f3 *) f; /* { dg-bogus   "incompatible function types" } */
-  d = (f4 *) f; /* { dg-warning "incompatible function types" } */
+  d = (f4 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   e = (f5 *) f; /* { dg-bogus   "incompatible function types" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(working copy)
@@ -8,5 +8,5 @@ char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(working copy)
@@ -8,5 +8,5 @@ char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(working copy)
@@ -17,6 +17,6 @@ char
 g (void)
 {
   return (char) p;
-/* { dg-warning "cast from pointer to integer of different size" "" { target c } .-1 } */
-/* { dg-error "cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
+/* { dg-warning "10:cast from pointer to integer of different size" "" { target c } .-1 } */
+/* { dg-error "10:cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
 }
Index: gcc/testsuite/g++.dg/Wcast-function-type.C
===================================================================
--- gcc/testsuite/g++.dg/Wcast-function-type.C	(revision 279041)
+++ gcc/testsuite/g++.dg/Wcast-function-type.C	(working copy)
@@ -12,6 +12,6 @@ typedef void (S::*MF)(int);
 void
 foo (void)
 {
-  MF p1 = (MF)&S::foo; /* { dg-warning "pointer to member" } */
+  MF p1 = (MF)&S::foo; /* { dg-warning "11:cast between incompatible pointer to member" } */
   MF p2 = (MF)&S::bar; /* { dg-bogus   "pointer to member" } */
 }
Index: gcc/testsuite/g++.dg/addr_builtin-1.C
===================================================================
--- gcc/testsuite/g++.dg/addr_builtin-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/addr_builtin-1.C	(working copy)
@@ -93,8 +93,8 @@ static F* test_taking_address_of_gcc_builtin ()
   // Expect a diagnostic for an invalid static_cast of a function to
   // either uintptr_t or enum, rather than one for the argument being
   // a built-in function, since the former is more relevant than the latter.
-  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "invalid" }
-  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "invalid" }
+  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
+  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
 
   // Reinterpret cast can cast a function to uintptr_t or enum,
   // so verify that a diagnostic is issued for the use of a builtin.
Index: gcc/testsuite/g++.dg/conversion/const2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/const2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/const2.C	(working copy)
@@ -7,5 +7,5 @@ typedef int D::*dm;
 bm bp;
 
 void f() {
-  const_cast<dm>(bp); // { dg-error "" }
+  const_cast<dm>(bp); // { dg-error "3:invalid .const_cast." }
 }
Index: gcc/testsuite/g++.dg/conversion/dynamic1.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/dynamic1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/dynamic1.C	(working copy)
@@ -11,5 +11,5 @@ A& bar();
 
 void baz()
 {
-  dynamic_cast<A&>( bar().foo );  // { dg-error "cannot 'dynamic_cast'" }
+  dynamic_cast<A&>( bar().foo );  // { dg-error "3:cannot 'dynamic_cast'" }
 }
Index: gcc/testsuite/g++.dg/conversion/ptrmem2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem2.C	(working copy)
@@ -35,9 +35,9 @@ const int B::*p9 = static_cast<const int B::*>(&D:
 const int D::*p10 = static_cast<const int D::*>(&B::x);
 
 // Invalid conversions which decrease cv-qualification.
-int B::*p11 = static_cast<int B::*>(p10); // { dg-error "casts away qualifiers" }
-int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "casts away qualifiers" }
+int B::*p11 = static_cast<int B::*>(p10); // { dg-error "15:.static_cast. from type .const int D::\\*. to type .int B::\\*. casts away qualifiers" }
+int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "15:.static_cast. from type .const int B::\\*. to type .int D::\\*. casts away qualifiers" }
 
 // Attempts to change member type.
-float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "invalid .static_cast." }
-float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "invalid .static_cast." }
+float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "17:invalid .static_cast." }
+float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "17:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/ptrmem3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem3.C	(working copy)
@@ -27,5 +27,5 @@ int (A::*p7)() = static_cast<int (A::*)()>(&D::f);
 int (D::*p8)() = static_cast<int (D::*)()>(&A::f);  // { dg-error "" }
 
 // Attempts to change member type.
-float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "" }
-float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "" }
+float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "21:invalid .static_cast." }
+float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "21:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/qual3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/qual3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/qual3.C	(working copy)
@@ -24,30 +24,30 @@ f (P p, Q q, Q2 q2, R r, S s, T t)
   const_cast<P>(q2);
   const_cast<Q>(p);
   const_cast<Q2>(p);
-  const_cast<S>(p); // { dg-error "invalid .const_cast." }
-  const_cast<P>(s); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q2); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(s); // { dg-error "invalid .const_cast." }
-  const_cast<Q2>(s); // { dg-error "invalid .const_cast." }
+  const_cast<S>(p); // { dg-error "3:invalid .const_cast." }
+  const_cast<P>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q2); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q2>(s); // { dg-error "3:invalid .const_cast." }
   const_cast<T>(s);
   const_cast<S>(t);
-  const_cast<T>(q); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(t); // { dg-error "invalid .const_cast." }
+  const_cast<T>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(t); // { dg-error "3:invalid .const_cast." }
 
   // Test reinterpret_cast.
-  reinterpret_cast<P>(q); // { dg-error "casts away qualifiers" }
-  reinterpret_cast<P>(q2); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
+  reinterpret_cast<P>(q2); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(p);
   reinterpret_cast<Q2>(p);
   reinterpret_cast<S>(p);
-  reinterpret_cast<P>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(q);
   reinterpret_cast<S>(q2);
   reinterpret_cast<Q>(s);
   reinterpret_cast<Q2>(s);
-  reinterpret_cast<T>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(t);
-  reinterpret_cast<T>(q); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(t);
 }
Index: gcc/testsuite/g++.dg/conversion/reinterpret3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/reinterpret3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/reinterpret3.C	(working copy)
@@ -3,5 +3,5 @@ struct S {};
 S s;
 
 void f() {
-  reinterpret_cast<const S>(s); // { dg-error "" }
+  reinterpret_cast<const S>(s); // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C	(working copy)
@@ -14,11 +14,11 @@ template <class T>
 constexpr bool f ()
 {
 #if __cplusplus > 201103L
-  T *p = reinterpret_cast<T*>(sizeof (T));
+  T *p = reinterpret_cast<T*>(sizeof (T));  // { dg-error "not a constant expression|in .constexpr. expansion of " }
   return p;
 #else
-  return *reinterpret_cast<T*>(sizeof (T));
+  return *reinterpret_cast<T*>(sizeof (T));  // { dg-error "not a constant expression|in .constexpr. expansion of " }
 #endif
 }
 
-constexpr bool b = f<int>();   // { dg-error "not a constant expression|in .constexpr. expansion of " }
+constexpr bool b = f<int>();
Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(working copy)
@@ -4,7 +4,7 @@
 void foo()
 {
   int i;
-  static_cast<void(*)()>([i]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([=]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([&]{});  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)()>([i]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([=]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([&]{});  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/nullptr04.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(working copy)
@@ -4,13 +4,13 @@
 
 __extension__ typedef __INTPTR_TYPE__ intptr_t;
 
-const int n4 = static_cast<const int>(nullptr); // { dg-error "invalid 'static_cast' " }
-const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "loses precision" }
+const int n4 = static_cast<const int>(nullptr); // { dg-error "16:invalid 'static_cast' " }
+const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n6 = reinterpret_cast<intptr_t>(nullptr);
 const intptr_t n7 = (intptr_t)nullptr;
 
 decltype(nullptr) mynull = 0;
-const int n8 = static_cast<const int>(mynull); // { dg-error "invalid 'static_cast' " }
-const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "loses precision" }
+const int n8 = static_cast<const int>(mynull); // { dg-error "16:invalid 'static_cast' " }
+const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n10 = reinterpret_cast<intptr_t>(mynull);
 const intptr_t n11 = (intptr_t)mynull;
Index: gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(working copy)
@@ -6,5 +6,5 @@ struct S { };
 void
 foo ()
 {
-  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "invalid cast of an rvalue expression of type 'void' to type" }
+  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "12:invalid cast of an rvalue expression of type 'void' to type" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/rv-cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(working copy)
@@ -10,11 +10,11 @@ struct A { };
 int main()
 {
   const_cast<int&>(lval<int>());
-  const_cast<int&>(xval<int>());   // { dg-error "" }
-  const_cast<int&>(prval<int>());  // { dg-error "" }
+  const_cast<int&>(xval<int>());   // { dg-error "3:invalid .const_cast. of an rvalue" }
+  const_cast<int&>(prval<int>());  // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<int&&>(lval<int>());
   const_cast<int&&>(xval<int>());
-  const_cast<int&&>(prval<int>()); // { dg-error "" }
+  const_cast<int&&>(prval<int>()); // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<A&&>(lval<A>());
   const_cast<A&&>(xval<A>());
   const_cast<A&&>(prval<A>());
Index: gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(working copy)
@@ -4,10 +4,10 @@
 void foo()
 {
   int i;
-  static_cast<void(*)(int)>([i](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([=](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([&](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)(int)>([i](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([=](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([&](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(working copy)
@@ -10,5 +10,5 @@ void f()
   NP np;
 
   static_cast<P>(np);
-  static_cast<NP>(p);		// { dg-error "" }
+  static_cast<NP>(p);		// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/cpp2a/array-conv9.C
===================================================================
--- gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(working copy)
@@ -8,7 +8,7 @@ void
 test ()
 {
   int (&r)[1] = const_cast<int(&)[1]>(arr);
-  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "invalid" }
+  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "17:invalid .const_cast." }
   int (&r3)[1] = (int(&)[1]) arr;
   int (&r4)[] = (int(&)[]) arr;
   int (&r5)[1] = static_cast<int(&)[1]>(arr);
@@ -23,5 +23,5 @@ test ()
   int(*p6)[] = (int(*)[1]) (int(*)[]) &arr;
   int(*p7)[] = static_cast<int(*)[]>(&arr);
   int(*p8)[] = static_cast<int(*)[1]>(&arr);
-  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "invalid" }
+  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "16:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/expr/cast11.C
===================================================================
--- gcc/testsuite/g++.dg/expr/cast11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/cast11.C	(working copy)
@@ -13,22 +13,22 @@ struct B { int i; const char c; } b = {};
 void f1()
 {
   int i = 0;
-  f((long const)i);			// { dg-warning "qualifiers ignored" }
-  f((int* const)&i);			// { dg-warning "qualifiers ignored" }
-  f((int const* const)&i);		// { dg-warning "qualifiers ignored" }
-  f((long* const)&i);			// { dg-warning "qualifiers ignored" }
+  f((long const)i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int* const)&i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int const* const)&i);		// { dg-warning "5:type qualifiers ignored" }
+  f((long* const)&i);			// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<long const>(i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<long const>(i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long* const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
   using ptrmem = int B::*;
-  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" }
+  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "5:type qualifiers ignored" }
 
   // No warnings, not a cv-qualified type:
   using ptrmem2 = const char B::*;
Index: gcc/testsuite/g++.dg/expr/static_cast8.C
===================================================================
--- gcc/testsuite/g++.dg/expr/static_cast8.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/static_cast8.C	(working copy)
@@ -9,9 +9,9 @@ extern C* c;
 
 void pointers(C* c, A2* a2, B1* b1)
 {
-  (void) static_cast<A1*>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C*>(a2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<B2*>(b1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<A1*>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C*>(a2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<B2*>(b1);	// { dg-error "10:invalid 'static_cast'" }
 }
 
 struct D1; // { dg-message "note: class type 'D1' is incomplete" }
@@ -21,7 +21,7 @@ struct E2; // { dg-message "note: class type 'E2'
 
 void references(C& c, D2& d2, E1& e1)
 {
-  (void) static_cast<D1&>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C&>(d2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<E2&>(e1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<D1&>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C&>(d2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<E2&>(e1);	// { dg-error "10:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/ext/vector6.C
===================================================================
--- gcc/testsuite/g++.dg/ext/vector6.C	(revision 279041)
+++ gcc/testsuite/g++.dg/ext/vector6.C	(working copy)
@@ -8,5 +8,5 @@ typedef union {__v_4F v; float a[4];} __v4F;
 void f(void)
 {
       __v_4F b;
-      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "" }
+      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "8:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/other/conversion1.C
===================================================================
--- gcc/testsuite/g++.dg/other/conversion1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/other/conversion1.C	(working copy)
@@ -13,5 +13,5 @@ int main()
 {
   long long m;
   
-  (void (QObject::*)()) m;    // { dg-error "invalid cast" }
+  (void (QObject::*)()) m;    // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/parse/pr26997.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr26997.C	(revision 279041)
+++ gcc/testsuite/g++.dg/parse/pr26997.C	(working copy)
@@ -21,7 +21,7 @@ class C {
 
 C bar (void)
 {
-  (C ())(3); // { dg-error "invalid cast" } 
+  (C ())(3); // { dg-error "3:invalid cast" } 
   return (C ());
 }
 
@@ -41,9 +41,9 @@ void foo2 (void)
 {
   C ()[2];
   (C ())[2];
-  (S ())(3); // { dg-error "invalid cast" } 
-  (C())*var; // { dg-error "invalid cast" } 
-  (C())+var;  // { dg-error "invalid cast" } 
+  (S ())(3); // { dg-error "3:invalid cast" } 
+  (C())*var; // { dg-error "3:invalid cast" } 
+  (C())+var;  // { dg-error "3:invalid cast" } 
   S()(3);
   (S()(3));
 }
Index: gcc/testsuite/g++.dg/rtti/no-rtti.C
===================================================================
--- gcc/testsuite/g++.dg/rtti/no-rtti.C	(revision 279041)
+++ gcc/testsuite/g++.dg/rtti/no-rtti.C	(working copy)
@@ -14,5 +14,5 @@ A* f();
 
 int main()
 {
-   B* b = dynamic_cast<B*>(f()); // { dg-error "" }
+   B* b = dynamic_cast<B*>(f()); // { dg-error "11:.dynamic_cast. not permitted" }
 }
Index: gcc/testsuite/g++.dg/tc1/dr137.C
===================================================================
--- gcc/testsuite/g++.dg/tc1/dr137.C	(revision 279041)
+++ gcc/testsuite/g++.dg/tc1/dr137.C	(working copy)
@@ -9,5 +9,5 @@ const void* v;
 void foo(void)
 {
   (void)static_cast<const volatile A *>(v);
-  (void)static_cast<A *>(v);  // { dg-error "" "static_cast cannot remove cv qualifiers" }
+  (void)static_cast<A *>(v);  // { dg-error "9:.static_cast. from type .const void\\*. to type .A\\*. casts away qualifiers" "static_cast cannot remove cv qualifiers" }
 }
Index: gcc/testsuite/g++.dg/template/cast4.C
===================================================================
--- gcc/testsuite/g++.dg/template/cast4.C	(revision 279041)
+++ gcc/testsuite/g++.dg/template/cast4.C	(working copy)
@@ -1,4 +1,4 @@
 template <class T> void f()
 {
-  static_cast<int&>(42);	// { dg-error "static_cast" }
+  static_cast<int&>(42);	// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(working copy)
@@ -3,5 +3,5 @@
 
 int main(int, char**) {
   const int foo[2] = {1,1};
-  ((int*)foo)[0] = 0; // { dg-warning "cast" }
+  ((int*)foo)[0] = 0; // { dg-warning "4:cast" }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual2.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(working copy)
@@ -1,4 +1,4 @@
 // PR c++/50956
 // { dg-options "-Wcast-qual" }
 
-void* p = (void*)"txt"; // { dg-warning "cast" }
+void* p = (void*)"txt"; // { dg-warning "11:cast" }
Index: gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(working copy)
@@ -17,9 +17,9 @@ void foo ()
   PV pv;
   PO po;
 
-  pf = reinterpret_cast <PF>(pv); // { dg-warning "conditionally-supported" }
-  pv = reinterpret_cast <PV>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(pv); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  pv = reinterpret_cast <PV>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 
-  pf = reinterpret_cast <PF>(po); // { dg-warning "conditionally-supported" }
-  po = reinterpret_cast <PO>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(po); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  po = reinterpret_cast <PO>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 }
Index: gcc/testsuite/g++.dg/warn/Wuseless-cast.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(working copy)
@@ -64,28 +64,28 @@ void f()
 {
   int n; 
 
-  (int)(n);                    // { dg-warning "useless cast" }
-  static_cast<int>(n);         // { dg-warning "useless cast" }
-  reinterpret_cast<int>(n);    // { dg-warning "useless cast" }
+  (int)(n);                    // { dg-warning "3:useless cast" }
+  static_cast<int>(n);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<int>(n);    // { dg-warning "3:useless cast" }
 
-  (int*)(&n);                  // { dg-warning "useless cast" }
-  const_cast<int*>(&n);        // { dg-warning "useless cast" }
-  static_cast<int*>(&n);       // { dg-warning "useless cast" }
-  reinterpret_cast<int*>(&n);  // { dg-warning "useless cast" }
+  (int*)(&n);                  // { dg-warning "3:useless cast" }
+  const_cast<int*>(&n);        // { dg-warning "3:useless cast" }
+  static_cast<int*>(&n);       // { dg-warning "3:useless cast" }
+  reinterpret_cast<int*>(&n);  // { dg-warning "3:useless cast" }
 
   int& m = n;
 
-  (int&)(m);                   // { dg-warning "useless cast" }
-  const_cast<int&>(m);         // { dg-warning "useless cast" }
-  static_cast<int&>(m);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(m);   // { dg-warning "useless cast" }
+  (int&)(m);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(m);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(m);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(m);   // { dg-warning "3:useless cast" }
 
   tmpl_f1(m);
 
-  (int&)(n);                   // { dg-warning "useless cast" }
-  const_cast<int&>(n);         // { dg-warning "useless cast" }
-  static_cast<int&>(n);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(n);   // { dg-warning "useless cast" }
+  (int&)(n);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(n);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(n);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(n);   // { dg-warning "3:useless cast" }
 
   tmpl_f2(n);
 
@@ -100,30 +100,30 @@ void f()
 
   A a;
 
-  (A)(a);                     // { dg-warning "useless cast" }
-  static_cast<A>(a);          // { dg-warning "useless cast" }
+  (A)(a);                     // { dg-warning "3:useless cast" }
+  static_cast<A>(a);          // { dg-warning "3:useless cast" }
 
-  (A*)(&a);                   // { dg-warning "useless cast" }
-  const_cast<A*>(&a);         // { dg-warning "useless cast" }
-  static_cast<A*>(&a);        // { dg-warning "useless cast" }
-  reinterpret_cast<A*>(&a);   // { dg-warning "useless cast" }
-  dynamic_cast<A*>(&a);       // { dg-warning "useless cast" }
+  (A*)(&a);                   // { dg-warning "3:useless cast" }
+  const_cast<A*>(&a);         // { dg-warning "3:useless cast" }
+  static_cast<A*>(&a);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<A*>(&a);   // { dg-warning "3:useless cast" }
+  dynamic_cast<A*>(&a);       // { dg-warning "3:useless cast" }
 
   A& b = a;
 
-  (A&)(b);                    // { dg-warning "useless cast" }
-  const_cast<A&>(b);          // { dg-warning "useless cast" }
-  static_cast<A&>(b);         // { dg-warning "useless cast" }     
-  static_cast<A&>(b);         // { dg-warning "useless cast" }
-  dynamic_cast<A&>(b);        // { dg-warning "useless cast" }
+  (A&)(b);                    // { dg-warning "3:useless cast" }
+  const_cast<A&>(b);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }     
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(b);        // { dg-warning "3:useless cast" }
 
   tmpl_f3(b);
 
-  (A&)(a);                    // { dg-warning "useless cast" } 
-  const_cast<A&>(a);          // { dg-warning "useless cast" }
-  static_cast<A&>(a);         // { dg-warning "useless cast" }
-  reinterpret_cast<A&>(a);    // { dg-warning "useless cast" }
-  dynamic_cast<A&>(a);        // { dg-warning "useless cast" }
+  (A&)(a);                    // { dg-warning "3:useless cast" } 
+  const_cast<A&>(a);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(a);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<A&>(a);    // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(a);        // { dg-warning "3:useless cast" }
 
   tmpl_f4(a);
 }
Index: gcc/testsuite/g++.dg/warn/pr35711.C
===================================================================
--- gcc/testsuite/g++.dg/warn/pr35711.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/pr35711.C	(working copy)
@@ -4,5 +4,5 @@
 
 int* foo (volatile int *p)
 {
-  return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
+  return (int*)p; // { dg-warning "10:cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
 }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(working copy)
@@ -33,7 +33,7 @@
 
 int main ();
 
-short s = (short) &main;	// { dg-error "loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
-char c = (char) &main;		// { dg-error "loses precision" "lose" }
+short s = (short) &main;	// { dg-error "11:cast \[^\n\r]* loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
+char c = (char) &main;		// { dg-error "10:cast \[^\n\r]* loses precision" "lose" }
 
 int main () { return 0; }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(working copy)
@@ -14,5 +14,5 @@ array_type *ap;
 
 void foo ()
 {
-  int i = *((array_type) *ap);	/* { dg-error "" } missed */
+  int i = *((array_type) *ap);	/* { dg-error "13:ISO C\\+\\+ forbids casting to an array type" } missed */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/overload1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(working copy)
@@ -8,5 +8,5 @@ struct A {
 struct B: public A { };
 
 void bar (A& a) {
-  B* bp = (B*)a;		// { dg-error "" } 
+  B* bp = (B*)a;		// { dg-error "11:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rfg26.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(working copy)
@@ -6,5 +6,5 @@ FTYPE f;                /* ok */
 void
 test_0 ()
 {
-    (FTYPE) f;          /* { dg-error "" } casting to function type */
+    (FTYPE) f;          /* { dg-error "5:invalid cast to function type" } casting to function type */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(working copy)
@@ -2,5 +2,5 @@
 int main ()
 {
    int i;
-   int &ir = (int&)(int)i;	// { dg-error "" } casting rvalue to reference type
+   int &ir = (int&)(int)i;	// { dg-error "14:invalid cast of an rvalue expression" } casting rvalue to reference type
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/warning2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(working copy)
@@ -10,5 +10,5 @@ struct B: public A { void f () { } };
 int main()
 {
   B* bp;
-  A& ar = (A&)bp;		// { dg-warning "" } 
+  A& ar = (A&)bp;		// { dg-warning "11:casting .B\\*. to .A&. does not dereference pointer" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(working copy)
@@ -1,5 +1,5 @@
 // { dg-do assemble  }
 int main() {
   int* d;
-  dynamic_cast<void*>(d);	// { dg-error "" } 
+  dynamic_cast<void*>(d);	// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(working copy)
@@ -9,5 +9,5 @@ class A {
 class B : public A { };
      
 void x (A& a) {
-  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "" } opps
+  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "17:cannot .dynamic_cast." } opps
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p11482.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(working copy)
@@ -6,5 +6,5 @@ void *vp;
 enum E { bad, ok } e;
 
 void foo() {
-  e = (E)vp;		// { dg-error "" } 
+  e = (E)vp;		// { dg-error "7:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2573.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(working copy)
@@ -9,7 +9,9 @@ class X {
 };
 
 char *X::add() {
-  char *f1 = (char *) &key;	// { dg-error "" } 
-  char *f2 = (char *) &vkey;	// { dg-error "" } 
+  char *f1 = (char *) &key;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
+  char *f2 = (char *) &vkey;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
   return f1;
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2855.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(working copy)
@@ -16,6 +16,6 @@ Ctest::operator const char *() const
 int main()
 {
   Ctest obj;
-  char* temp = (char *)obj;		// { dg-error "invalid cast" } 
+  char* temp = (char *)obj;		// { dg-error "16:invalid cast" } 
   temp[0] = '\0';
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p7476.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(working copy)
@@ -16,5 +16,5 @@ void HeapTracked::isObjectAllocation(HeapTracked *
 void HeapTracked::isObjectAllocation(const HeapTracked *ptr)
 {
   const_cast<void*>(dynamic_cast<const void*>(ptr));
-  dynamic_cast<void*>(ptr);		// { dg-error "" } 
+  dynamic_cast<void*>(ptr);		// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p8039.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(working copy)
@@ -11,5 +11,5 @@ extern void bar(int*);
 int main()
 {
   int (C::*mfp)() = &C::func;
-  bar((int*)mfp);		// { dg-error "" } no clear semantics
+  bar((int*)mfp);		// { dg-error "7:invalid cast" } no clear semantics
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast2.C	(working copy)
@@ -10,8 +10,9 @@ int main()
   typedef void (A::*F)();
   F p;
 
-  const_cast<const A>(a); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<F>(p); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<int (*)()>(&main); // { dg-error "" } function type in const_cast
-  const_cast<int (&)()>(main); // { dg-error "" } function type in const_cast
+  const_cast<const A>(a); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<F>(p); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<int (*)()>(&main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
+  // { dg-error "26:ISO C\\+\\+ forbids taking address" "" { target *-*-* } .-1 }
+  const_cast<int (&)()>(main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast3.C	(working copy)
@@ -21,12 +21,12 @@ void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <int *const *> (p);
   static_cast <int const *const *> (p);
   
-  static_cast <X *> (cp);           // { dg-error "" } lose const
+  static_cast <X *> (cp);           // { dg-error "3:.static_cast. from type .const void\\*. to type .X\\*. casts away qualifiers" } lose const
   static_cast <X const *> (cp);
-  static_cast <int *> (cp);         // { dg-error "" } lose const
+  static_cast <int *> (cp);         // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*. casts away qualifiers" } lose const
   static_cast <int const *> (cp);
-  static_cast <int **> (cp);        // { dg-error "" } lose const
-  static_cast <int const **> (cp);  // { dg-error "" } lose const
+  static_cast <int **> (cp);        // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*\\*. casts away qualifiers" } lose const
+  static_cast <int const **> (cp);  // { dg-error "3:.static_cast. from type .const void\\*. to type .const int\\*\\*. casts away qualifiers" } lose const
   static_cast <int *const *> (cp);
   static_cast <int const *const *> (cp);
   
@@ -33,12 +33,12 @@ void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <Z *> (yp);
   static_cast <Z const *> (yp);
 
-  static_cast <Z *> (ycp);          // { dg-error "" } lose const
+  static_cast <Z *> (ycp);          // { dg-error "3:.static_cast. from type .const Y\\*. to type .Z\\*. casts away qualifiers" } lose const
   static_cast <Z const *> (ycp);
 
   static_cast <Y *> (zp);
   static_cast <Y const *> (zp);
 
-  static_cast <Y *> (zcp);          // { dg-error "" } lose const
+  static_cast <Y *> (zcp);          // { dg-error "3:invalid .static_cast. from type .const Z\\*. to type .Y\\*." } lose const
   static_cast <Y const *> (zcp);
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(working copy)
@@ -10,6 +10,6 @@ extern volatile C& cr;
 
 void f ()
 {
-  dynamic_cast<void*>(cp); // { dg-error "" } cannot dynamic_cast
-  dynamic_cast<C&>(cr); // { dg-error "" } cannot dynamic_cast
+  dynamic_cast<void*>(cp); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
+  dynamic_cast<C&>(cr); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(working copy)
@@ -11,7 +11,7 @@ struct D : public B {
 
 void foo() {
   B x;
-  dynamic_cast<D*>(&x); // { dg-warning "" } will never succeed
+  dynamic_cast<D*>(&x); // { dg-warning "3:.dynamic_cast" } will never succeed
   B* p = &x;
   dynamic_cast<D*>(p);
 }
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 279041)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -3064,7 +3064,8 @@ plugin_build_cast_expr (cc1_plugin::connection *se
 			gcc_expr operand2)
 {
   plugin_context *ctx = static_cast<plugin_context *> (self);
-  tree (*build_cast)(tree type, tree expr, tsubst_flags_t complain) = NULL;
+  cp_expr (*build_cast)(location_t loc, tree type, tree expr,
+			tsubst_flags_t complain) = NULL;
   tree type = convert_in (operand1);
   tree expr = convert_in (operand2);
 
@@ -3101,7 +3102,7 @@ plugin_build_cast_expr (cc1_plugin::connection *se
   if (!template_dependent_p)
     processing_template_decl--;
 
-  tree val = build_cast (type, expr, tf_error);
+  tree val = build_cast (input_location, type, expr, tf_error);
 
   if (template_dependent_p)
     processing_template_decl--;
Jason Merrill Dec. 8, 2019, 5:51 p.m. UTC | #3
On 12/6/19 4:36 PM, Paolo Carlini wrote:
> Hi,
> 
> On 06/12/19 18:53, Jason Merrill wrote:
>> On 12/6/19 11:14 AM, Paolo Carlini wrote:
>>> Hi,
>>>
>>> as promised, the below takes care of the various remaining casts. 
>>> It's mostly mechanical, follows the same approach used for 
>>> build_functional_cast. Tested x86_64-linux.
>>
>> It occurs to me that once we're passing the location into the build_* 
>> functions, we can apply it to the expression there rather than in the 
>> parser.
> 
> In fact that occurred to me too ;) but at first I didn't like the idea 
> of multiplying the set_location calls... Anyway, in practice for the 
> casts of this last patch the idea works reasonably well, because most of 
> the complexity is encapsulated in the *_1 versions of the functions and 
> the build_* functions proper have only a couple of returns. I wanted to 
> send those changes... But then my build failed in the libcp1plugin.cc 
> bits because the switch also includes c_cast and all the functions must 
> return the same type. And then for consistency we want also to adjust 
> functional_cast (which allows to remove the set_location in the parser 
> which also remained after my previous patch). Those two cast however are 
> more annoying, because there aren't *_1 counterparts and the functions 
> have *lots* of returns, are complicated. Thus for those I'm proposing to 
> create ad hoc *_1 identical to the current functions in order to have 
> single set_location in cp_build_c_cast and build_functional_cast. All in 
> all, I don't have better ideas... I'm finishing testing the below.

Hmm, is the change to cp_expr really necessary vs. using 
protected_set_expr_location?

Jason
Paolo Carlini Dec. 9, 2019, 12:06 p.m. UTC | #4
Hi,

On 08/12/19 18:51, Jason Merrill wrote:
> Hmm, is the change to cp_expr really necessary vs. using 
> protected_set_expr_location?

Yes, using protected_set_expr_location works fine in this case, I 
suppose because we are dealing with expressions anyway plus the cp_expr 
constructor from a tree copies the location too. In the below I also 
added the thin build_functional_case wrapper, this way consistently all 
the build_*_cast functions called by the parser do not use set_location 
afterwards. Note, at some point we should also do something about the 
build_x_* functions which have been doing that for a while...

Anyway, the below passed testing.

Thanks, Paolo.

////////////////////////////////
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 279041)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -6998,7 +6998,8 @@ extern tree build_typeid			(tree, tsubst_flags_t);
 extern tree get_tinfo_decl			(tree);
 extern tree get_typeid				(tree, tsubst_flags_t);
 extern tree build_headof			(tree);
-extern tree build_dynamic_cast			(tree, tree, tsubst_flags_t);
+extern tree build_dynamic_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern void emit_support_tinfos			(void);
 extern bool emit_tinfo_decl			(tree);
 
@@ -7547,13 +7548,17 @@ extern tree build_x_compound_expr		(location_t, tr
 						 tsubst_flags_t);
 extern tree build_compound_expr                 (location_t, tree, tree);
 extern tree cp_build_compound_expr		(tree, tree, tsubst_flags_t);
-extern tree build_static_cast			(tree, tree, tsubst_flags_t);
-extern tree build_reinterpret_cast		(tree, tree, tsubst_flags_t);
-extern tree build_const_cast			(tree, tree, tsubst_flags_t);
+extern tree build_static_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
+extern tree build_reinterpret_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
+extern tree build_const_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree build_c_cast			(location_t, tree, tree);
 extern cp_expr build_c_cast			(location_t loc, tree type,
 						 cp_expr expr);
-extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
+extern tree cp_build_c_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern cp_expr build_x_modify_expr		(location_t, tree,
 						 enum tree_code, tree,
 						 tsubst_flags_t);
@@ -7613,7 +7618,8 @@ extern int lvalue_or_else			(tree, enum lvalue_use
 extern void check_template_keyword		(tree);
 extern bool check_raw_literal_operator		(const_tree decl);
 extern bool check_literal_operator_args		(const_tree, bool *, bool *);
-extern void maybe_warn_about_useless_cast       (tree, tree, tsubst_flags_t);
+extern void maybe_warn_about_useless_cast       (location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
 extern tree finish_left_unary_fold_expr      (tree, int);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 279041)
+++ gcc/cp/decl.c	(working copy)
@@ -6483,7 +6483,8 @@ reshape_init (tree type, tree init, tsubst_flags_t
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  return cp_build_c_cast (type, elt, tf_warning_or_error);
+	  return cp_build_c_cast (input_location, type, elt,
+				  tf_warning_or_error);
 	}
       else
 	return error_mark_node;
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 279041)
+++ gcc/cp/method.c	(working copy)
@@ -474,7 +474,8 @@ forward_parm (tree parm)
   if (!TYPE_REF_P (type))
     type = cp_build_reference_type (type, /*rval=*/true);
   warning_sentinel w (warn_useless_cast);
-  exp = build_static_cast (type, exp, tf_warning_or_error);
+  exp = build_static_cast (input_location, type, exp,
+			   tf_warning_or_error);
   if (DECL_PACK_P (parm))
     exp = make_pack_expansion (exp);
   return exp;
@@ -1361,7 +1362,8 @@ build_comparison_op (tree fndecl, tsubst_flags_t c
 	      if (TREE_CODE (comp) == SPACESHIP_EXPR)
 		TREE_TYPE (comp) = rettype;
 	      else
-		comp = build_static_cast (rettype, comp, complain);
+		comp = build_static_cast (input_location, rettype, comp,
+					  complain);
 	      info.check (comp);
 	      if (info.defining)
 		{
@@ -1395,7 +1397,8 @@ build_comparison_op (tree fndecl, tsubst_flags_t c
 	    {
 	      tree seql = lookup_comparison_result (cc_strong_ordering,
 						    "equal", complain);
-	      val = build_static_cast (rettype, seql, complain);
+	      val = build_static_cast (input_location, rettype, seql,
+				       complain);
 	    }
 	  finish_return_stmt (val);
 	}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 279041)
+++ gcc/cp/parser.c	(working copy)
@@ -6895,36 +6895,38 @@ cp_parser_postfix_expression (cp_parser *parser, b
 	    break;
 	  }
 
+	/* Construct a location e.g. :
+	     reinterpret_cast <int *> (expr)
+	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	   ranging from the start of the "*_cast" token to the final closing
+	   paren, with the caret at the start.  */
+	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
+
 	switch (keyword)
 	  {
 	  case RID_DYNCAST:
 	    postfix_expression
-	      = build_dynamic_cast (type, expression, tf_warning_or_error);
+	      = build_dynamic_cast (cp_cast_loc, type, expression,
+				    tf_warning_or_error);
 	    break;
 	  case RID_STATCAST:
 	    postfix_expression
-	      = build_static_cast (type, expression, tf_warning_or_error);
+	      = build_static_cast (cp_cast_loc, type, expression,
+				   tf_warning_or_error);
 	    break;
 	  case RID_REINTCAST:
 	    postfix_expression
-	      = build_reinterpret_cast (type, expression,
+	      = build_reinterpret_cast (cp_cast_loc, type, expression,
                                         tf_warning_or_error);
 	    break;
 	  case RID_CONSTCAST:
 	    postfix_expression
-	      = build_const_cast (type, expression, tf_warning_or_error);
+	      = build_const_cast (cp_cast_loc, type, expression,
+				  tf_warning_or_error);
 	    break;
 	  default:
 	    gcc_unreachable ();
 	  }
-
-	/* Construct a location e.g. :
-	     reinterpret_cast <int *> (expr)
-	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	   ranging from the start of the "*_cast" token to the final closing
-	   paren, with the caret at the start.  */
-	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
-	postfix_expression.set_location (cp_cast_loc);
       }
       break;
 
@@ -9150,17 +9152,18 @@ get_cast_suggestion (tree dst_type, tree orig_expr
     return NULL;
 
   /* First try const_cast.  */
-  trial = build_const_cast (dst_type, orig_expr, tf_none);
+  trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "const_cast";
 
   /* If that fails, try static_cast.  */
-  trial = build_static_cast (dst_type, orig_expr, tf_none);
+  trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "static_cast";
 
   /* Finally, try reinterpret_cast.  */
-  trial = build_reinterpret_cast (dst_type, orig_expr, tf_none);
+  trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
+				  tf_none);
   if (trial != error_mark_node)
     return "reinterpret_cast";
 
@@ -10148,8 +10151,8 @@ cp_parser_builtin_offsetof (cp_parser *parser)
 
   /* Build the (type *)null that begins the traditional offsetof macro.  */
   tree object_ptr
-    = build_static_cast (build_pointer_type (type), null_pointer_node,
-			 tf_warning_or_error);
+    = build_static_cast (input_location, build_pointer_type (type),
+			 null_pointer_node, tf_warning_or_error);
 
   /* Parse the offsetof-member-designator.  We begin as if we saw "expr->".  */
   expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, object_ptr,
@@ -29277,7 +29280,6 @@ cp_parser_functional_cast (cp_parser* parser, tree
 					   parser->lexer);
   cast = build_functional_cast (combined_loc, type, expression_list,
                                 tf_warning_or_error);
-  cast.set_location (combined_loc);
   
   /* [expr.const]/1: In an integral constant expression "only type
      conversions to integral or enumeration type can be used".  */
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 279041)
+++ gcc/cp/pt.c	(working copy)
@@ -19020,16 +19020,16 @@ tsubst_copy_and_build (tree t,
 	    r = build_functional_cast (input_location, type, op, complain);
 	    break;
 	  case REINTERPRET_CAST_EXPR:
-	    r = build_reinterpret_cast (type, op, complain);
+	    r = build_reinterpret_cast (input_location, type, op, complain);
 	    break;
 	  case CONST_CAST_EXPR:
-	    r = build_const_cast (type, op, complain);
+	    r = build_const_cast (input_location, type, op, complain);
 	    break;
 	  case DYNAMIC_CAST_EXPR:
-	    r = build_dynamic_cast (type, op, complain);
+	    r = build_dynamic_cast (input_location, type, op, complain);
 	    break;
 	  case STATIC_CAST_EXPR:
-	    r = build_static_cast (type, op, complain);
+	    r = build_static_cast (input_location, type, op, complain);
 	    break;
 	  default:
 	    gcc_unreachable ();
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c	(revision 279041)
+++ gcc/cp/rtti.c	(working copy)
@@ -123,7 +123,7 @@ static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
 
 static tree ifnonnull (tree, tree, tsubst_flags_t);
 static tree tinfo_name (tree, bool);
-static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
+static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
 static tree throw_bad_typeid (void);
 static tree get_tinfo_ptr (tree);
@@ -548,7 +548,8 @@ ifnonnull (tree test, tree result, tsubst_flags_t
    paper.  */
 
 static tree
-build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
+build_dynamic_cast_1 (location_t loc, tree type, tree expr,
+		      tsubst_flags_t complain)
 {
   enum tree_code tc = TREE_CODE (type);
   tree exprtype;
@@ -646,7 +647,7 @@ static tree
     tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
 			      ba_check, NULL, complain);
     if (binfo)
-      return build_static_cast (type, expr, complain);
+      return build_static_cast (loc, type, expr, complain);
   }
 
   /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
@@ -691,8 +692,9 @@ static tree
 		{
 		  tree expr = throw_bad_cast ();
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, old_expr);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, old_expr);
 		  /* Bash it to the expected type.  */
 		  TREE_TYPE (expr) = type;
 		  return expr;
@@ -706,8 +708,9 @@ static tree
 		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
 		{
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, op);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, op);
 		  retval = build_int_cst (type, 0);
 		  return retval;
 		}
@@ -717,7 +720,8 @@ static tree
 	  if (!flag_rtti)
 	    {
               if (complain & tf_error)
-		error ("%<dynamic_cast%> not permitted with %<-fno-rtti%>");
+		error_at (loc,
+			  "%<dynamic_cast%> not permitted with %<-fno-rtti%>");
 	      return error_mark_node;
 	    }
 
@@ -796,13 +800,15 @@ static tree
 
  fail:
   if (complain & tf_error)
-    error ("cannot %<dynamic_cast%> %qE (of type %q#T) to type %q#T (%s)",
-           old_expr, TREE_TYPE (old_expr), type, errstr);
+    error_at (loc, "cannot %<dynamic_cast%> %qE (of type %q#T) "
+	      "to type %q#T (%s)",
+	      old_expr, TREE_TYPE (old_expr), type, errstr);
   return error_mark_node;
 }
 
 tree
-build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
+build_dynamic_cast (location_t loc, tree type, tree expr,
+		    tsubst_flags_t complain)
 {
   tree r;
 
@@ -813,12 +819,16 @@ tree
     {
       expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
       TREE_SIDE_EFFECTS (expr) = 1;
-      return convert_from_reference (expr);
+      r = convert_from_reference (expr);
+      protected_set_expr_location (r, loc);
+      return r;
     }
 
-  r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
+  r = convert_from_reference (build_dynamic_cast_1 (loc, type, expr,
+						    complain));
   if (r != error_mark_node)
-    maybe_warn_about_useless_cast (type, expr, complain);
+    maybe_warn_about_useless_cast (loc, type, expr, complain);
+  protected_set_expr_location (r, loc);
   return r;
 }
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 279041)
+++ gcc/cp/semantics.c	(working copy)
@@ -5918,9 +5918,11 @@ finish_omp_reduction_clause (tree c, bool *need_de
 	      if (need_static_cast)
 		{
 		  tree rtype = build_reference_type (atype);
-		  omp_out = build_static_cast (rtype, omp_out,
+		  omp_out = build_static_cast (input_location,
+					       rtype, omp_out,
 					       tf_warning_or_error);
-		  omp_in = build_static_cast (rtype, omp_in,
+		  omp_in = build_static_cast (input_location,
+					      rtype, omp_in,
 					      tf_warning_or_error);
 		  if (omp_out == error_mark_node || omp_in == error_mark_node)
 		    return true;
@@ -5955,9 +5957,11 @@ finish_omp_reduction_clause (tree c, bool *need_de
 		      return true;
 		    }
 		  tree rtype = build_reference_type (atype);
-		  omp_priv = build_static_cast (rtype, omp_priv,
+		  omp_priv = build_static_cast (input_location,
+						rtype, omp_priv,
 						tf_warning_or_error);
-		  omp_orig = build_static_cast (rtype, omp_orig,
+		  omp_orig = build_static_cast (input_location,
+						rtype, omp_orig,
 						tf_warning_or_error);
 		  if (omp_priv == error_mark_node
 		      || omp_orig == error_mark_node)
@@ -6138,13 +6142,16 @@ cp_omp_finish_iterators (tree iter)
       begin = mark_rvalue_use (begin);
       end = mark_rvalue_use (end);
       step = mark_rvalue_use (step);
-      begin = cp_build_c_cast (type, begin, tf_warning_or_error);
-      end = cp_build_c_cast (type, end, tf_warning_or_error);
+      begin = cp_build_c_cast (input_location, type, begin,
+			       tf_warning_or_error);
+      end = cp_build_c_cast (input_location, type, end,
+			     tf_warning_or_error);
       orig_step = step;
       if (!processing_template_decl)
 	step = orig_step = save_expr (step);
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
-      step = cp_build_c_cast (stype, step, tf_warning_or_error);
+      step = cp_build_c_cast (input_location, stype, step,
+			      tf_warning_or_error);
       if (POINTER_TYPE_P (type) && !processing_template_decl)
 	{
 	  begin = save_expr (begin);
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 279041)
+++ gcc/cp/tree.c	(working copy)
@@ -425,7 +425,8 @@ cp_stabilize_reference (tree ref)
 	  /* This inhibits warnings in, eg, cxx_mark_addressable
 	     (c++/60955).  */
 	  warning_sentinel s (extra_warnings);
-	  ref = build_static_cast (type, ref, tf_error);
+	  ref = build_static_cast (input_location, type, ref,
+				   tf_error);
 	}
     }
 
@@ -1222,7 +1223,8 @@ move (tree expr)
   tree type = TREE_TYPE (expr);
   gcc_assert (!TYPE_REF_P (type));
   type = cp_build_reference_type (type, /*rval*/true);
-  return build_static_cast (type, expr, tf_warning_or_error);
+  return build_static_cast (input_location, type, expr,
+			    tf_warning_or_error);
 }
 
 /* Used by the C++ front end to build qualified array types.  However,
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 279041)
+++ gcc/cp/typeck.c	(working copy)
@@ -6446,7 +6446,7 @@ cp_build_unary_op (enum tree_code code, tree xarg,
 				   build_zero_cst (TREE_TYPE (arg)), complain);
       arg = perform_implicit_conversion (boolean_type_node, arg,
 					 complain);
-      val = invert_truthvalue_loc (input_location, arg);
+      val = invert_truthvalue_loc (location, arg);
       if (arg != error_mark_node)
 	return val;
       errstring = _("in argument to unary !");
@@ -7075,8 +7075,9 @@ cp_build_compound_expr (tree lhs, tree rhs, tsubst
 */
 
 static bool
-check_for_casting_away_constness (tree src_type, tree dest_type,
-				  enum tree_code cast, tsubst_flags_t complain)
+check_for_casting_away_constness (location_t loc, tree src_type,
+				  tree dest_type, enum tree_code cast,
+				  tsubst_flags_t complain)
 {
   /* C-style casts are allowed to cast away constness.  With
      WARN_CAST_QUAL, we still want to issue a warning.  */
@@ -7090,23 +7091,23 @@ static bool
     {
     case CAST_EXPR:
       if (complain & tf_warning)
-	warning (OPT_Wcast_qual,
-		 "cast from type %qT to type %qT casts away qualifiers",
-		 src_type, dest_type);
+	warning_at (loc, OPT_Wcast_qual,
+		    "cast from type %qT to type %qT casts away qualifiers",
+		    src_type, dest_type);
       return false;
-      
+
     case STATIC_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<static_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
+		  "away qualifiers",
+		  src_type, dest_type);
       return true;
-      
+
     case REINTERPRET_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<reinterpret_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
+		  "casts away qualifiers",
+		  src_type, dest_type);
       return true;
 
     default:
@@ -7116,7 +7117,8 @@ static bool
 
 /* Warns if the cast from expression EXPR to type TYPE is useless.  */
 void
-maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
+maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
+			       tsubst_flags_t complain)
 {
   if (warn_useless_cast
       && complain & tf_warning)
@@ -7126,22 +7128,22 @@ void
 	       ? xvalue_p (expr) : lvalue_p (expr))
 	   && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
 	  || same_type_p (TREE_TYPE (expr), type))
-	warning (OPT_Wuseless_cast, "useless cast to type %q#T", type);
+	warning_at (loc, OPT_Wuseless_cast,
+		    "useless cast to type %q#T", type);
     }
 }
 
 /* Warns if the cast ignores cv-qualifiers on TYPE.  */
-void
-maybe_warn_about_cast_ignoring_quals (tree type, tsubst_flags_t complain)
+static void
+maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
+				      tsubst_flags_t complain)
 {
   if (warn_ignored_qualifiers
       && complain & tf_warning
       && !CLASS_TYPE_P (type)
       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
-    {
-      warning (OPT_Wignored_qualifiers, "type qualifiers ignored on cast "
-	       "result type");
-    }
+    warning_at (loc, OPT_Wignored_qualifiers,
+		"type qualifiers ignored on cast result type");
 }
 
 /* Convert EXPR (an expression with pointer-to-member type) to TYPE
@@ -7200,7 +7202,7 @@ convert_ptrmem (tree type, tree expr, bool allow_i
    indicate whether or not the cast was valid.  */
 
 static tree
-build_static_cast_1 (tree type, tree expr, bool c_cast_p,
+build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
 		     bool *valid_p, tsubst_flags_t complain)
 {
   tree intype;
@@ -7269,7 +7271,7 @@ static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7427,7 +7429,8 @@ static tree
 	return expr;
 
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
@@ -7439,7 +7442,7 @@ static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7476,7 +7479,7 @@ static tree
       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
 	{
 	  if (!c_cast_p
-	      && check_for_casting_away_constness (intype, type,
+	      && check_for_casting_away_constness (loc, intype, type,
 						   STATIC_CAST_EXPR,
 						   complain))
 	    return error_mark_node;
@@ -7498,7 +7501,8 @@ static tree
       && TYPE_PTROB_P (type))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       if (processing_template_decl)
@@ -7513,7 +7517,8 @@ static tree
 /* Return an expression representing static_cast<TYPE>(EXPR).  */
 
 tree
-build_static_cast (tree type, tree oexpr, tsubst_flags_t complain)
+build_static_cast (location_t loc, tree type, tree oexpr,
+		   tsubst_flags_t complain)
 {
   tree expr = oexpr;
   tree result;
@@ -7530,7 +7535,9 @@ tree
       expr = build_min (STATIC_CAST_EXPR, type, oexpr);
       /* We don't know if it will or will not have side effects.  */
       TREE_SIDE_EFFECTS (expr) = 1;
-      return convert_from_reference (expr);
+      result = convert_from_reference (expr);
+      protected_set_expr_location (result, loc);
+      return result;
     }
   else if (processing_template_decl)
     expr = build_non_dependent_expr (expr);
@@ -7542,24 +7549,25 @@ tree
       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
     expr = TREE_OPERAND (expr, 0);
 
-  result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
-                                complain);
+  result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
+				&valid_p, complain);
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, expr, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, expr, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       if (processing_template_decl)
 	goto tmpl;
+      protected_set_expr_location (result, loc);
       return result;
     }
 
   if (complain & tf_error)
     {
-      error ("invalid %<static_cast%> from type %qT to type %qT",
-	     TREE_TYPE (expr), type);
+      error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
+		TREE_TYPE (expr), type);
       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
 	  && CLASS_TYPE_P (TREE_TYPE (type))
 	    && !COMPLETE_TYPE_P (TREE_TYPE (type)))
@@ -7633,8 +7641,9 @@ build_nop_reinterpret (tree type, tree expr)
    indicate whether or not reinterpret_cast was valid.  */
 
 static tree
-build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
-			  bool *valid_p, tsubst_flags_t complain)
+build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
+			  bool c_cast_p, bool *valid_p,
+			  tsubst_flags_t complain)
 {
   tree intype;
 
@@ -7670,9 +7679,9 @@ static tree
       else if (!lvalue_p (expr))
 	{
           if (complain & tf_error)
-            error ("invalid cast of an rvalue expression of type "
-                   "%qT to type %qT",
-                   intype, type);
+            error_at (loc, "invalid cast of an rvalue expression of type "
+		      "%qT to type %qT",
+		      intype, type);
 	  return error_mark_node;
 	}
 
@@ -7683,8 +7692,8 @@ static tree
           && (complain & tf_warning)
 	  && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
 			 COMPARE_BASE | COMPARE_DERIVED)))
-	warning (0, "casting %qT to %qT does not dereference pointer",
-		 intype, type);
+	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
+		    intype, type);
 
       expr = cp_build_addr_expr (expr, complain);
 
@@ -7693,7 +7702,7 @@ static tree
 
       if (expr != error_mark_node)
 	expr = build_reinterpret_cast_1
-	  (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+	  (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
 	   valid_p, complain);
       if (expr != error_mark_node)
 	/* cp_build_indirect_ref isn't right for rvalue refs.  */
@@ -7740,7 +7749,7 @@ static tree
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            permerror (input_location, "cast from %qH to %qI loses precision",
+            permerror (loc, "cast from %qH to %qI loses precision",
                        intype, type);
           else
             return error_mark_node;
@@ -7764,9 +7773,9 @@ static tree
       if ((complain & tf_warning)
 	  && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
 					     TREE_TYPE (intype)))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible function types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible function types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
@@ -7775,9 +7784,9 @@ static tree
 	  && !cxx_safe_function_type_cast_p
 		(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
 		 TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible pointer to member types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible pointer to member types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
@@ -7784,7 +7793,7 @@ static tree
 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type,
+	  && check_for_casting_away_constness (loc, intype, type,
 					       REINTERPRET_CAST_EXPR,
 					       complain))
 	return error_mark_node;
@@ -7797,8 +7806,9 @@ static tree
 	  && COMPLETE_TYPE_P (TREE_TYPE (intype))
 	  && min_align_of_type (TREE_TYPE (type))
 	     > min_align_of_type (TREE_TYPE (intype)))
-	warning (OPT_Wcast_align, "cast from %qH to %qI "
-		 "increases required alignment of target type", intype, type);
+	warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+		    "increases required alignment of target type",
+		    intype, type);
 
       if (warn_strict_aliasing <= 2)
 	/* strict_aliasing_warning STRIP_NOPs its expr.  */
@@ -7812,9 +7822,9 @@ static tree
       if (complain & tf_warning)
 	/* C++11 5.2.10 p8 says that "Converting a function pointer to an
 	   object pointer type or vice versa is conditionally-supported."  */
-	warning (OPT_Wconditionally_supported,
-		 "casting between pointer-to-function and pointer-to-object "
-		 "is conditionally-supported");
+	warning_at (loc, OPT_Wconditionally_supported,
+		    "casting between pointer-to-function and "
+		    "pointer-to-object is conditionally-supported");
       return build_nop_reinterpret (type, expr);
     }
   else if (gnu_vector_type_p (type))
@@ -7827,7 +7837,8 @@ static tree
       if (valid_p)
 	*valid_p = false;
       if (complain & tf_error)
-        error ("invalid cast from type %qT to type %qT", intype, type);
+        error_at (loc, "invalid cast from type %qT to type %qT",
+		  intype, type);
       return error_mark_node;
     }
 
@@ -7839,7 +7850,8 @@ static tree
 }
 
 tree
-build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
+build_reinterpret_cast (location_t loc, tree type, tree expr,
+			tsubst_flags_t complain)
 {
   tree r;
 
@@ -7854,16 +7866,19 @@ tree
 	  && type_dependent_expression_p (expr))
 	/* There might turn out to be side effects inside expr.  */
 	TREE_SIDE_EFFECTS (t) = 1;
-      return convert_from_reference (t);
+      r = convert_from_reference (t);
+      protected_set_expr_location (r, loc);
+      return r;
     }
 
-  r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+  r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
 				/*valid_p=*/NULL, complain);
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
+  protected_set_expr_location (r, loc);
   return r;
 }
 
@@ -7875,8 +7890,8 @@ tree
    whether or not the conversion succeeded.  */
 
 static tree
-build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
-		    bool *valid_p)
+build_const_cast_1 (location_t loc, tree dst_type, tree expr,
+		    tsubst_flags_t complain, bool *valid_p)
 {
   tree src_type;
   tree reference_type;
@@ -7895,9 +7910,9 @@ static tree
   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is not a pointer, "
-	       "reference, nor a pointer-to-data-member type", dst_type);
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is not a pointer, reference, "
+		  "nor a pointer-to-data-member type", dst_type);
       return error_mark_node;
     }
 
@@ -7904,10 +7919,10 @@ static tree
   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is a pointer or reference to a function type",
-	       dst_type);
-      return error_mark_node;
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is a pointer or reference to a function type",
+		  dst_type);
+       return error_mark_node;
     }
 
   /* A prvalue of non-class type is cv-unqualified.  */
@@ -7946,10 +7961,10 @@ static tree
       else
 	{
 	  if (complain & tf_error)
-	    error ("invalid %<const_cast%> of an rvalue of type %qT "
-		   "to type %qT",
-		   src_type, dst_type);
-	  return error_mark_node;
+	    error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
+		      "to type %qT",
+		      src_type, dst_type);
+ 	  return error_mark_node;
 	}
       dst_type = build_pointer_type (TREE_TYPE (dst_type));
       src_type = build_pointer_type (src_type);
@@ -7974,7 +7989,7 @@ static tree
 	      *valid_p = true;
 	      /* This cast is actually a C-style cast.  Issue a warning if
 		 the user is making a potentially unsafe cast.  */
-	      check_for_casting_away_constness (src_type, dst_type,
+	      check_for_casting_away_constness (loc, src_type, dst_type,
 						CAST_EXPR, complain);
 	      /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
 	      if ((STRICT_ALIGNMENT || warn_cast_align == 2)
@@ -7981,9 +7996,9 @@ static tree
 		  && (complain & tf_warning)
 		  && min_align_of_type (TREE_TYPE (dst_type))
 		     > min_align_of_type (TREE_TYPE (src_type)))
-		warning (OPT_Wcast_align, "cast from %qH to %qI "
-			 "increases required alignment of target type",
-			 src_type, dst_type);
+		warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+			    "increases required alignment of target type",
+			    src_type, dst_type);
 	    }
 	  if (reference_type)
 	    {
@@ -8011,18 +8026,19 @@ static tree
       else if (valid_p
 	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
 					    TREE_TYPE (src_type)))
-	check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
-					  complain);
+	check_for_casting_away_constness (loc, src_type, dst_type,
+					  CAST_EXPR, complain);
     }
 
   if (complain & tf_error)
-    error ("invalid %<const_cast%> from type %qT to type %qT",
-	   src_type, dst_type);
+    error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
+	      src_type, dst_type);
   return error_mark_node;
 }
 
 tree
-build_const_cast (tree type, tree expr, tsubst_flags_t complain)
+build_const_cast (location_t loc, tree type, tree expr,
+		  tsubst_flags_t complain)
 {
   tree r;
 
@@ -8037,15 +8053,18 @@ tree
 	  && type_dependent_expression_p (expr))
 	/* There might turn out to be side effects inside expr.  */
 	TREE_SIDE_EFFECTS (t) = 1;
-      return convert_from_reference (t);
+      r = convert_from_reference (t);
+      protected_set_expr_location (r, loc);
+      return r;
     }
 
-  r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL);
+  r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
+  protected_set_expr_location (r, loc);
   return r;
 }
 
@@ -8052,9 +8071,9 @@ tree
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (location_t /*loc*/, tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
 {
-  return cp_build_c_cast (type, expr, tf_warning_or_error);
+  return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
 }
 
 /* Like the "build_c_cast" used for c-common, but using cp_expr to
@@ -8064,7 +8083,7 @@ tree
 cp_expr
 build_c_cast (location_t loc, tree type, cp_expr expr)
 {
-  cp_expr result = cp_build_c_cast (type, expr, tf_warning_or_error);
+  cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
   result.set_location (loc);
   return result;
 }
@@ -8073,7 +8092,8 @@ build_c_cast (location_t loc, tree type, cp_expr e
    TYPE of expression EXPR.  */
 
 tree
-cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_build_c_cast (location_t loc, tree type, tree expr,
+		 tsubst_flags_t complain)
 {
   tree value = expr;
   tree result;
@@ -8112,7 +8132,8 @@ tree
       if (TYPE_PTR_P (TREE_TYPE (expr)))
 	{
           if (complain & tf_error)
-            permerror (input_location, "ISO C++ forbids casting to an array type %qT", type);
+            permerror (loc, "ISO C++ forbids casting to an array type %qT",
+		       type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
@@ -8120,7 +8141,8 @@ tree
       else
 	{
           if (complain & tf_error)
-            error ("ISO C++ forbids casting to an array type %qT", type);
+            error_at (loc, "ISO C++ forbids casting to an array type %qT",
+		      type);
 	  return error_mark_node;
 	}
     }
@@ -8128,7 +8150,7 @@ tree
   if (FUNC_OR_METHOD_TYPE_P (type))
     {
       if (complain & tf_error)
-        error ("invalid cast to function type %qT", type);
+        error_at (loc, "invalid cast to function type %qT", type);
       return error_mark_node;
     }
 
@@ -8138,28 +8160,28 @@ tree
       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
       /* Don't warn about converting any constant.  */
       && !TREE_CONSTANT (value))
-    warning_at (input_location, OPT_Wint_to_pointer_cast, 
+    warning_at (loc, OPT_Wint_to_pointer_cast, 
 		"cast to pointer from integer of different size");
 
   /* A C-style cast can be a const_cast.  */
-  result = build_const_cast_1 (type, value, complain & tf_warning,
+  result = build_const_cast_1 (loc, type, value, complain & tf_warning,
 			       &valid_p);
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, value, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, value, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       return result;
     }
 
   /* Or a static cast.  */
-  result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
+  result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				&valid_p, complain);
   /* Or a reinterpret_cast.  */
   if (!valid_p)
-    result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+    result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				       &valid_p, complain);
   /* The static_cast or reinterpret_cast may be followed by a
      const_cast.  */
@@ -8170,8 +8192,8 @@ tree
     {
       tree result_type;
 
-      maybe_warn_about_useless_cast (type, value, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, value, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 
       /* Non-class rvalues always have cv-unqualified type.  */
       if (!CLASS_TYPE_P (type))
@@ -8186,7 +8208,7 @@ tree
 	 to succeed.  */
       if (!same_type_p (non_reference (type), non_reference (result_type)))
 	{
-	  result = build_const_cast_1 (type, result, false, &valid_p);
+	  result = build_const_cast_1 (loc, type, result, false, &valid_p);
 	  gcc_assert (valid_p);
 	}
       return result;
@@ -8878,7 +8900,7 @@ build_ptrmemfunc (tree type, tree pfn, int force,
 	  if (same_type_p (to_type, pfn_type))
 	    return pfn;
 	  else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
-	    return build_reinterpret_cast (to_type, pfn, 
+	    return build_reinterpret_cast (input_location, to_type, pfn, 
                                            complain);
 	}
 
@@ -8912,7 +8934,7 @@ build_ptrmemfunc (tree type, tree pfn, int force,
   /* Handle null pointer to member function conversions.  */
   if (null_ptr_cst_p (pfn))
     {
-      pfn = cp_build_c_cast (type, pfn, complain);
+      pfn = cp_build_c_cast (input_location, type, pfn, complain);
       return build_ptrmemfunc1 (to_type,
 				integer_zero_node,
 				pfn);
@@ -9067,7 +9089,7 @@ convert_for_assignment (tree type, tree rhs,
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  rhs = cp_build_c_cast (type, elt, complain);
+	  rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
 	}
       else
 	rhs = error_mark_node;
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 279041)
+++ gcc/cp/typeck2.c	(working copy)
@@ -2227,9 +2227,9 @@ build_m_component_ref (tree datum, tree component,
 
 /* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
 
-tree
-build_functional_cast (location_t loc, tree exp, tree parms,
-		       tsubst_flags_t complain)
+static tree
+build_functional_cast_1 (location_t loc, tree exp, tree parms,
+			 tsubst_flags_t complain)
 {
   /* This is either a call to a constructor,
      or a C cast in C++'s `functional' notation.  */
@@ -2318,7 +2318,7 @@ build_m_component_ref (tree datum, tree component,
 
       /* This must build a C cast.  */
       parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
-      return cp_build_c_cast (type, parms, complain);
+      return cp_build_c_cast (loc, type, parms, complain);
     }
 
   /* Prepare to evaluate as a call to a constructor.  If this expression
@@ -2339,7 +2339,7 @@ build_m_component_ref (tree datum, tree component,
      conversion is equivalent (in definedness, and if defined in
      meaning) to the corresponding cast expression.  */
   if (parms && TREE_CHAIN (parms) == NULL_TREE)
-    return cp_build_c_cast (type, TREE_VALUE (parms), complain);
+    return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);
 
   /* [expr.type.conv]
 
@@ -2367,6 +2367,15 @@ build_m_component_ref (tree datum, tree component,
 
   return build_cplus_new (type, exp, complain);
 }
+
+tree
+build_functional_cast (location_t loc, tree exp, tree parms,
+		       tsubst_flags_t complain)
+{
+  tree result = build_functional_cast_1 (loc, exp, parms, complain);
+  protected_set_expr_location (result, loc);
+  return result;  
+}
 
 
 /* Add new exception specifier SPEC, to the LIST we currently have.
Index: gcc/testsuite/c-c++-common/Wcast-align.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-align.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-align.c	(working copy)
@@ -16,8 +16,8 @@ struct t { double x; } *q;
 void
 foo (void)
 {
-  y = (c *) x;  /* { dg-warning "alignment" } */
-  z = (d *) x;  /* { dg-warning "alignment" } */
+  y = (c *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
+  z = (d *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
   (long long *) p;  /* { dg-bogus "alignment" } */
   (double *) q;     /* { dg-bogus "alignment" } */
 }
Index: gcc/testsuite/c-c++-common/Wcast-function-type.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-function-type.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-function-type.c	(working copy)
@@ -24,8 +24,8 @@ void
 foo (void)
 {
   a = (f1 *) f; /* { dg-bogus   "incompatible function types" } */
-  b = (f2 *) f; /* { dg-warning "incompatible function types" } */
+  b = (f2 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   c = (f3 *) f; /* { dg-bogus   "incompatible function types" } */
-  d = (f4 *) f; /* { dg-warning "incompatible function types" } */
+  d = (f4 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   e = (f5 *) f; /* { dg-bogus   "incompatible function types" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(working copy)
@@ -8,5 +8,5 @@ char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(working copy)
@@ -8,5 +8,5 @@ char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(working copy)
@@ -17,6 +17,6 @@ char
 g (void)
 {
   return (char) p;
-/* { dg-warning "cast from pointer to integer of different size" "" { target c } .-1 } */
-/* { dg-error "cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
+/* { dg-warning "10:cast from pointer to integer of different size" "" { target c } .-1 } */
+/* { dg-error "10:cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
 }
Index: gcc/testsuite/g++.dg/Wcast-function-type.C
===================================================================
--- gcc/testsuite/g++.dg/Wcast-function-type.C	(revision 279041)
+++ gcc/testsuite/g++.dg/Wcast-function-type.C	(working copy)
@@ -12,6 +12,6 @@ typedef void (S::*MF)(int);
 void
 foo (void)
 {
-  MF p1 = (MF)&S::foo; /* { dg-warning "pointer to member" } */
+  MF p1 = (MF)&S::foo; /* { dg-warning "11:cast between incompatible pointer to member" } */
   MF p2 = (MF)&S::bar; /* { dg-bogus   "pointer to member" } */
 }
Index: gcc/testsuite/g++.dg/addr_builtin-1.C
===================================================================
--- gcc/testsuite/g++.dg/addr_builtin-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/addr_builtin-1.C	(working copy)
@@ -93,8 +93,8 @@ static F* test_taking_address_of_gcc_builtin ()
   // Expect a diagnostic for an invalid static_cast of a function to
   // either uintptr_t or enum, rather than one for the argument being
   // a built-in function, since the former is more relevant than the latter.
-  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "invalid" }
-  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "invalid" }
+  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
+  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
 
   // Reinterpret cast can cast a function to uintptr_t or enum,
   // so verify that a diagnostic is issued for the use of a builtin.
Index: gcc/testsuite/g++.dg/conversion/const2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/const2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/const2.C	(working copy)
@@ -7,5 +7,5 @@ typedef int D::*dm;
 bm bp;
 
 void f() {
-  const_cast<dm>(bp); // { dg-error "" }
+  const_cast<dm>(bp); // { dg-error "3:invalid .const_cast." }
 }
Index: gcc/testsuite/g++.dg/conversion/dynamic1.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/dynamic1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/dynamic1.C	(working copy)
@@ -11,5 +11,5 @@ A& bar();
 
 void baz()
 {
-  dynamic_cast<A&>( bar().foo );  // { dg-error "cannot 'dynamic_cast'" }
+  dynamic_cast<A&>( bar().foo );  // { dg-error "3:cannot 'dynamic_cast'" }
 }
Index: gcc/testsuite/g++.dg/conversion/ptrmem2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem2.C	(working copy)
@@ -35,9 +35,9 @@ const int B::*p9 = static_cast<const int B::*>(&D:
 const int D::*p10 = static_cast<const int D::*>(&B::x);
 
 // Invalid conversions which decrease cv-qualification.
-int B::*p11 = static_cast<int B::*>(p10); // { dg-error "casts away qualifiers" }
-int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "casts away qualifiers" }
+int B::*p11 = static_cast<int B::*>(p10); // { dg-error "15:.static_cast. from type .const int D::\\*. to type .int B::\\*. casts away qualifiers" }
+int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "15:.static_cast. from type .const int B::\\*. to type .int D::\\*. casts away qualifiers" }
 
 // Attempts to change member type.
-float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "invalid .static_cast." }
-float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "invalid .static_cast." }
+float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "17:invalid .static_cast." }
+float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "17:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/ptrmem3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem3.C	(working copy)
@@ -27,5 +27,5 @@ int (A::*p7)() = static_cast<int (A::*)()>(&D::f);
 int (D::*p8)() = static_cast<int (D::*)()>(&A::f);  // { dg-error "" }
 
 // Attempts to change member type.
-float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "" }
-float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "" }
+float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "21:invalid .static_cast." }
+float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "21:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/qual3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/qual3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/qual3.C	(working copy)
@@ -24,30 +24,30 @@ f (P p, Q q, Q2 q2, R r, S s, T t)
   const_cast<P>(q2);
   const_cast<Q>(p);
   const_cast<Q2>(p);
-  const_cast<S>(p); // { dg-error "invalid .const_cast." }
-  const_cast<P>(s); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q2); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(s); // { dg-error "invalid .const_cast." }
-  const_cast<Q2>(s); // { dg-error "invalid .const_cast." }
+  const_cast<S>(p); // { dg-error "3:invalid .const_cast." }
+  const_cast<P>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q2); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q2>(s); // { dg-error "3:invalid .const_cast." }
   const_cast<T>(s);
   const_cast<S>(t);
-  const_cast<T>(q); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(t); // { dg-error "invalid .const_cast." }
+  const_cast<T>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(t); // { dg-error "3:invalid .const_cast." }
 
   // Test reinterpret_cast.
-  reinterpret_cast<P>(q); // { dg-error "casts away qualifiers" }
-  reinterpret_cast<P>(q2); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
+  reinterpret_cast<P>(q2); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(p);
   reinterpret_cast<Q2>(p);
   reinterpret_cast<S>(p);
-  reinterpret_cast<P>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(q);
   reinterpret_cast<S>(q2);
   reinterpret_cast<Q>(s);
   reinterpret_cast<Q2>(s);
-  reinterpret_cast<T>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(t);
-  reinterpret_cast<T>(q); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(t);
 }
Index: gcc/testsuite/g++.dg/conversion/reinterpret3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/reinterpret3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/reinterpret3.C	(working copy)
@@ -3,5 +3,5 @@ struct S {};
 S s;
 
 void f() {
-  reinterpret_cast<const S>(s); // { dg-error "" }
+  reinterpret_cast<const S>(s); // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-cast.C	(working copy)
@@ -14,11 +14,11 @@ template <class T>
 constexpr bool f ()
 {
 #if __cplusplus > 201103L
-  T *p = reinterpret_cast<T*>(sizeof (T));
+  T *p = reinterpret_cast<T*>(sizeof (T));  // { dg-error "not a constant expression" "" { target c++14 } }
   return p;
 #else
-  return *reinterpret_cast<T*>(sizeof (T));
+  return *reinterpret_cast<T*>(sizeof (T));  // { dg-error "not a constant expression" "" { target c++11_only } }
 #endif
 }
 
-constexpr bool b = f<int>();   // { dg-error "not a constant expression|in .constexpr. expansion of " }
+constexpr bool b = f<int>();   // { dg-message "in .constexpr. expansion of " }
Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(working copy)
@@ -4,7 +4,7 @@
 void foo()
 {
   int i;
-  static_cast<void(*)()>([i]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([=]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([&]{});  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)()>([i]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([=]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([&]{});  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/nullptr04.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(working copy)
@@ -4,13 +4,13 @@
 
 __extension__ typedef __INTPTR_TYPE__ intptr_t;
 
-const int n4 = static_cast<const int>(nullptr); // { dg-error "invalid 'static_cast' " }
-const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "loses precision" }
+const int n4 = static_cast<const int>(nullptr); // { dg-error "16:invalid 'static_cast' " }
+const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n6 = reinterpret_cast<intptr_t>(nullptr);
 const intptr_t n7 = (intptr_t)nullptr;
 
 decltype(nullptr) mynull = 0;
-const int n8 = static_cast<const int>(mynull); // { dg-error "invalid 'static_cast' " }
-const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "loses precision" }
+const int n8 = static_cast<const int>(mynull); // { dg-error "16:invalid 'static_cast' " }
+const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n10 = reinterpret_cast<intptr_t>(mynull);
 const intptr_t n11 = (intptr_t)mynull;
Index: gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(working copy)
@@ -6,5 +6,5 @@ struct S { };
 void
 foo ()
 {
-  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "invalid cast of an rvalue expression of type 'void' to type" }
+  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "12:invalid cast of an rvalue expression of type 'void' to type" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/rv-cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(working copy)
@@ -10,11 +10,11 @@ struct A { };
 int main()
 {
   const_cast<int&>(lval<int>());
-  const_cast<int&>(xval<int>());   // { dg-error "" }
-  const_cast<int&>(prval<int>());  // { dg-error "" }
+  const_cast<int&>(xval<int>());   // { dg-error "3:invalid .const_cast. of an rvalue" }
+  const_cast<int&>(prval<int>());  // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<int&&>(lval<int>());
   const_cast<int&&>(xval<int>());
-  const_cast<int&&>(prval<int>()); // { dg-error "" }
+  const_cast<int&&>(prval<int>()); // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<A&&>(lval<A>());
   const_cast<A&&>(xval<A>());
   const_cast<A&&>(prval<A>());
Index: gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(working copy)
@@ -4,10 +4,10 @@
 void foo()
 {
   int i;
-  static_cast<void(*)(int)>([i](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([=](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([&](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)(int)>([i](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([=](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([&](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(working copy)
@@ -10,5 +10,5 @@ void f()
   NP np;
 
   static_cast<P>(np);
-  static_cast<NP>(p);		// { dg-error "" }
+  static_cast<NP>(p);		// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/cpp2a/array-conv9.C
===================================================================
--- gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(working copy)
@@ -8,7 +8,7 @@ void
 test ()
 {
   int (&r)[1] = const_cast<int(&)[1]>(arr);
-  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "invalid" }
+  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "17:invalid .const_cast." }
   int (&r3)[1] = (int(&)[1]) arr;
   int (&r4)[] = (int(&)[]) arr;
   int (&r5)[1] = static_cast<int(&)[1]>(arr);
@@ -23,5 +23,5 @@ test ()
   int(*p6)[] = (int(*)[1]) (int(*)[]) &arr;
   int(*p7)[] = static_cast<int(*)[]>(&arr);
   int(*p8)[] = static_cast<int(*)[1]>(&arr);
-  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "invalid" }
+  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "16:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/expr/cast11.C
===================================================================
--- gcc/testsuite/g++.dg/expr/cast11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/cast11.C	(working copy)
@@ -13,22 +13,22 @@ struct B { int i; const char c; } b = {};
 void f1()
 {
   int i = 0;
-  f((long const)i);			// { dg-warning "qualifiers ignored" }
-  f((int* const)&i);			// { dg-warning "qualifiers ignored" }
-  f((int const* const)&i);		// { dg-warning "qualifiers ignored" }
-  f((long* const)&i);			// { dg-warning "qualifiers ignored" }
+  f((long const)i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int* const)&i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int const* const)&i);		// { dg-warning "5:type qualifiers ignored" }
+  f((long* const)&i);			// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<long const>(i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<long const>(i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long* const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
   using ptrmem = int B::*;
-  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" }
+  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "5:type qualifiers ignored" }
 
   // No warnings, not a cv-qualified type:
   using ptrmem2 = const char B::*;
Index: gcc/testsuite/g++.dg/expr/static_cast8.C
===================================================================
--- gcc/testsuite/g++.dg/expr/static_cast8.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/static_cast8.C	(working copy)
@@ -9,9 +9,9 @@ extern C* c;
 
 void pointers(C* c, A2* a2, B1* b1)
 {
-  (void) static_cast<A1*>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C*>(a2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<B2*>(b1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<A1*>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C*>(a2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<B2*>(b1);	// { dg-error "10:invalid 'static_cast'" }
 }
 
 struct D1; // { dg-message "note: class type 'D1' is incomplete" }
@@ -21,7 +21,7 @@ struct E2; // { dg-message "note: class type 'E2'
 
 void references(C& c, D2& d2, E1& e1)
 {
-  (void) static_cast<D1&>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C&>(d2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<E2&>(e1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<D1&>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C&>(d2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<E2&>(e1);	// { dg-error "10:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/ext/vector6.C
===================================================================
--- gcc/testsuite/g++.dg/ext/vector6.C	(revision 279041)
+++ gcc/testsuite/g++.dg/ext/vector6.C	(working copy)
@@ -8,5 +8,5 @@ typedef union {__v_4F v; float a[4];} __v4F;
 void f(void)
 {
       __v_4F b;
-      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "" }
+      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "8:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/other/conversion1.C
===================================================================
--- gcc/testsuite/g++.dg/other/conversion1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/other/conversion1.C	(working copy)
@@ -13,5 +13,5 @@ int main()
 {
   long long m;
   
-  (void (QObject::*)()) m;    // { dg-error "invalid cast" }
+  (void (QObject::*)()) m;    // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/parse/pr26997.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr26997.C	(revision 279041)
+++ gcc/testsuite/g++.dg/parse/pr26997.C	(working copy)
@@ -21,7 +21,7 @@ class C {
 
 C bar (void)
 {
-  (C ())(3); // { dg-error "invalid cast" } 
+  (C ())(3); // { dg-error "3:invalid cast" } 
   return (C ());
 }
 
@@ -41,9 +41,9 @@ void foo2 (void)
 {
   C ()[2];
   (C ())[2];
-  (S ())(3); // { dg-error "invalid cast" } 
-  (C())*var; // { dg-error "invalid cast" } 
-  (C())+var;  // { dg-error "invalid cast" } 
+  (S ())(3); // { dg-error "3:invalid cast" } 
+  (C())*var; // { dg-error "3:invalid cast" } 
+  (C())+var;  // { dg-error "3:invalid cast" } 
   S()(3);
   (S()(3));
 }
Index: gcc/testsuite/g++.dg/rtti/no-rtti.C
===================================================================
--- gcc/testsuite/g++.dg/rtti/no-rtti.C	(revision 279041)
+++ gcc/testsuite/g++.dg/rtti/no-rtti.C	(working copy)
@@ -14,5 +14,5 @@ A* f();
 
 int main()
 {
-   B* b = dynamic_cast<B*>(f()); // { dg-error "" }
+   B* b = dynamic_cast<B*>(f()); // { dg-error "11:.dynamic_cast. not permitted" }
 }
Index: gcc/testsuite/g++.dg/tc1/dr137.C
===================================================================
--- gcc/testsuite/g++.dg/tc1/dr137.C	(revision 279041)
+++ gcc/testsuite/g++.dg/tc1/dr137.C	(working copy)
@@ -9,5 +9,5 @@ const void* v;
 void foo(void)
 {
   (void)static_cast<const volatile A *>(v);
-  (void)static_cast<A *>(v);  // { dg-error "" "static_cast cannot remove cv qualifiers" }
+  (void)static_cast<A *>(v);  // { dg-error "9:.static_cast. from type .const void\\*. to type .A\\*. casts away qualifiers" "static_cast cannot remove cv qualifiers" }
 }
Index: gcc/testsuite/g++.dg/template/cast4.C
===================================================================
--- gcc/testsuite/g++.dg/template/cast4.C	(revision 279041)
+++ gcc/testsuite/g++.dg/template/cast4.C	(working copy)
@@ -1,4 +1,4 @@
 template <class T> void f()
 {
-  static_cast<int&>(42);	// { dg-error "static_cast" }
+  static_cast<int&>(42);	// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(working copy)
@@ -3,5 +3,5 @@
 
 int main(int, char**) {
   const int foo[2] = {1,1};
-  ((int*)foo)[0] = 0; // { dg-warning "cast" }
+  ((int*)foo)[0] = 0; // { dg-warning "4:cast" }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual2.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(working copy)
@@ -1,4 +1,4 @@
 // PR c++/50956
 // { dg-options "-Wcast-qual" }
 
-void* p = (void*)"txt"; // { dg-warning "cast" }
+void* p = (void*)"txt"; // { dg-warning "11:cast" }
Index: gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(working copy)
@@ -17,9 +17,9 @@ void foo ()
   PV pv;
   PO po;
 
-  pf = reinterpret_cast <PF>(pv); // { dg-warning "conditionally-supported" }
-  pv = reinterpret_cast <PV>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(pv); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  pv = reinterpret_cast <PV>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 
-  pf = reinterpret_cast <PF>(po); // { dg-warning "conditionally-supported" }
-  po = reinterpret_cast <PO>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(po); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  po = reinterpret_cast <PO>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 }
Index: gcc/testsuite/g++.dg/warn/Wuseless-cast.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(working copy)
@@ -64,28 +64,28 @@ void f()
 {
   int n; 
 
-  (int)(n);                    // { dg-warning "useless cast" }
-  static_cast<int>(n);         // { dg-warning "useless cast" }
-  reinterpret_cast<int>(n);    // { dg-warning "useless cast" }
+  (int)(n);                    // { dg-warning "3:useless cast" }
+  static_cast<int>(n);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<int>(n);    // { dg-warning "3:useless cast" }
 
-  (int*)(&n);                  // { dg-warning "useless cast" }
-  const_cast<int*>(&n);        // { dg-warning "useless cast" }
-  static_cast<int*>(&n);       // { dg-warning "useless cast" }
-  reinterpret_cast<int*>(&n);  // { dg-warning "useless cast" }
+  (int*)(&n);                  // { dg-warning "3:useless cast" }
+  const_cast<int*>(&n);        // { dg-warning "3:useless cast" }
+  static_cast<int*>(&n);       // { dg-warning "3:useless cast" }
+  reinterpret_cast<int*>(&n);  // { dg-warning "3:useless cast" }
 
   int& m = n;
 
-  (int&)(m);                   // { dg-warning "useless cast" }
-  const_cast<int&>(m);         // { dg-warning "useless cast" }
-  static_cast<int&>(m);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(m);   // { dg-warning "useless cast" }
+  (int&)(m);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(m);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(m);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(m);   // { dg-warning "3:useless cast" }
 
   tmpl_f1(m);
 
-  (int&)(n);                   // { dg-warning "useless cast" }
-  const_cast<int&>(n);         // { dg-warning "useless cast" }
-  static_cast<int&>(n);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(n);   // { dg-warning "useless cast" }
+  (int&)(n);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(n);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(n);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(n);   // { dg-warning "3:useless cast" }
 
   tmpl_f2(n);
 
@@ -100,30 +100,30 @@ void f()
 
   A a;
 
-  (A)(a);                     // { dg-warning "useless cast" }
-  static_cast<A>(a);          // { dg-warning "useless cast" }
+  (A)(a);                     // { dg-warning "3:useless cast" }
+  static_cast<A>(a);          // { dg-warning "3:useless cast" }
 
-  (A*)(&a);                   // { dg-warning "useless cast" }
-  const_cast<A*>(&a);         // { dg-warning "useless cast" }
-  static_cast<A*>(&a);        // { dg-warning "useless cast" }
-  reinterpret_cast<A*>(&a);   // { dg-warning "useless cast" }
-  dynamic_cast<A*>(&a);       // { dg-warning "useless cast" }
+  (A*)(&a);                   // { dg-warning "3:useless cast" }
+  const_cast<A*>(&a);         // { dg-warning "3:useless cast" }
+  static_cast<A*>(&a);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<A*>(&a);   // { dg-warning "3:useless cast" }
+  dynamic_cast<A*>(&a);       // { dg-warning "3:useless cast" }
 
   A& b = a;
 
-  (A&)(b);                    // { dg-warning "useless cast" }
-  const_cast<A&>(b);          // { dg-warning "useless cast" }
-  static_cast<A&>(b);         // { dg-warning "useless cast" }     
-  static_cast<A&>(b);         // { dg-warning "useless cast" }
-  dynamic_cast<A&>(b);        // { dg-warning "useless cast" }
+  (A&)(b);                    // { dg-warning "3:useless cast" }
+  const_cast<A&>(b);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }     
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(b);        // { dg-warning "3:useless cast" }
 
   tmpl_f3(b);
 
-  (A&)(a);                    // { dg-warning "useless cast" } 
-  const_cast<A&>(a);          // { dg-warning "useless cast" }
-  static_cast<A&>(a);         // { dg-warning "useless cast" }
-  reinterpret_cast<A&>(a);    // { dg-warning "useless cast" }
-  dynamic_cast<A&>(a);        // { dg-warning "useless cast" }
+  (A&)(a);                    // { dg-warning "3:useless cast" } 
+  const_cast<A&>(a);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(a);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<A&>(a);    // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(a);        // { dg-warning "3:useless cast" }
 
   tmpl_f4(a);
 }
Index: gcc/testsuite/g++.dg/warn/pr35711.C
===================================================================
--- gcc/testsuite/g++.dg/warn/pr35711.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/pr35711.C	(working copy)
@@ -4,5 +4,5 @@
 
 int* foo (volatile int *p)
 {
-  return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
+  return (int*)p; // { dg-warning "10:cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
 }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(working copy)
@@ -33,7 +33,7 @@
 
 int main ();
 
-short s = (short) &main;	// { dg-error "loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
-char c = (char) &main;		// { dg-error "loses precision" "lose" }
+short s = (short) &main;	// { dg-error "11:cast \[^\n\r]* loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
+char c = (char) &main;		// { dg-error "10:cast \[^\n\r]* loses precision" "lose" }
 
 int main () { return 0; }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(working copy)
@@ -14,5 +14,5 @@ array_type *ap;
 
 void foo ()
 {
-  int i = *((array_type) *ap);	/* { dg-error "" } missed */
+  int i = *((array_type) *ap);	/* { dg-error "13:ISO C\\+\\+ forbids casting to an array type" } missed */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/overload1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(working copy)
@@ -8,5 +8,5 @@ struct A {
 struct B: public A { };
 
 void bar (A& a) {
-  B* bp = (B*)a;		// { dg-error "" } 
+  B* bp = (B*)a;		// { dg-error "11:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rfg26.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(working copy)
@@ -6,5 +6,5 @@ FTYPE f;                /* ok */
 void
 test_0 ()
 {
-    (FTYPE) f;          /* { dg-error "" } casting to function type */
+    (FTYPE) f;          /* { dg-error "5:invalid cast to function type" } casting to function type */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(working copy)
@@ -2,5 +2,5 @@
 int main ()
 {
    int i;
-   int &ir = (int&)(int)i;	// { dg-error "" } casting rvalue to reference type
+   int &ir = (int&)(int)i;	// { dg-error "14:invalid cast of an rvalue expression" } casting rvalue to reference type
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/warning2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(working copy)
@@ -10,5 +10,5 @@ struct B: public A { void f () { } };
 int main()
 {
   B* bp;
-  A& ar = (A&)bp;		// { dg-warning "" } 
+  A& ar = (A&)bp;		// { dg-warning "11:casting .B\\*. to .A&. does not dereference pointer" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(working copy)
@@ -1,5 +1,5 @@
 // { dg-do assemble  }
 int main() {
   int* d;
-  dynamic_cast<void*>(d);	// { dg-error "" } 
+  dynamic_cast<void*>(d);	// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(working copy)
@@ -9,5 +9,5 @@ class A {
 class B : public A { };
      
 void x (A& a) {
-  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "" } opps
+  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "17:cannot .dynamic_cast." } opps
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p11482.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(working copy)
@@ -6,5 +6,5 @@ void *vp;
 enum E { bad, ok } e;
 
 void foo() {
-  e = (E)vp;		// { dg-error "" } 
+  e = (E)vp;		// { dg-error "7:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2573.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(working copy)
@@ -9,7 +9,9 @@ class X {
 };
 
 char *X::add() {
-  char *f1 = (char *) &key;	// { dg-error "" } 
-  char *f2 = (char *) &vkey;	// { dg-error "" } 
+  char *f1 = (char *) &key;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
+  char *f2 = (char *) &vkey;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
   return f1;
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2855.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(working copy)
@@ -16,6 +16,6 @@ Ctest::operator const char *() const
 int main()
 {
   Ctest obj;
-  char* temp = (char *)obj;		// { dg-error "invalid cast" } 
+  char* temp = (char *)obj;		// { dg-error "16:invalid cast" } 
   temp[0] = '\0';
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p7476.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(working copy)
@@ -16,5 +16,5 @@ void HeapTracked::isObjectAllocation(HeapTracked *
 void HeapTracked::isObjectAllocation(const HeapTracked *ptr)
 {
   const_cast<void*>(dynamic_cast<const void*>(ptr));
-  dynamic_cast<void*>(ptr);		// { dg-error "" } 
+  dynamic_cast<void*>(ptr);		// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p8039.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(working copy)
@@ -11,5 +11,5 @@ extern void bar(int*);
 int main()
 {
   int (C::*mfp)() = &C::func;
-  bar((int*)mfp);		// { dg-error "" } no clear semantics
+  bar((int*)mfp);		// { dg-error "7:invalid cast" } no clear semantics
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast2.C	(working copy)
@@ -10,8 +10,9 @@ int main()
   typedef void (A::*F)();
   F p;
 
-  const_cast<const A>(a); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<F>(p); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<int (*)()>(&main); // { dg-error "" } function type in const_cast
-  const_cast<int (&)()>(main); // { dg-error "" } function type in const_cast
+  const_cast<const A>(a); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<F>(p); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<int (*)()>(&main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
+  // { dg-error "26:ISO C\\+\\+ forbids taking address" "" { target *-*-* } .-1 }
+  const_cast<int (&)()>(main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast3.C	(working copy)
@@ -21,12 +21,12 @@ void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <int *const *> (p);
   static_cast <int const *const *> (p);
   
-  static_cast <X *> (cp);           // { dg-error "" } lose const
+  static_cast <X *> (cp);           // { dg-error "3:.static_cast. from type .const void\\*. to type .X\\*. casts away qualifiers" } lose const
   static_cast <X const *> (cp);
-  static_cast <int *> (cp);         // { dg-error "" } lose const
+  static_cast <int *> (cp);         // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*. casts away qualifiers" } lose const
   static_cast <int const *> (cp);
-  static_cast <int **> (cp);        // { dg-error "" } lose const
-  static_cast <int const **> (cp);  // { dg-error "" } lose const
+  static_cast <int **> (cp);        // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*\\*. casts away qualifiers" } lose const
+  static_cast <int const **> (cp);  // { dg-error "3:.static_cast. from type .const void\\*. to type .const int\\*\\*. casts away qualifiers" } lose const
   static_cast <int *const *> (cp);
   static_cast <int const *const *> (cp);
   
@@ -33,12 +33,12 @@ void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <Z *> (yp);
   static_cast <Z const *> (yp);
 
-  static_cast <Z *> (ycp);          // { dg-error "" } lose const
+  static_cast <Z *> (ycp);          // { dg-error "3:.static_cast. from type .const Y\\*. to type .Z\\*. casts away qualifiers" } lose const
   static_cast <Z const *> (ycp);
 
   static_cast <Y *> (zp);
   static_cast <Y const *> (zp);
 
-  static_cast <Y *> (zcp);          // { dg-error "" } lose const
+  static_cast <Y *> (zcp);          // { dg-error "3:invalid .static_cast. from type .const Z\\*. to type .Y\\*." } lose const
   static_cast <Y const *> (zcp);
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(working copy)
@@ -10,6 +10,6 @@ extern volatile C& cr;
 
 void f ()
 {
-  dynamic_cast<void*>(cp); // { dg-error "" } cannot dynamic_cast
-  dynamic_cast<C&>(cr); // { dg-error "" } cannot dynamic_cast
+  dynamic_cast<void*>(cp); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
+  dynamic_cast<C&>(cr); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(working copy)
@@ -11,7 +11,7 @@ struct D : public B {
 
 void foo() {
   B x;
-  dynamic_cast<D*>(&x); // { dg-warning "" } will never succeed
+  dynamic_cast<D*>(&x); // { dg-warning "3:.dynamic_cast" } will never succeed
   B* p = &x;
   dynamic_cast<D*>(p);
 }
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 279041)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -3064,7 +3064,8 @@ plugin_build_cast_expr (cc1_plugin::connection *se
 			gcc_expr operand2)
 {
   plugin_context *ctx = static_cast<plugin_context *> (self);
-  tree (*build_cast)(tree type, tree expr, tsubst_flags_t complain) = NULL;
+  tree (*build_cast)(location_t loc, tree type, tree expr,
+		     tsubst_flags_t complain) = NULL;
   tree type = convert_in (operand1);
   tree expr = convert_in (operand2);
 
@@ -3101,7 +3102,7 @@ plugin_build_cast_expr (cc1_plugin::connection *se
   if (!template_dependent_p)
     processing_template_decl--;
 
-  tree val = build_cast (type, expr, tf_error);
+  tree val = build_cast (input_location, type, expr, tf_error);
 
   if (template_dependent_p)
     processing_template_decl--;
Jason Merrill Dec. 9, 2019, 7:27 p.m. UTC | #5
On 12/9/19 7:06 AM, Paolo Carlini wrote:
> Hi,
> 
> On 08/12/19 18:51, Jason Merrill wrote:
>> Hmm, is the change to cp_expr really necessary vs. using 
>> protected_set_expr_location?
> 
> Yes, using protected_set_expr_location works fine in this case, I 
> suppose because we are dealing with expressions anyway plus the cp_expr 
> constructor from a tree copies the location too. In the below I also 
> added the thin build_functional_case wrapper, this way consistently all 
> the build_*_cast functions called by the parser do not use set_location 
> afterwards. Note, at some point we should also do something about the 
> build_x_* functions which have been doing that for a while...
> 
> Anyway, the below passed testing.
> 
> Thanks, Paolo.
> 
> ////////////////////////////////
> 

OK.

Jason
diff mbox series

Patch

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 279041)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -6998,7 +6998,8 @@  extern tree build_typeid			(tree, tsubst_flags_t);
 extern tree get_tinfo_decl			(tree);
 extern tree get_typeid				(tree, tsubst_flags_t);
 extern tree build_headof			(tree);
-extern tree build_dynamic_cast			(tree, tree, tsubst_flags_t);
+extern tree build_dynamic_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern void emit_support_tinfos			(void);
 extern bool emit_tinfo_decl			(tree);
 
@@ -7547,13 +7548,17 @@  extern tree build_x_compound_expr		(location_t, tr
 						 tsubst_flags_t);
 extern tree build_compound_expr                 (location_t, tree, tree);
 extern tree cp_build_compound_expr		(tree, tree, tsubst_flags_t);
-extern tree build_static_cast			(tree, tree, tsubst_flags_t);
-extern tree build_reinterpret_cast		(tree, tree, tsubst_flags_t);
-extern tree build_const_cast			(tree, tree, tsubst_flags_t);
+extern tree build_static_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
+extern tree build_reinterpret_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
+extern tree build_const_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree build_c_cast			(location_t, tree, tree);
 extern cp_expr build_c_cast			(location_t loc, tree type,
 						 cp_expr expr);
-extern tree cp_build_c_cast			(tree, tree, tsubst_flags_t);
+extern tree cp_build_c_cast			(location_t, tree, tree,
+						 tsubst_flags_t);
 extern cp_expr build_x_modify_expr		(location_t, tree,
 						 enum tree_code, tree,
 						 tsubst_flags_t);
@@ -7613,7 +7618,8 @@  extern int lvalue_or_else			(tree, enum lvalue_use
 extern void check_template_keyword		(tree);
 extern bool check_raw_literal_operator		(const_tree decl);
 extern bool check_literal_operator_args		(const_tree, bool *, bool *);
-extern void maybe_warn_about_useless_cast       (tree, tree, tsubst_flags_t);
+extern void maybe_warn_about_useless_cast       (location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
 extern tree finish_left_unary_fold_expr      (tree, int);
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 279041)
+++ gcc/cp/decl.c	(working copy)
@@ -6483,7 +6483,8 @@  reshape_init (tree type, tree init, tsubst_flags_t
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  return cp_build_c_cast (type, elt, tf_warning_or_error);
+	  return cp_build_c_cast (input_location, type, elt,
+				  tf_warning_or_error);
 	}
       else
 	return error_mark_node;
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 279041)
+++ gcc/cp/method.c	(working copy)
@@ -474,7 +474,8 @@  forward_parm (tree parm)
   if (!TYPE_REF_P (type))
     type = cp_build_reference_type (type, /*rval=*/true);
   warning_sentinel w (warn_useless_cast);
-  exp = build_static_cast (type, exp, tf_warning_or_error);
+  exp = build_static_cast (input_location, type, exp,
+			   tf_warning_or_error);
   if (DECL_PACK_P (parm))
     exp = make_pack_expansion (exp);
   return exp;
@@ -1361,7 +1362,8 @@  build_comparison_op (tree fndecl, tsubst_flags_t c
 	      if (TREE_CODE (comp) == SPACESHIP_EXPR)
 		TREE_TYPE (comp) = rettype;
 	      else
-		comp = build_static_cast (rettype, comp, complain);
+		comp = build_static_cast (input_location, rettype, comp,
+					  complain);
 	      info.check (comp);
 	      if (info.defining)
 		{
@@ -1395,7 +1397,8 @@  build_comparison_op (tree fndecl, tsubst_flags_t c
 	    {
 	      tree seql = lookup_comparison_result (cc_strong_ordering,
 						    "equal", complain);
-	      val = build_static_cast (rettype, seql, complain);
+	      val = build_static_cast (input_location, rettype, seql,
+				       complain);
 	    }
 	  finish_return_stmt (val);
 	}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 279041)
+++ gcc/cp/parser.c	(working copy)
@@ -6895,35 +6895,39 @@  cp_parser_postfix_expression (cp_parser *parser, b
 	    break;
 	  }
 
+	/* Construct a location e.g. :
+	     reinterpret_cast <int *> (expr)
+	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	   ranging from the start of the "*_cast" token to the final closing
+	   paren, with the caret at the start.  */
+	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
+
 	switch (keyword)
 	  {
 	  case RID_DYNCAST:
 	    postfix_expression
-	      = build_dynamic_cast (type, expression, tf_warning_or_error);
+	      = build_dynamic_cast (cp_cast_loc, type, expression,
+				    tf_warning_or_error);
 	    break;
 	  case RID_STATCAST:
 	    postfix_expression
-	      = build_static_cast (type, expression, tf_warning_or_error);
+	      = build_static_cast (cp_cast_loc, type, expression,
+				   tf_warning_or_error);
 	    break;
 	  case RID_REINTCAST:
 	    postfix_expression
-	      = build_reinterpret_cast (type, expression,
+	      = build_reinterpret_cast (cp_cast_loc, type, expression,
                                         tf_warning_or_error);
 	    break;
 	  case RID_CONSTCAST:
 	    postfix_expression
-	      = build_const_cast (type, expression, tf_warning_or_error);
+	      = build_const_cast (cp_cast_loc, type, expression,
+				  tf_warning_or_error);
 	    break;
 	  default:
 	    gcc_unreachable ();
 	  }
 
-	/* Construct a location e.g. :
-	     reinterpret_cast <int *> (expr)
-	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	   ranging from the start of the "*_cast" token to the final closing
-	   paren, with the caret at the start.  */
-	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);
 	postfix_expression.set_location (cp_cast_loc);
       }
       break;
@@ -9150,17 +9154,18 @@  get_cast_suggestion (tree dst_type, tree orig_expr
     return NULL;
 
   /* First try const_cast.  */
-  trial = build_const_cast (dst_type, orig_expr, tf_none);
+  trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "const_cast";
 
   /* If that fails, try static_cast.  */
-  trial = build_static_cast (dst_type, orig_expr, tf_none);
+  trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
   if (trial != error_mark_node)
     return "static_cast";
 
   /* Finally, try reinterpret_cast.  */
-  trial = build_reinterpret_cast (dst_type, orig_expr, tf_none);
+  trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
+				  tf_none);
   if (trial != error_mark_node)
     return "reinterpret_cast";
 
@@ -10148,8 +10153,8 @@  cp_parser_builtin_offsetof (cp_parser *parser)
 
   /* Build the (type *)null that begins the traditional offsetof macro.  */
   tree object_ptr
-    = build_static_cast (build_pointer_type (type), null_pointer_node,
-			 tf_warning_or_error);
+    = build_static_cast (input_location, build_pointer_type (type),
+			 null_pointer_node, tf_warning_or_error);
 
   /* Parse the offsetof-member-designator.  We begin as if we saw "expr->".  */
   expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, object_ptr,
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 279041)
+++ gcc/cp/pt.c	(working copy)
@@ -19020,16 +19020,16 @@  tsubst_copy_and_build (tree t,
 	    r = build_functional_cast (input_location, type, op, complain);
 	    break;
 	  case REINTERPRET_CAST_EXPR:
-	    r = build_reinterpret_cast (type, op, complain);
+	    r = build_reinterpret_cast (input_location, type, op, complain);
 	    break;
 	  case CONST_CAST_EXPR:
-	    r = build_const_cast (type, op, complain);
+	    r = build_const_cast (input_location, type, op, complain);
 	    break;
 	  case DYNAMIC_CAST_EXPR:
-	    r = build_dynamic_cast (type, op, complain);
+	    r = build_dynamic_cast (input_location, type, op, complain);
 	    break;
 	  case STATIC_CAST_EXPR:
-	    r = build_static_cast (type, op, complain);
+	    r = build_static_cast (input_location, type, op, complain);
 	    break;
 	  default:
 	    gcc_unreachable ();
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c	(revision 279041)
+++ gcc/cp/rtti.c	(working copy)
@@ -123,7 +123,7 @@  static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
 
 static tree ifnonnull (tree, tree, tsubst_flags_t);
 static tree tinfo_name (tree, bool);
-static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
+static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
 static tree throw_bad_typeid (void);
 static tree get_tinfo_ptr (tree);
@@ -548,7 +548,8 @@  ifnonnull (tree test, tree result, tsubst_flags_t
    paper.  */
 
 static tree
-build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
+build_dynamic_cast_1 (location_t loc, tree type, tree expr,
+		      tsubst_flags_t complain)
 {
   enum tree_code tc = TREE_CODE (type);
   tree exprtype;
@@ -646,7 +647,7 @@  static tree
     tree binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
 			      ba_check, NULL, complain);
     if (binfo)
-      return build_static_cast (type, expr, complain);
+      return build_static_cast (loc, type, expr, complain);
   }
 
   /* Apply trivial conversion T -> T& for dereferenced ptrs.  */
@@ -691,8 +692,9 @@  static tree
 		{
 		  tree expr = throw_bad_cast ();
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, old_expr);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, old_expr);
 		  /* Bash it to the expected type.  */
 		  TREE_TYPE (expr) = type;
 		  return expr;
@@ -706,8 +708,9 @@  static tree
 		  && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE)
 		{
                   if (complain & tf_warning)
-	            warning (0, "%<dynamic_cast<%#T>(%#D)%> can never succeed",
-	                     type, op);
+	            warning_at (loc, 0,
+				"%<dynamic_cast<%#T>(%#D)%> can never succeed",
+				type, op);
 		  retval = build_int_cst (type, 0);
 		  return retval;
 		}
@@ -717,7 +720,8 @@  static tree
 	  if (!flag_rtti)
 	    {
               if (complain & tf_error)
-		error ("%<dynamic_cast%> not permitted with %<-fno-rtti%>");
+		error_at (loc,
+			  "%<dynamic_cast%> not permitted with %<-fno-rtti%>");
 	      return error_mark_node;
 	    }
 
@@ -796,13 +800,15 @@  static tree
 
  fail:
   if (complain & tf_error)
-    error ("cannot %<dynamic_cast%> %qE (of type %q#T) to type %q#T (%s)",
-           old_expr, TREE_TYPE (old_expr), type, errstr);
+    error_at (loc, "cannot %<dynamic_cast%> %qE (of type %q#T) "
+	      "to type %q#T (%s)",
+	      old_expr, TREE_TYPE (old_expr), type, errstr);
   return error_mark_node;
 }
 
 tree
-build_dynamic_cast (tree type, tree expr, tsubst_flags_t complain)
+build_dynamic_cast (location_t loc, tree type, tree expr,
+		    tsubst_flags_t complain)
 {
   tree r;
 
@@ -816,9 +822,10 @@  tree
       return convert_from_reference (expr);
     }
 
-  r = convert_from_reference (build_dynamic_cast_1 (type, expr, complain));
+  r = convert_from_reference (build_dynamic_cast_1 (loc, type, expr,
+						    complain));
   if (r != error_mark_node)
-    maybe_warn_about_useless_cast (type, expr, complain);
+    maybe_warn_about_useless_cast (loc, type, expr, complain);
   return r;
 }
 
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 279041)
+++ gcc/cp/semantics.c	(working copy)
@@ -5918,9 +5918,11 @@  finish_omp_reduction_clause (tree c, bool *need_de
 	      if (need_static_cast)
 		{
 		  tree rtype = build_reference_type (atype);
-		  omp_out = build_static_cast (rtype, omp_out,
+		  omp_out = build_static_cast (input_location,
+					       rtype, omp_out,
 					       tf_warning_or_error);
-		  omp_in = build_static_cast (rtype, omp_in,
+		  omp_in = build_static_cast (input_location,
+					      rtype, omp_in,
 					      tf_warning_or_error);
 		  if (omp_out == error_mark_node || omp_in == error_mark_node)
 		    return true;
@@ -5955,9 +5957,11 @@  finish_omp_reduction_clause (tree c, bool *need_de
 		      return true;
 		    }
 		  tree rtype = build_reference_type (atype);
-		  omp_priv = build_static_cast (rtype, omp_priv,
+		  omp_priv = build_static_cast (input_location,
+						rtype, omp_priv,
 						tf_warning_or_error);
-		  omp_orig = build_static_cast (rtype, omp_orig,
+		  omp_orig = build_static_cast (input_location,
+						rtype, omp_orig,
 						tf_warning_or_error);
 		  if (omp_priv == error_mark_node
 		      || omp_orig == error_mark_node)
@@ -6138,13 +6142,16 @@  cp_omp_finish_iterators (tree iter)
       begin = mark_rvalue_use (begin);
       end = mark_rvalue_use (end);
       step = mark_rvalue_use (step);
-      begin = cp_build_c_cast (type, begin, tf_warning_or_error);
-      end = cp_build_c_cast (type, end, tf_warning_or_error);
+      begin = cp_build_c_cast (input_location, type, begin,
+			       tf_warning_or_error);
+      end = cp_build_c_cast (input_location, type, end,
+			     tf_warning_or_error);
       orig_step = step;
       if (!processing_template_decl)
 	step = orig_step = save_expr (step);
       tree stype = POINTER_TYPE_P (type) ? sizetype : type;
-      step = cp_build_c_cast (stype, step, tf_warning_or_error);
+      step = cp_build_c_cast (input_location, stype, step,
+			      tf_warning_or_error);
       if (POINTER_TYPE_P (type) && !processing_template_decl)
 	{
 	  begin = save_expr (begin);
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c	(revision 279041)
+++ gcc/cp/tree.c	(working copy)
@@ -425,7 +425,8 @@  cp_stabilize_reference (tree ref)
 	  /* This inhibits warnings in, eg, cxx_mark_addressable
 	     (c++/60955).  */
 	  warning_sentinel s (extra_warnings);
-	  ref = build_static_cast (type, ref, tf_error);
+	  ref = build_static_cast (input_location, type, ref,
+				   tf_error);
 	}
     }
 
@@ -1222,7 +1223,8 @@  move (tree expr)
   tree type = TREE_TYPE (expr);
   gcc_assert (!TYPE_REF_P (type));
   type = cp_build_reference_type (type, /*rval*/true);
-  return build_static_cast (type, expr, tf_warning_or_error);
+  return build_static_cast (input_location, type, expr,
+			    tf_warning_or_error);
 }
 
 /* Used by the C++ front end to build qualified array types.  However,
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c	(revision 279041)
+++ gcc/cp/typeck.c	(working copy)
@@ -6446,7 +6446,7 @@  cp_build_unary_op (enum tree_code code, tree xarg,
 				   build_zero_cst (TREE_TYPE (arg)), complain);
       arg = perform_implicit_conversion (boolean_type_node, arg,
 					 complain);
-      val = invert_truthvalue_loc (input_location, arg);
+      val = invert_truthvalue_loc (location, arg);
       if (arg != error_mark_node)
 	return val;
       errstring = _("in argument to unary !");
@@ -7075,8 +7075,9 @@  cp_build_compound_expr (tree lhs, tree rhs, tsubst
 */
 
 static bool
-check_for_casting_away_constness (tree src_type, tree dest_type,
-				  enum tree_code cast, tsubst_flags_t complain)
+check_for_casting_away_constness (location_t loc, tree src_type,
+				  tree dest_type, enum tree_code cast,
+				  tsubst_flags_t complain)
 {
   /* C-style casts are allowed to cast away constness.  With
      WARN_CAST_QUAL, we still want to issue a warning.  */
@@ -7090,23 +7091,23 @@  static bool
     {
     case CAST_EXPR:
       if (complain & tf_warning)
-	warning (OPT_Wcast_qual,
-		 "cast from type %qT to type %qT casts away qualifiers",
-		 src_type, dest_type);
+	warning_at (loc, OPT_Wcast_qual,
+		    "cast from type %qT to type %qT casts away qualifiers",
+		    src_type, dest_type);
       return false;
-      
+
     case STATIC_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<static_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<static_cast%> from type %qT to type %qT casts "
+		  "away qualifiers",
+		  src_type, dest_type);
       return true;
-      
+
     case REINTERPRET_CAST_EXPR:
       if (complain & tf_error)
-	error ("%<reinterpret_cast%> from type %qT to type %qT casts away "
-	       "qualifiers",
-	       src_type, dest_type);
+	error_at (loc, "%<reinterpret_cast%> from type %qT to type %qT "
+		  "casts away qualifiers",
+		  src_type, dest_type);
       return true;
 
     default:
@@ -7116,7 +7117,8 @@  static bool
 
 /* Warns if the cast from expression EXPR to type TYPE is useless.  */
 void
-maybe_warn_about_useless_cast (tree type, tree expr, tsubst_flags_t complain)
+maybe_warn_about_useless_cast (location_t loc, tree type, tree expr,
+			       tsubst_flags_t complain)
 {
   if (warn_useless_cast
       && complain & tf_warning)
@@ -7126,22 +7128,22 @@  void
 	       ? xvalue_p (expr) : lvalue_p (expr))
 	   && same_type_p (TREE_TYPE (expr), TREE_TYPE (type)))
 	  || same_type_p (TREE_TYPE (expr), type))
-	warning (OPT_Wuseless_cast, "useless cast to type %q#T", type);
+	warning_at (loc, OPT_Wuseless_cast,
+		    "useless cast to type %q#T", type);
     }
 }
 
 /* Warns if the cast ignores cv-qualifiers on TYPE.  */
-void
-maybe_warn_about_cast_ignoring_quals (tree type, tsubst_flags_t complain)
+static void
+maybe_warn_about_cast_ignoring_quals (location_t loc, tree type,
+				      tsubst_flags_t complain)
 {
   if (warn_ignored_qualifiers
       && complain & tf_warning
       && !CLASS_TYPE_P (type)
       && (cp_type_quals (type) & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE)))
-    {
-      warning (OPT_Wignored_qualifiers, "type qualifiers ignored on cast "
-	       "result type");
-    }
+    warning_at (loc, OPT_Wignored_qualifiers,
+		"type qualifiers ignored on cast result type");
 }
 
 /* Convert EXPR (an expression with pointer-to-member type) to TYPE
@@ -7200,7 +7202,7 @@  convert_ptrmem (tree type, tree expr, bool allow_i
    indicate whether or not the cast was valid.  */
 
 static tree
-build_static_cast_1 (tree type, tree expr, bool c_cast_p,
+build_static_cast_1 (location_t loc, tree type, tree expr, bool c_cast_p,
 		     bool *valid_p, tsubst_flags_t complain)
 {
   tree intype;
@@ -7269,7 +7271,7 @@  static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7427,7 +7429,8 @@  static tree
 	return expr;
 
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
@@ -7439,7 +7442,7 @@  static tree
       if (sanitize_flags_p (SANITIZE_VPTR))
 	{
 	  tree ubsan_check
-	    = cp_ubsan_maybe_instrument_downcast (input_location, type,
+	    = cp_ubsan_maybe_instrument_downcast (loc, type,
 						  intype, expr);
 	  if (ubsan_check)
 	    expr = ubsan_check;
@@ -7476,7 +7479,7 @@  static tree
       if (can_convert (t1, t2, complain) || can_convert (t2, t1, complain))
 	{
 	  if (!c_cast_p
-	      && check_for_casting_away_constness (intype, type,
+	      && check_for_casting_away_constness (loc, intype, type,
 						   STATIC_CAST_EXPR,
 						   complain))
 	    return error_mark_node;
@@ -7498,7 +7501,8 @@  static tree
       && TYPE_PTROB_P (type))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type, STATIC_CAST_EXPR,
+	  && check_for_casting_away_constness (loc, intype, type,
+					       STATIC_CAST_EXPR,
 					       complain))
 	return error_mark_node;
       if (processing_template_decl)
@@ -7513,7 +7517,8 @@  static tree
 /* Return an expression representing static_cast<TYPE>(EXPR).  */
 
 tree
-build_static_cast (tree type, tree oexpr, tsubst_flags_t complain)
+build_static_cast (location_t loc, tree type, tree oexpr,
+		   tsubst_flags_t complain)
 {
   tree expr = oexpr;
   tree result;
@@ -7542,14 +7547,14 @@  tree
       && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0)))
     expr = TREE_OPERAND (expr, 0);
 
-  result = build_static_cast_1 (type, expr, /*c_cast_p=*/false, &valid_p,
-                                complain);
+  result = build_static_cast_1 (loc, type, expr, /*c_cast_p=*/false,
+				&valid_p, complain);
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, expr, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, expr, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       if (processing_template_decl)
 	goto tmpl;
@@ -7558,8 +7563,8 @@  tree
 
   if (complain & tf_error)
     {
-      error ("invalid %<static_cast%> from type %qT to type %qT",
-	     TREE_TYPE (expr), type);
+      error_at (loc, "invalid %<static_cast%> from type %qT to type %qT",
+		TREE_TYPE (expr), type);
       if ((TYPE_PTR_P (type) || TYPE_REF_P (type))
 	  && CLASS_TYPE_P (TREE_TYPE (type))
 	    && !COMPLETE_TYPE_P (TREE_TYPE (type)))
@@ -7633,8 +7638,9 @@  build_nop_reinterpret (tree type, tree expr)
    indicate whether or not reinterpret_cast was valid.  */
 
 static tree
-build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
-			  bool *valid_p, tsubst_flags_t complain)
+build_reinterpret_cast_1 (location_t loc, tree type, tree expr,
+			  bool c_cast_p, bool *valid_p,
+			  tsubst_flags_t complain)
 {
   tree intype;
 
@@ -7670,9 +7676,9 @@  static tree
       else if (!lvalue_p (expr))
 	{
           if (complain & tf_error)
-            error ("invalid cast of an rvalue expression of type "
-                   "%qT to type %qT",
-                   intype, type);
+            error_at (loc, "invalid cast of an rvalue expression of type "
+		      "%qT to type %qT",
+		      intype, type);
 	  return error_mark_node;
 	}
 
@@ -7683,8 +7689,8 @@  static tree
           && (complain & tf_warning)
 	  && (comptypes (TREE_TYPE (intype), TREE_TYPE (type),
 			 COMPARE_BASE | COMPARE_DERIVED)))
-	warning (0, "casting %qT to %qT does not dereference pointer",
-		 intype, type);
+	warning_at (loc, 0, "casting %qT to %qT does not dereference pointer",
+		    intype, type);
 
       expr = cp_build_addr_expr (expr, complain);
 
@@ -7693,7 +7699,7 @@  static tree
 
       if (expr != error_mark_node)
 	expr = build_reinterpret_cast_1
-	  (build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
+	  (loc, build_pointer_type (TREE_TYPE (type)), expr, c_cast_p,
 	   valid_p, complain);
       if (expr != error_mark_node)
 	/* cp_build_indirect_ref isn't right for rvalue refs.  */
@@ -7740,7 +7746,7 @@  static tree
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
           if (complain & tf_error)
-            permerror (input_location, "cast from %qH to %qI loses precision",
+            permerror (loc, "cast from %qH to %qI loses precision",
                        intype, type);
           else
             return error_mark_node;
@@ -7764,9 +7770,9 @@  static tree
       if ((complain & tf_warning)
 	  && !cxx_safe_function_type_cast_p (TREE_TYPE (type),
 					     TREE_TYPE (intype)))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible function types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible function types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
@@ -7775,9 +7781,9 @@  static tree
 	  && !cxx_safe_function_type_cast_p
 		(TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (type)),
 		 TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (intype))))
-	warning (OPT_Wcast_function_type,
-		 "cast between incompatible pointer to member types"
-		 " from %qH to %qI", intype, type);
+	warning_at (loc, OPT_Wcast_function_type,
+		    "cast between incompatible pointer to member types"
+		    " from %qH to %qI", intype, type);
       return build_nop_reinterpret (type, expr);
     }
   else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype))
@@ -7784,7 +7790,7 @@  static tree
 	   || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
     {
       if (!c_cast_p
-	  && check_for_casting_away_constness (intype, type,
+	  && check_for_casting_away_constness (loc, intype, type,
 					       REINTERPRET_CAST_EXPR,
 					       complain))
 	return error_mark_node;
@@ -7797,8 +7803,9 @@  static tree
 	  && COMPLETE_TYPE_P (TREE_TYPE (intype))
 	  && min_align_of_type (TREE_TYPE (type))
 	     > min_align_of_type (TREE_TYPE (intype)))
-	warning (OPT_Wcast_align, "cast from %qH to %qI "
-		 "increases required alignment of target type", intype, type);
+	warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+		    "increases required alignment of target type",
+		    intype, type);
 
       if (warn_strict_aliasing <= 2)
 	/* strict_aliasing_warning STRIP_NOPs its expr.  */
@@ -7812,9 +7819,9 @@  static tree
       if (complain & tf_warning)
 	/* C++11 5.2.10 p8 says that "Converting a function pointer to an
 	   object pointer type or vice versa is conditionally-supported."  */
-	warning (OPT_Wconditionally_supported,
-		 "casting between pointer-to-function and pointer-to-object "
-		 "is conditionally-supported");
+	warning_at (loc, OPT_Wconditionally_supported,
+		    "casting between pointer-to-function and "
+		    "pointer-to-object is conditionally-supported");
       return build_nop_reinterpret (type, expr);
     }
   else if (gnu_vector_type_p (type))
@@ -7827,7 +7834,8 @@  static tree
       if (valid_p)
 	*valid_p = false;
       if (complain & tf_error)
-        error ("invalid cast from type %qT to type %qT", intype, type);
+        error_at (loc, "invalid cast from type %qT to type %qT",
+		  intype, type);
       return error_mark_node;
     }
 
@@ -7839,7 +7847,8 @@  static tree
 }
 
 tree
-build_reinterpret_cast (tree type, tree expr, tsubst_flags_t complain)
+build_reinterpret_cast (location_t loc, tree type, tree expr,
+			tsubst_flags_t complain)
 {
   tree r;
 
@@ -7857,12 +7866,12 @@  tree
       return convert_from_reference (t);
     }
 
-  r = build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
+  r = build_reinterpret_cast_1 (loc, type, expr, /*c_cast_p=*/false,
 				/*valid_p=*/NULL, complain);
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
   return r;
 }
@@ -7875,8 +7884,8 @@  tree
    whether or not the conversion succeeded.  */
 
 static tree
-build_const_cast_1 (tree dst_type, tree expr, tsubst_flags_t complain,
-		    bool *valid_p)
+build_const_cast_1 (location_t loc, tree dst_type, tree expr,
+		    tsubst_flags_t complain, bool *valid_p)
 {
   tree src_type;
   tree reference_type;
@@ -7895,9 +7904,9 @@  static tree
   if (!INDIRECT_TYPE_P (dst_type) && !TYPE_PTRDATAMEM_P (dst_type))
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is not a pointer, "
-	       "reference, nor a pointer-to-data-member type", dst_type);
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is not a pointer, reference, "
+		  "nor a pointer-to-data-member type", dst_type);
       return error_mark_node;
     }
 
@@ -7904,10 +7913,10 @@  static tree
   if (TREE_CODE (TREE_TYPE (dst_type)) == FUNCTION_TYPE)
     {
       if (complain & tf_error)
-	error ("invalid use of %<const_cast%> with type %qT, "
-	       "which is a pointer or reference to a function type",
-	       dst_type);
-      return error_mark_node;
+	error_at (loc, "invalid use of %<const_cast%> with type %qT, "
+		  "which is a pointer or reference to a function type",
+		  dst_type);
+       return error_mark_node;
     }
 
   /* A prvalue of non-class type is cv-unqualified.  */
@@ -7946,10 +7955,10 @@  static tree
       else
 	{
 	  if (complain & tf_error)
-	    error ("invalid %<const_cast%> of an rvalue of type %qT "
-		   "to type %qT",
-		   src_type, dst_type);
-	  return error_mark_node;
+	    error_at (loc, "invalid %<const_cast%> of an rvalue of type %qT "
+		      "to type %qT",
+		      src_type, dst_type);
+ 	  return error_mark_node;
 	}
       dst_type = build_pointer_type (TREE_TYPE (dst_type));
       src_type = build_pointer_type (src_type);
@@ -7974,7 +7983,7 @@  static tree
 	      *valid_p = true;
 	      /* This cast is actually a C-style cast.  Issue a warning if
 		 the user is making a potentially unsafe cast.  */
-	      check_for_casting_away_constness (src_type, dst_type,
+	      check_for_casting_away_constness (loc, src_type, dst_type,
 						CAST_EXPR, complain);
 	      /* ??? comp_ptr_ttypes_const ignores TYPE_ALIGN.  */
 	      if ((STRICT_ALIGNMENT || warn_cast_align == 2)
@@ -7981,9 +7990,9 @@  static tree
 		  && (complain & tf_warning)
 		  && min_align_of_type (TREE_TYPE (dst_type))
 		     > min_align_of_type (TREE_TYPE (src_type)))
-		warning (OPT_Wcast_align, "cast from %qH to %qI "
-			 "increases required alignment of target type",
-			 src_type, dst_type);
+		warning_at (loc, OPT_Wcast_align, "cast from %qH to %qI "
+			    "increases required alignment of target type",
+			    src_type, dst_type);
 	    }
 	  if (reference_type)
 	    {
@@ -8011,18 +8020,19 @@  static tree
       else if (valid_p
 	       && !at_least_as_qualified_p (TREE_TYPE (dst_type),
 					    TREE_TYPE (src_type)))
-	check_for_casting_away_constness (src_type, dst_type, CAST_EXPR,
-					  complain);
+	check_for_casting_away_constness (loc, src_type, dst_type,
+					  CAST_EXPR, complain);
     }
 
   if (complain & tf_error)
-    error ("invalid %<const_cast%> from type %qT to type %qT",
-	   src_type, dst_type);
+    error_at (loc, "invalid %<const_cast%> from type %qT to type %qT",
+	      src_type, dst_type);
   return error_mark_node;
 }
 
 tree
-build_const_cast (tree type, tree expr, tsubst_flags_t complain)
+build_const_cast (location_t loc, tree type, tree expr,
+		  tsubst_flags_t complain)
 {
   tree r;
 
@@ -8040,11 +8050,11 @@  tree
       return convert_from_reference (t);
     }
 
-  r = build_const_cast_1 (type, expr, complain, /*valid_p=*/NULL);
+  r = build_const_cast_1 (loc, type, expr, complain, /*valid_p=*/NULL);
   if (r != error_mark_node)
     {
-      maybe_warn_about_useless_cast (type, expr, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, expr, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
     }
   return r;
 }
@@ -8052,9 +8062,9 @@  tree
 /* Like cp_build_c_cast, but for the c-common bits.  */
 
 tree
-build_c_cast (location_t /*loc*/, tree type, tree expr)
+build_c_cast (location_t loc, tree type, tree expr)
 {
-  return cp_build_c_cast (type, expr, tf_warning_or_error);
+  return cp_build_c_cast (loc, type, expr, tf_warning_or_error);
 }
 
 /* Like the "build_c_cast" used for c-common, but using cp_expr to
@@ -8064,7 +8074,7 @@  tree
 cp_expr
 build_c_cast (location_t loc, tree type, cp_expr expr)
 {
-  cp_expr result = cp_build_c_cast (type, expr, tf_warning_or_error);
+  cp_expr result = cp_build_c_cast (loc, type, expr, tf_warning_or_error);
   result.set_location (loc);
   return result;
 }
@@ -8073,7 +8083,8 @@  build_c_cast (location_t loc, tree type, cp_expr e
    TYPE of expression EXPR.  */
 
 tree
-cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
+cp_build_c_cast (location_t loc, tree type, tree expr,
+		 tsubst_flags_t complain)
 {
   tree value = expr;
   tree result;
@@ -8112,7 +8123,8 @@  tree
       if (TYPE_PTR_P (TREE_TYPE (expr)))
 	{
           if (complain & tf_error)
-            permerror (input_location, "ISO C++ forbids casting to an array type %qT", type);
+            permerror (loc, "ISO C++ forbids casting to an array type %qT",
+		       type);
           else
             return error_mark_node;
 	  type = build_pointer_type (TREE_TYPE (type));
@@ -8120,7 +8132,8 @@  tree
       else
 	{
           if (complain & tf_error)
-            error ("ISO C++ forbids casting to an array type %qT", type);
+            error_at (loc, "ISO C++ forbids casting to an array type %qT",
+		      type);
 	  return error_mark_node;
 	}
     }
@@ -8128,7 +8141,7 @@  tree
   if (FUNC_OR_METHOD_TYPE_P (type))
     {
       if (complain & tf_error)
-        error ("invalid cast to function type %qT", type);
+        error_at (loc, "invalid cast to function type %qT", type);
       return error_mark_node;
     }
 
@@ -8138,28 +8151,28 @@  tree
       && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (value))
       /* Don't warn about converting any constant.  */
       && !TREE_CONSTANT (value))
-    warning_at (input_location, OPT_Wint_to_pointer_cast, 
+    warning_at (loc, OPT_Wint_to_pointer_cast, 
 		"cast to pointer from integer of different size");
 
   /* A C-style cast can be a const_cast.  */
-  result = build_const_cast_1 (type, value, complain & tf_warning,
+  result = build_const_cast_1 (loc, type, value, complain & tf_warning,
 			       &valid_p);
   if (valid_p)
     {
       if (result != error_mark_node)
 	{
-	  maybe_warn_about_useless_cast (type, value, complain);
-	  maybe_warn_about_cast_ignoring_quals (type, complain);
+	  maybe_warn_about_useless_cast (loc, type, value, complain);
+	  maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 	}
       return result;
     }
 
   /* Or a static cast.  */
-  result = build_static_cast_1 (type, value, /*c_cast_p=*/true,
+  result = build_static_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				&valid_p, complain);
   /* Or a reinterpret_cast.  */
   if (!valid_p)
-    result = build_reinterpret_cast_1 (type, value, /*c_cast_p=*/true,
+    result = build_reinterpret_cast_1 (loc, type, value, /*c_cast_p=*/true,
 				       &valid_p, complain);
   /* The static_cast or reinterpret_cast may be followed by a
      const_cast.  */
@@ -8170,8 +8183,8 @@  tree
     {
       tree result_type;
 
-      maybe_warn_about_useless_cast (type, value, complain);
-      maybe_warn_about_cast_ignoring_quals (type, complain);
+      maybe_warn_about_useless_cast (loc, type, value, complain);
+      maybe_warn_about_cast_ignoring_quals (loc, type, complain);
 
       /* Non-class rvalues always have cv-unqualified type.  */
       if (!CLASS_TYPE_P (type))
@@ -8186,7 +8199,7 @@  tree
 	 to succeed.  */
       if (!same_type_p (non_reference (type), non_reference (result_type)))
 	{
-	  result = build_const_cast_1 (type, result, false, &valid_p);
+	  result = build_const_cast_1 (loc, type, result, false, &valid_p);
 	  gcc_assert (valid_p);
 	}
       return result;
@@ -8878,7 +8891,7 @@  build_ptrmemfunc (tree type, tree pfn, int force,
 	  if (same_type_p (to_type, pfn_type))
 	    return pfn;
 	  else if (integer_zerop (n) && TREE_CODE (pfn) != CONSTRUCTOR)
-	    return build_reinterpret_cast (to_type, pfn, 
+	    return build_reinterpret_cast (input_location, to_type, pfn, 
                                            complain);
 	}
 
@@ -8912,7 +8925,7 @@  build_ptrmemfunc (tree type, tree pfn, int force,
   /* Handle null pointer to member function conversions.  */
   if (null_ptr_cst_p (pfn))
     {
-      pfn = cp_build_c_cast (type, pfn, complain);
+      pfn = cp_build_c_cast (input_location, type, pfn, complain);
       return build_ptrmemfunc1 (to_type,
 				integer_zero_node,
 				pfn);
@@ -9067,7 +9080,7 @@  convert_for_assignment (tree type, tree rhs,
 	{
 	  warning_sentinel w (warn_useless_cast);
 	  warning_sentinel w2 (warn_ignored_qualifiers);
-	  rhs = cp_build_c_cast (type, elt, complain);
+	  rhs = cp_build_c_cast (rhs_loc, type, elt, complain);
 	}
       else
 	rhs = error_mark_node;
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 279041)
+++ gcc/cp/typeck2.c	(working copy)
@@ -2318,7 +2318,7 @@  build_functional_cast (location_t loc, tree exp, t
 
       /* This must build a C cast.  */
       parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
-      return cp_build_c_cast (type, parms, complain);
+      return cp_build_c_cast (loc, type, parms, complain);
     }
 
   /* Prepare to evaluate as a call to a constructor.  If this expression
@@ -2339,7 +2339,7 @@  build_functional_cast (location_t loc, tree exp, t
      conversion is equivalent (in definedness, and if defined in
      meaning) to the corresponding cast expression.  */
   if (parms && TREE_CHAIN (parms) == NULL_TREE)
-    return cp_build_c_cast (type, TREE_VALUE (parms), complain);
+    return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);
 
   /* [expr.type.conv]
 
Index: gcc/testsuite/c-c++-common/Wcast-align.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-align.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-align.c	(working copy)
@@ -16,8 +16,8 @@  struct t { double x; } *q;
 void
 foo (void)
 {
-  y = (c *) x;  /* { dg-warning "alignment" } */
-  z = (d *) x;  /* { dg-warning "alignment" } */
+  y = (c *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
+  z = (d *) x;  /* { dg-warning "7:cast \[^\n\r]* required alignment of target type" } */
   (long long *) p;  /* { dg-bogus "alignment" } */
   (double *) q;     /* { dg-bogus "alignment" } */
 }
Index: gcc/testsuite/c-c++-common/Wcast-function-type.c
===================================================================
--- gcc/testsuite/c-c++-common/Wcast-function-type.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wcast-function-type.c	(working copy)
@@ -24,8 +24,8 @@  void
 foo (void)
 {
   a = (f1 *) f; /* { dg-bogus   "incompatible function types" } */
-  b = (f2 *) f; /* { dg-warning "incompatible function types" } */
+  b = (f2 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   c = (f3 *) f; /* { dg-bogus   "incompatible function types" } */
-  d = (f4 *) f; /* { dg-warning "incompatible function types" } */
+  d = (f4 *) f; /* { dg-warning "7:cast between incompatible function types" } */
   e = (f5 *) f; /* { dg-bogus   "incompatible function types" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-1.c	(working copy)
@@ -8,5 +8,5 @@  char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-2.c	(working copy)
@@ -8,5 +8,5 @@  char c;
 void *
 f (void)
 {
-  return (void *) c; /* { dg-warning "cast to pointer from integer of different size" } */
+  return (void *) c; /* { dg-warning "10:cast to pointer from integer of different size" } */
 }
Index: gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(revision 279041)
+++ gcc/testsuite/c-c++-common/Wint-to-pointer-cast-3.c	(working copy)
@@ -17,6 +17,6 @@  char
 g (void)
 {
   return (char) p;
-/* { dg-warning "cast from pointer to integer of different size" "" { target c } .-1 } */
-/* { dg-error "cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
+/* { dg-warning "10:cast from pointer to integer of different size" "" { target c } .-1 } */
+/* { dg-error "10:cast from 'void\\*' to 'char' loses precision" "" { target c++ } .-2 } */
 }
Index: gcc/testsuite/g++.dg/Wcast-function-type.C
===================================================================
--- gcc/testsuite/g++.dg/Wcast-function-type.C	(revision 279041)
+++ gcc/testsuite/g++.dg/Wcast-function-type.C	(working copy)
@@ -12,6 +12,6 @@  typedef void (S::*MF)(int);
 void
 foo (void)
 {
-  MF p1 = (MF)&S::foo; /* { dg-warning "pointer to member" } */
+  MF p1 = (MF)&S::foo; /* { dg-warning "11:cast between incompatible pointer to member" } */
   MF p2 = (MF)&S::bar; /* { dg-bogus   "pointer to member" } */
 }
Index: gcc/testsuite/g++.dg/addr_builtin-1.C
===================================================================
--- gcc/testsuite/g++.dg/addr_builtin-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/addr_builtin-1.C	(working copy)
@@ -93,8 +93,8 @@  static F* test_taking_address_of_gcc_builtin ()
   // Expect a diagnostic for an invalid static_cast of a function to
   // either uintptr_t or enum, rather than one for the argument being
   // a built-in function, since the former is more relevant than the latter.
-  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "invalid" }
-  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "invalid" }
+  a = static_cast<uintptr_t>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
+  a = static_cast<UINTPTR_E>(__builtin_trap);       // { dg-error "7:invalid .static_cast." }
 
   // Reinterpret cast can cast a function to uintptr_t or enum,
   // so verify that a diagnostic is issued for the use of a builtin.
Index: gcc/testsuite/g++.dg/conversion/const2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/const2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/const2.C	(working copy)
@@ -7,5 +7,5 @@  typedef int D::*dm;
 bm bp;
 
 void f() {
-  const_cast<dm>(bp); // { dg-error "" }
+  const_cast<dm>(bp); // { dg-error "3:invalid .const_cast." }
 }
Index: gcc/testsuite/g++.dg/conversion/dynamic1.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/dynamic1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/dynamic1.C	(working copy)
@@ -11,5 +11,5 @@  A& bar();
 
 void baz()
 {
-  dynamic_cast<A&>( bar().foo );  // { dg-error "cannot 'dynamic_cast'" }
+  dynamic_cast<A&>( bar().foo );  // { dg-error "3:cannot 'dynamic_cast'" }
 }
Index: gcc/testsuite/g++.dg/conversion/ptrmem2.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem2.C	(working copy)
@@ -35,9 +35,9 @@  const int B::*p9 = static_cast<const int B::*>(&D:
 const int D::*p10 = static_cast<const int D::*>(&B::x);
 
 // Invalid conversions which decrease cv-qualification.
-int B::*p11 = static_cast<int B::*>(p10); // { dg-error "casts away qualifiers" }
-int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "casts away qualifiers" }
+int B::*p11 = static_cast<int B::*>(p10); // { dg-error "15:.static_cast. from type .const int D::\\*. to type .int B::\\*. casts away qualifiers" }
+int D::*p12 = static_cast<int D::*>(p9);  // { dg-error "15:.static_cast. from type .const int B::\\*. to type .int D::\\*. casts away qualifiers" }
 
 // Attempts to change member type.
-float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "invalid .static_cast." }
-float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "invalid .static_cast." }
+float B::*p13 = static_cast<float B::*>(&D::x); // { dg-error "17:invalid .static_cast." }
+float D::*p14 = static_cast<float D::*>(&B::x); // { dg-error "17:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/ptrmem3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/ptrmem3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/ptrmem3.C	(working copy)
@@ -27,5 +27,5 @@  int (A::*p7)() = static_cast<int (A::*)()>(&D::f);
 int (D::*p8)() = static_cast<int (D::*)()>(&A::f);  // { dg-error "" }
 
 // Attempts to change member type.
-float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "" }
-float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "" }
+float (B::*p13)() = static_cast<float (B::*)()>(&D::f); // { dg-error "21:invalid .static_cast." }
+float (D::*p14)() = static_cast<float (D::*)()>(&B::f); // { dg-error "21:invalid .static_cast." }
Index: gcc/testsuite/g++.dg/conversion/qual3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/qual3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/qual3.C	(working copy)
@@ -24,30 +24,30 @@  f (P p, Q q, Q2 q2, R r, S s, T t)
   const_cast<P>(q2);
   const_cast<Q>(p);
   const_cast<Q2>(p);
-  const_cast<S>(p); // { dg-error "invalid .const_cast." }
-  const_cast<P>(s); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q); // { dg-error "invalid .const_cast." }
-  const_cast<S>(q2); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(s); // { dg-error "invalid .const_cast." }
-  const_cast<Q2>(s); // { dg-error "invalid .const_cast." }
+  const_cast<S>(p); // { dg-error "3:invalid .const_cast." }
+  const_cast<P>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<S>(q2); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(s); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q2>(s); // { dg-error "3:invalid .const_cast." }
   const_cast<T>(s);
   const_cast<S>(t);
-  const_cast<T>(q); // { dg-error "invalid .const_cast." }
-  const_cast<Q>(t); // { dg-error "invalid .const_cast." }
+  const_cast<T>(q); // { dg-error "3:invalid .const_cast." }
+  const_cast<Q>(t); // { dg-error "3:invalid .const_cast." }
 
   // Test reinterpret_cast.
-  reinterpret_cast<P>(q); // { dg-error "casts away qualifiers" }
-  reinterpret_cast<P>(q2); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
+  reinterpret_cast<P>(q2); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(p);
   reinterpret_cast<Q2>(p);
   reinterpret_cast<S>(p);
-  reinterpret_cast<P>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<P>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(q);
   reinterpret_cast<S>(q2);
   reinterpret_cast<Q>(s);
   reinterpret_cast<Q2>(s);
-  reinterpret_cast<T>(s); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(s); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<S>(t);
-  reinterpret_cast<T>(q); // { dg-error "casts away qualifiers" }
+  reinterpret_cast<T>(q); // { dg-error "3:.reinterpret_cast. \[^\n\r]* casts away qualifiers" }
   reinterpret_cast<Q>(t);
 }
Index: gcc/testsuite/g++.dg/conversion/reinterpret3.C
===================================================================
--- gcc/testsuite/g++.dg/conversion/reinterpret3.C	(revision 279041)
+++ gcc/testsuite/g++.dg/conversion/reinterpret3.C	(working copy)
@@ -3,5 +3,5 @@  struct S {};
 S s;
 
 void f() {
-  reinterpret_cast<const S>(s); // { dg-error "" }
+  reinterpret_cast<const S>(s); // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv11.C	(working copy)
@@ -4,7 +4,7 @@ 
 void foo()
 {
   int i;
-  static_cast<void(*)()>([i]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([=]{});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)()>([&]{});  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)()>([i]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([=]{});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)()>([&]{});  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/nullptr04.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/nullptr04.C	(working copy)
@@ -4,13 +4,13 @@ 
 
 __extension__ typedef __INTPTR_TYPE__ intptr_t;
 
-const int n4 = static_cast<const int>(nullptr); // { dg-error "invalid 'static_cast' " }
-const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "loses precision" }
+const int n4 = static_cast<const int>(nullptr); // { dg-error "16:invalid 'static_cast' " }
+const short int n5 = reinterpret_cast<short int>(nullptr); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n6 = reinterpret_cast<intptr_t>(nullptr);
 const intptr_t n7 = (intptr_t)nullptr;
 
 decltype(nullptr) mynull = 0;
-const int n8 = static_cast<const int>(mynull); // { dg-error "invalid 'static_cast' " }
-const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "loses precision" }
+const int n8 = static_cast<const int>(mynull); // { dg-error "16:invalid 'static_cast' " }
+const short int n9 = reinterpret_cast<short int>(mynull); // { dg-error "22:cast from .std::nullptr_t. to .short int. loses precision" }
 const intptr_t n10 = reinterpret_cast<intptr_t>(mynull);
 const intptr_t n11 = (intptr_t)mynull;
Index: gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/reinterpret_cast2.C	(working copy)
@@ -6,5 +6,5 @@  struct S { };
 void
 foo ()
 {
-  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "invalid cast of an rvalue expression of type 'void' to type" }
+  auto a = reinterpret_cast<S&&>(foo ());	// { dg-error "12:invalid cast of an rvalue expression of type 'void' to type" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/rv-cast2.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp0x/rv-cast2.C	(working copy)
@@ -10,11 +10,11 @@  struct A { };
 int main()
 {
   const_cast<int&>(lval<int>());
-  const_cast<int&>(xval<int>());   // { dg-error "" }
-  const_cast<int&>(prval<int>());  // { dg-error "" }
+  const_cast<int&>(xval<int>());   // { dg-error "3:invalid .const_cast. of an rvalue" }
+  const_cast<int&>(prval<int>());  // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<int&&>(lval<int>());
   const_cast<int&&>(xval<int>());
-  const_cast<int&&>(prval<int>()); // { dg-error "" }
+  const_cast<int&&>(prval<int>()); // { dg-error "3:invalid .const_cast. of an rvalue" }
   const_cast<A&&>(lval<A>());
   const_cast<A&&>(xval<A>());
   const_cast<A&&>(prval<A>());
Index: gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1y/lambda-conv1.C	(working copy)
@@ -4,10 +4,10 @@ 
 void foo()
 {
   int i;
-  static_cast<void(*)(int)>([i](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([=](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<void(*)(int)>([&](auto){});  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
-  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "invalid 'static_cast'" }
+  static_cast<void(*)(int)>([i](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([=](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<void(*)(int)>([&](auto){});  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([i](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([=](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
+  static_cast<float(*)(float)>([&](auto x){ return x; });  // { dg-error "3:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp1z/noexcept-type7.C	(working copy)
@@ -10,5 +10,5 @@  void f()
   NP np;
 
   static_cast<P>(np);
-  static_cast<NP>(p);		// { dg-error "" }
+  static_cast<NP>(p);		// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/cpp2a/array-conv9.C
===================================================================
--- gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(revision 279041)
+++ gcc/testsuite/g++.dg/cpp2a/array-conv9.C	(working copy)
@@ -8,7 +8,7 @@  void
 test ()
 {
   int (&r)[1] = const_cast<int(&)[1]>(arr);
-  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "invalid" }
+  int (&r2)[] = const_cast<int(&)[]>(arr); // { dg-error "17:invalid .const_cast." }
   int (&r3)[1] = (int(&)[1]) arr;
   int (&r4)[] = (int(&)[]) arr;
   int (&r5)[1] = static_cast<int(&)[1]>(arr);
@@ -23,5 +23,5 @@  test ()
   int(*p6)[] = (int(*)[1]) (int(*)[]) &arr;
   int(*p7)[] = static_cast<int(*)[]>(&arr);
   int(*p8)[] = static_cast<int(*)[1]>(&arr);
-  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "invalid" }
+  int(*p9)[] = static_cast<int(*)[1]>(&arr2); // { dg-error "16:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/expr/cast11.C
===================================================================
--- gcc/testsuite/g++.dg/expr/cast11.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/cast11.C	(working copy)
@@ -13,22 +13,22 @@  struct B { int i; const char c; } b = {};
 void f1()
 {
   int i = 0;
-  f((long const)i);			// { dg-warning "qualifiers ignored" }
-  f((int* const)&i);			// { dg-warning "qualifiers ignored" }
-  f((int const* const)&i);		// { dg-warning "qualifiers ignored" }
-  f((long* const)&i);			// { dg-warning "qualifiers ignored" }
+  f((long const)i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int* const)&i);			// { dg-warning "5:type qualifiers ignored" }
+  f((int const* const)&i);		// { dg-warning "5:type qualifiers ignored" }
+  f((long* const)&i);			// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<long const>(i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<long const>(i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
-  f(static_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<int* const>(&i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<long* const>(&i));	// { dg-warning "qualifiers ignored" }
+  f(static_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<int* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<long* const>(&i));	// { dg-warning "5:type qualifiers ignored" }
 
   using ptrmem = int B::*;
-  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "qualifiers ignored" }
-  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "qualifiers ignored" }
+  f(static_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(const_cast<ptrmem const>(&B::i));	// { dg-warning "5:type qualifiers ignored" }
+  f(reinterpret_cast<ptrmem const>(&B::i)); // { dg-warning "5:type qualifiers ignored" }
 
   // No warnings, not a cv-qualified type:
   using ptrmem2 = const char B::*;
Index: gcc/testsuite/g++.dg/expr/static_cast8.C
===================================================================
--- gcc/testsuite/g++.dg/expr/static_cast8.C	(revision 279041)
+++ gcc/testsuite/g++.dg/expr/static_cast8.C	(working copy)
@@ -9,9 +9,9 @@  extern C* c;
 
 void pointers(C* c, A2* a2, B1* b1)
 {
-  (void) static_cast<A1*>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C*>(a2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<B2*>(b1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<A1*>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C*>(a2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<B2*>(b1);	// { dg-error "10:invalid 'static_cast'" }
 }
 
 struct D1; // { dg-message "note: class type 'D1' is incomplete" }
@@ -21,7 +21,7 @@  struct E2; // { dg-message "note: class type 'E2'
 
 void references(C& c, D2& d2, E1& e1)
 {
-  (void) static_cast<D1&>(c);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<C&>(d2);	// { dg-error "invalid 'static_cast'" }
-  (void) static_cast<E2&>(e1);	// { dg-error "invalid 'static_cast'" }
+  (void) static_cast<D1&>(c);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<C&>(d2);	// { dg-error "10:invalid 'static_cast'" }
+  (void) static_cast<E2&>(e1);	// { dg-error "10:invalid 'static_cast'" }
 }
Index: gcc/testsuite/g++.dg/ext/vector6.C
===================================================================
--- gcc/testsuite/g++.dg/ext/vector6.C	(revision 279041)
+++ gcc/testsuite/g++.dg/ext/vector6.C	(working copy)
@@ -8,5 +8,5 @@  typedef union {__v_4F v; float a[4];} __v4F;
 void f(void)
 {
       __v_4F b;
-      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "" }
+      (reinterpret_cast<__v4F>(b).a)[1] = 1; // { dg-error "8:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/other/conversion1.C
===================================================================
--- gcc/testsuite/g++.dg/other/conversion1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/other/conversion1.C	(working copy)
@@ -13,5 +13,5 @@  int main()
 {
   long long m;
   
-  (void (QObject::*)()) m;    // { dg-error "invalid cast" }
+  (void (QObject::*)()) m;    // { dg-error "3:invalid cast" }
 }
Index: gcc/testsuite/g++.dg/parse/pr26997.C
===================================================================
--- gcc/testsuite/g++.dg/parse/pr26997.C	(revision 279041)
+++ gcc/testsuite/g++.dg/parse/pr26997.C	(working copy)
@@ -21,7 +21,7 @@  class C {
 
 C bar (void)
 {
-  (C ())(3); // { dg-error "invalid cast" } 
+  (C ())(3); // { dg-error "3:invalid cast" } 
   return (C ());
 }
 
@@ -41,9 +41,9 @@  void foo2 (void)
 {
   C ()[2];
   (C ())[2];
-  (S ())(3); // { dg-error "invalid cast" } 
-  (C())*var; // { dg-error "invalid cast" } 
-  (C())+var;  // { dg-error "invalid cast" } 
+  (S ())(3); // { dg-error "3:invalid cast" } 
+  (C())*var; // { dg-error "3:invalid cast" } 
+  (C())+var;  // { dg-error "3:invalid cast" } 
   S()(3);
   (S()(3));
 }
Index: gcc/testsuite/g++.dg/rtti/no-rtti.C
===================================================================
--- gcc/testsuite/g++.dg/rtti/no-rtti.C	(revision 279041)
+++ gcc/testsuite/g++.dg/rtti/no-rtti.C	(working copy)
@@ -14,5 +14,5 @@  A* f();
 
 int main()
 {
-   B* b = dynamic_cast<B*>(f()); // { dg-error "" }
+   B* b = dynamic_cast<B*>(f()); // { dg-error "11:.dynamic_cast. not permitted" }
 }
Index: gcc/testsuite/g++.dg/tc1/dr137.C
===================================================================
--- gcc/testsuite/g++.dg/tc1/dr137.C	(revision 279041)
+++ gcc/testsuite/g++.dg/tc1/dr137.C	(working copy)
@@ -9,5 +9,5 @@  const void* v;
 void foo(void)
 {
   (void)static_cast<const volatile A *>(v);
-  (void)static_cast<A *>(v);  // { dg-error "" "static_cast cannot remove cv qualifiers" }
+  (void)static_cast<A *>(v);  // { dg-error "9:.static_cast. from type .const void\\*. to type .A\\*. casts away qualifiers" "static_cast cannot remove cv qualifiers" }
 }
Index: gcc/testsuite/g++.dg/template/cast4.C
===================================================================
--- gcc/testsuite/g++.dg/template/cast4.C	(revision 279041)
+++ gcc/testsuite/g++.dg/template/cast4.C	(working copy)
@@ -1,4 +1,4 @@ 
 template <class T> void f()
 {
-  static_cast<int&>(42);	// { dg-error "static_cast" }
+  static_cast<int&>(42);	// { dg-error "3:invalid .static_cast." }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual1.C	(working copy)
@@ -3,5 +3,5 @@ 
 
 int main(int, char**) {
   const int foo[2] = {1,1};
-  ((int*)foo)[0] = 0; // { dg-warning "cast" }
+  ((int*)foo)[0] = 0; // { dg-warning "4:cast" }
 }
Index: gcc/testsuite/g++.dg/warn/Wcast-qual2.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wcast-qual2.C	(working copy)
@@ -1,4 +1,4 @@ 
 // PR c++/50956
 // { dg-options "-Wcast-qual" }
 
-void* p = (void*)"txt"; // { dg-warning "cast" }
+void* p = (void*)"txt"; // { dg-warning "11:cast" }
Index: gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wconditionally-supported-1.C	(working copy)
@@ -17,9 +17,9 @@  void foo ()
   PV pv;
   PO po;
 
-  pf = reinterpret_cast <PF>(pv); // { dg-warning "conditionally-supported" }
-  pv = reinterpret_cast <PV>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(pv); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  pv = reinterpret_cast <PV>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 
-  pf = reinterpret_cast <PF>(po); // { dg-warning "conditionally-supported" }
-  po = reinterpret_cast <PO>(pf); // { dg-warning "conditionally-supported" }
+  pf = reinterpret_cast <PF>(po); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
+  po = reinterpret_cast <PO>(pf); // { dg-warning "8:casting between pointer-to-function and pointer-to-object is conditionally-supported" }
 }
Index: gcc/testsuite/g++.dg/warn/Wuseless-cast.C
===================================================================
--- gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/Wuseless-cast.C	(working copy)
@@ -64,28 +64,28 @@  void f()
 {
   int n; 
 
-  (int)(n);                    // { dg-warning "useless cast" }
-  static_cast<int>(n);         // { dg-warning "useless cast" }
-  reinterpret_cast<int>(n);    // { dg-warning "useless cast" }
+  (int)(n);                    // { dg-warning "3:useless cast" }
+  static_cast<int>(n);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<int>(n);    // { dg-warning "3:useless cast" }
 
-  (int*)(&n);                  // { dg-warning "useless cast" }
-  const_cast<int*>(&n);        // { dg-warning "useless cast" }
-  static_cast<int*>(&n);       // { dg-warning "useless cast" }
-  reinterpret_cast<int*>(&n);  // { dg-warning "useless cast" }
+  (int*)(&n);                  // { dg-warning "3:useless cast" }
+  const_cast<int*>(&n);        // { dg-warning "3:useless cast" }
+  static_cast<int*>(&n);       // { dg-warning "3:useless cast" }
+  reinterpret_cast<int*>(&n);  // { dg-warning "3:useless cast" }
 
   int& m = n;
 
-  (int&)(m);                   // { dg-warning "useless cast" }
-  const_cast<int&>(m);         // { dg-warning "useless cast" }
-  static_cast<int&>(m);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(m);   // { dg-warning "useless cast" }
+  (int&)(m);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(m);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(m);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(m);   // { dg-warning "3:useless cast" }
 
   tmpl_f1(m);
 
-  (int&)(n);                   // { dg-warning "useless cast" }
-  const_cast<int&>(n);         // { dg-warning "useless cast" }
-  static_cast<int&>(n);        // { dg-warning "useless cast" }
-  reinterpret_cast<int&>(n);   // { dg-warning "useless cast" }
+  (int&)(n);                   // { dg-warning "3:useless cast" }
+  const_cast<int&>(n);         // { dg-warning "3:useless cast" }
+  static_cast<int&>(n);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<int&>(n);   // { dg-warning "3:useless cast" }
 
   tmpl_f2(n);
 
@@ -100,30 +100,30 @@  void f()
 
   A a;
 
-  (A)(a);                     // { dg-warning "useless cast" }
-  static_cast<A>(a);          // { dg-warning "useless cast" }
+  (A)(a);                     // { dg-warning "3:useless cast" }
+  static_cast<A>(a);          // { dg-warning "3:useless cast" }
 
-  (A*)(&a);                   // { dg-warning "useless cast" }
-  const_cast<A*>(&a);         // { dg-warning "useless cast" }
-  static_cast<A*>(&a);        // { dg-warning "useless cast" }
-  reinterpret_cast<A*>(&a);   // { dg-warning "useless cast" }
-  dynamic_cast<A*>(&a);       // { dg-warning "useless cast" }
+  (A*)(&a);                   // { dg-warning "3:useless cast" }
+  const_cast<A*>(&a);         // { dg-warning "3:useless cast" }
+  static_cast<A*>(&a);        // { dg-warning "3:useless cast" }
+  reinterpret_cast<A*>(&a);   // { dg-warning "3:useless cast" }
+  dynamic_cast<A*>(&a);       // { dg-warning "3:useless cast" }
 
   A& b = a;
 
-  (A&)(b);                    // { dg-warning "useless cast" }
-  const_cast<A&>(b);          // { dg-warning "useless cast" }
-  static_cast<A&>(b);         // { dg-warning "useless cast" }     
-  static_cast<A&>(b);         // { dg-warning "useless cast" }
-  dynamic_cast<A&>(b);        // { dg-warning "useless cast" }
+  (A&)(b);                    // { dg-warning "3:useless cast" }
+  const_cast<A&>(b);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }     
+  static_cast<A&>(b);         // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(b);        // { dg-warning "3:useless cast" }
 
   tmpl_f3(b);
 
-  (A&)(a);                    // { dg-warning "useless cast" } 
-  const_cast<A&>(a);          // { dg-warning "useless cast" }
-  static_cast<A&>(a);         // { dg-warning "useless cast" }
-  reinterpret_cast<A&>(a);    // { dg-warning "useless cast" }
-  dynamic_cast<A&>(a);        // { dg-warning "useless cast" }
+  (A&)(a);                    // { dg-warning "3:useless cast" } 
+  const_cast<A&>(a);          // { dg-warning "3:useless cast" }
+  static_cast<A&>(a);         // { dg-warning "3:useless cast" }
+  reinterpret_cast<A&>(a);    // { dg-warning "3:useless cast" }
+  dynamic_cast<A&>(a);        // { dg-warning "3:useless cast" }
 
   tmpl_f4(a);
 }
Index: gcc/testsuite/g++.dg/warn/pr35711.C
===================================================================
--- gcc/testsuite/g++.dg/warn/pr35711.C	(revision 279041)
+++ gcc/testsuite/g++.dg/warn/pr35711.C	(working copy)
@@ -4,5 +4,5 @@ 
 
 int* foo (volatile int *p)
 {
-  return (int*)p; // { dg-warning "cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
+  return (int*)p; // { dg-warning "10:cast from type 'volatile int\\*' to type 'int\\*' casts away qualifiers" }
 }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900227_01.C	(working copy)
@@ -33,7 +33,7 @@ 
 
 int main ();
 
-short s = (short) &main;	// { dg-error "loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
-char c = (char) &main;		// { dg-error "loses precision" "lose" }
+short s = (short) &main;	// { dg-error "11:cast \[^\n\r]* loses precision" "lose" { xfail h8*-*-* xstormy16-*-* } }
+char c = (char) &main;		// { dg-error "10:cast \[^\n\r]* loses precision" "lose" }
 
 int main () { return 0; }
Index: gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.bugs/900404_07.C	(working copy)
@@ -14,5 +14,5 @@  array_type *ap;
 
 void foo ()
 {
-  int i = *((array_type) *ap);	/* { dg-error "" } missed */
+  int i = *((array_type) *ap);	/* { dg-error "13:ISO C\\+\\+ forbids casting to an array type" } missed */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/overload1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/overload1.C	(working copy)
@@ -8,5 +8,5 @@  struct A {
 struct B: public A { };
 
 void bar (A& a) {
-  B* bp = (B*)a;		// { dg-error "" } 
+  B* bp = (B*)a;		// { dg-error "11:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rfg26.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rfg26.C	(working copy)
@@ -6,5 +6,5 @@  FTYPE f;                /* ok */
 void
 test_0 ()
 {
-    (FTYPE) f;          /* { dg-error "" } casting to function type */
+    (FTYPE) f;          /* { dg-error "5:invalid cast to function type" } casting to function type */
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/rvalue3.C	(working copy)
@@ -2,5 +2,5 @@ 
 int main ()
 {
    int i;
-   int &ir = (int&)(int)i;	// { dg-error "" } casting rvalue to reference type
+   int &ir = (int&)(int)i;	// { dg-error "14:invalid cast of an rvalue expression" } casting rvalue to reference type
 }
Index: gcc/testsuite/g++.old-deja/g++.jason/warning2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.jason/warning2.C	(working copy)
@@ -10,5 +10,5 @@  struct B: public A { void f () { } };
 int main()
 {
   B* bp;
-  A& ar = (A&)bp;		// { dg-warning "" } 
+  A& ar = (A&)bp;		// { dg-warning "11:casting .B\\*. to .A&. does not dereference pointer" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast4.C	(working copy)
@@ -1,5 +1,5 @@ 
 // { dg-do assemble  }
 int main() {
   int* d;
-  dynamic_cast<void*>(d);	// { dg-error "" } 
+  dynamic_cast<void*>(d);	// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/dyncast6.C	(working copy)
@@ -9,5 +9,5 @@  class A {
 class B : public A { };
      
 void x (A& a) {
-  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "" } opps
+  const B& b1 = dynamic_cast<B&>((const A&)a);	// { dg-error "17:cannot .dynamic_cast." } opps
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p11482.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p11482.C	(working copy)
@@ -6,5 +6,5 @@  void *vp;
 enum E { bad, ok } e;
 
 void foo() {
-  e = (E)vp;		// { dg-error "" } 
+  e = (E)vp;		// { dg-error "7:invalid cast" } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2573.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2573.C	(working copy)
@@ -9,7 +9,9 @@  class X {
 };
 
 char *X::add() {
-  char *f1 = (char *) &key;	// { dg-error "" } 
-  char *f2 = (char *) &vkey;	// { dg-error "" } 
+  char *f1 = (char *) &key;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
+  char *f2 = (char *) &vkey;	// { dg-error "14:invalid cast" }
+  // { dg-error "24:ISO C\\+\\+ forbids taking the address" "" { target *-*-* } .-1 }
   return f1;
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p2855.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p2855.C	(working copy)
@@ -16,6 +16,6 @@  Ctest::operator const char *() const
 int main()
 {
   Ctest obj;
-  char* temp = (char *)obj;		// { dg-error "invalid cast" } 
+  char* temp = (char *)obj;		// { dg-error "16:invalid cast" } 
   temp[0] = '\0';
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p7476.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p7476.C	(working copy)
@@ -16,5 +16,5 @@  void HeapTracked::isObjectAllocation(HeapTracked *
 void HeapTracked::isObjectAllocation(const HeapTracked *ptr)
 {
   const_cast<void*>(dynamic_cast<const void*>(ptr));
-  dynamic_cast<void*>(ptr);		// { dg-error "" } 
+  dynamic_cast<void*>(ptr);		// { dg-error "3:cannot .dynamic_cast." } 
 }
Index: gcc/testsuite/g++.old-deja/g++.mike/p8039.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.mike/p8039.C	(working copy)
@@ -11,5 +11,5 @@  extern void bar(int*);
 int main()
 {
   int (C::*mfp)() = &C::func;
-  bar((int*)mfp);		// { dg-error "" } no clear semantics
+  bar((int*)mfp);		// { dg-error "7:invalid cast" } no clear semantics
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast2.C	(working copy)
@@ -10,8 +10,9 @@  int main()
   typedef void (A::*F)();
   F p;
 
-  const_cast<const A>(a); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<F>(p); // { dg-error "" } const_cast requires pointer/ref types
-  const_cast<int (*)()>(&main); // { dg-error "" } function type in const_cast
-  const_cast<int (&)()>(main); // { dg-error "" } function type in const_cast
+  const_cast<const A>(a); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<F>(p); // { dg-error "3:invalid use of .const_cast." } const_cast requires pointer/ref types
+  const_cast<int (*)()>(&main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
+  // { dg-error "26:ISO C\\+\\+ forbids taking address" "" { target *-*-* } .-1 }
+  const_cast<int (&)()>(main); // { dg-error "3:invalid use of .const_cast." } function type in const_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/cast3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/cast3.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/cast3.C	(working copy)
@@ -21,12 +21,12 @@  void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <int *const *> (p);
   static_cast <int const *const *> (p);
   
-  static_cast <X *> (cp);           // { dg-error "" } lose const
+  static_cast <X *> (cp);           // { dg-error "3:.static_cast. from type .const void\\*. to type .X\\*. casts away qualifiers" } lose const
   static_cast <X const *> (cp);
-  static_cast <int *> (cp);         // { dg-error "" } lose const
+  static_cast <int *> (cp);         // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*. casts away qualifiers" } lose const
   static_cast <int const *> (cp);
-  static_cast <int **> (cp);        // { dg-error "" } lose const
-  static_cast <int const **> (cp);  // { dg-error "" } lose const
+  static_cast <int **> (cp);        // { dg-error "3:.static_cast. from type .const void\\*. to type .int\\*\\*. casts away qualifiers" } lose const
+  static_cast <int const **> (cp);  // { dg-error "3:.static_cast. from type .const void\\*. to type .const int\\*\\*. casts away qualifiers" } lose const
   static_cast <int *const *> (cp);
   static_cast <int const *const *> (cp);
   
@@ -33,12 +33,12 @@  void fn (void *p, void const *cp, Y *yp, Y const *
   static_cast <Z *> (yp);
   static_cast <Z const *> (yp);
 
-  static_cast <Z *> (ycp);          // { dg-error "" } lose const
+  static_cast <Z *> (ycp);          // { dg-error "3:.static_cast. from type .const Y\\*. to type .Z\\*. casts away qualifiers" } lose const
   static_cast <Z const *> (ycp);
 
   static_cast <Y *> (zp);
   static_cast <Y const *> (zp);
 
-  static_cast <Y *> (zcp);          // { dg-error "" } lose const
+  static_cast <Y *> (zcp);          // { dg-error "3:invalid .static_cast. from type .const Z\\*. to type .Y\\*." } lose const
   static_cast <Y const *> (zcp);
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast1.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast1.C	(working copy)
@@ -10,6 +10,6 @@  extern volatile C& cr;
 
 void f ()
 {
-  dynamic_cast<void*>(cp); // { dg-error "" } cannot dynamic_cast
-  dynamic_cast<C&>(cr); // { dg-error "" } cannot dynamic_cast
+  dynamic_cast<void*>(cp); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
+  dynamic_cast<C&>(cr); // { dg-error "3:cannot .dynamic_cast." } cannot dynamic_cast
 }
Index: gcc/testsuite/g++.old-deja/g++.other/dcast2.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(revision 279041)
+++ gcc/testsuite/g++.old-deja/g++.other/dcast2.C	(working copy)
@@ -11,7 +11,7 @@  struct D : public B {
 
 void foo() {
   B x;
-  dynamic_cast<D*>(&x); // { dg-warning "" } will never succeed
+  dynamic_cast<D*>(&x); // { dg-warning "3:.dynamic_cast" } will never succeed
   B* p = &x;
   dynamic_cast<D*>(p);
 }
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 279041)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -3064,7 +3064,8 @@  plugin_build_cast_expr (cc1_plugin::connection *se
 			gcc_expr operand2)
 {
   plugin_context *ctx = static_cast<plugin_context *> (self);
-  tree (*build_cast)(tree type, tree expr, tsubst_flags_t complain) = NULL;
+  tree (*build_cast)(location_t loc, tree type, tree expr,
+		     tsubst_flags_t complain) = NULL;
   tree type = convert_in (operand1);
   tree expr = convert_in (operand2);
 
@@ -3101,7 +3102,7 @@  plugin_build_cast_expr (cc1_plugin::connection *se
   if (!template_dependent_p)
     processing_template_decl--;
 
-  tree val = build_cast (type, expr, tf_error);
+  tree val = build_cast (input_location, type, expr, tf_error);
 
   if (template_dependent_p)
     processing_template_decl--;