[C++] Add location parameter to composite_pointer_type and use it

Message ID b636f743-091c-64e9-8b8b-cea364e6bd56@oracle.com
State New
Headers show
Series
  • [C++] Add location parameter to composite_pointer_type and use it
Related show

Commit Message

Paolo Carlini Oct. 31, 2019, 3:56 p.m.
Hi,

yesterday I noticed that we want to forward the location parameter of 
cp_build_binary_op to composite_pointer_type and then 
composite_pointer_error. Note, for the time being at least, this is 
always for CPO_COMPARISON, the other two composite_pointer_operation 
cases aren't involved - and the various functions (eg, 
common_pointer_type) forward input_location - but I'm consistently 
changing all the pedwarn, emit_diagnostic, and error_at anyway to use 
the location. Additionally, I had in my tree some additional uses for 
cp_expr_loc_or_input_loc.

Tested x86_64-linux.

Thanks, Paolo.

////////////////////////////
/cp
2019-10-31  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck.c (composite_pointer_type): Add a const op_location_t&
	parameter and use it in diagnostics.
	(composite_pointer_error): Likewise.
	(composite_pointer_type_r): Add a const op_location_t&
	parameter and forward it.
	(cp_build_binary_op): Adjust calls.
	(common_pointer_type): Likewise.
	* call.c (add_builtin_candidate): Likewise.
	(build_conditional_expr_1): Likewise.
	* cp-tree.h (composite_pointer_type): Update declaration.

	* typeck.c (cxx_sizeof_expr): Use cp_expr_loc_or_input_loc
	in permerror.
	(cxx_alignof_expr): Likewise.
	(lvalue_or_else): Likewise.

/testsuite
2019-10-31  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/conversion/ptrmem9.C: Check location.
	* g++.dg/warn/Waddress-1.C: Check locations.
	* g++.old-deja/g++.jason/rfg20.C: Likewise.
	* g++.old-deja/g++.law/typeck1.C: Likewise.
	* g++.old-deja/g++.rfg/00321_01-.C: Likewise.

	* g++.dg/diagnostic/alignof1.C: New.
	* g++.dg/expr/sizeof1.C: Check location.
	* g++.dg/cpp0x/rv-lvalue-req.C: Check locations.

Comments

Paolo Carlini Nov. 1, 2019, 2:06 p.m. | #1
Hi again,

On 31/10/19 16:56, Paolo Carlini wrote:
> Hi,

>

> yesterday I noticed that we want to forward the location parameter of 

> cp_build_binary_op to composite_pointer_type and then 

> composite_pointer_error. Note, for the time being at least, this is 

> always for CPO_COMPARISON, the other two composite_pointer_operation 

> cases aren't involved - and the various functions (eg, 

> common_pointer_type) forward input_location - but I'm consistently 

> changing all the pedwarn, emit_diagnostic, and error_at anyway to use 

> the location.


In fact, build_conditional_expr_1, which passes CPO_CONDITIONAL_EXPR, 
has available a suitable location, thus we can extend my previous patch 
and forward that too instead of input_location. Tested as usual 
x86_64-linux.

Thanks, Paolo.

/////////////////////
/cp
2019-11-01  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck.c (composite_pointer_type): Add a const op_location_t&
	parameter and use it in diagnostics.
	(composite_pointer_error): Likewise.
	(composite_pointer_type_r): Add a const op_location_t&
	parameter and forward it.
	(cp_build_binary_op): Adjust calls.
	(common_pointer_type): Likewise.
	* call.c (add_builtin_candidate): Likewise.
	(build_conditional_expr_1): Likewise.
	* cp-tree.h (composite_pointer_type): Update declaration.

	* typeck.c (cxx_sizeof_expr): Use cp_expr_loc_or_input_loc
	in permerror.
	(cxx_alignof_expr): Likewise.
	(lvalue_or_else): Likewise.

/testsuite
2019-11-01  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/conversion/ptrmem9.C: Check location.
	* g++.dg/expr/cond2.C: Likewise.
	* g++.dg/warn/Waddress-1.C: Check locations.
	* g++.old-deja/g++.bugs/900324_02.C: Check location.
	* g++.old-deja/g++.jason/rfg20.C: Likewise.
	* g++.old-deja/g++.law/typeck1.C: Likewise.
	* g++.old-deja/g++.rfg/00321_01-.C: Likewise.
	* g++.old-deja/g++.rfg/00324_02-.C: Likewise.

	* g++.dg/diagnostic/alignof1.C: New.
	* g++.dg/expr/sizeof1.C: Check location.
	* g++.dg/cpp0x/rv-lvalue-req.C: Check locations.
Index: cp/call.c
===================================================================
--- cp/call.c	(revision 277705)
+++ cp/call.c	(working copy)
@@ -3029,7 +3029,8 @@ add_builtin_candidate (struct z_candidate **candid
     {
       if (TYPE_PTR_OR_PTRMEM_P (type1))
 	{
-	  tree cptype = composite_pointer_type (type1, type2,
+	  tree cptype = composite_pointer_type (input_location,
+						type1, type2,
 						error_mark_node,
 						error_mark_node,
 						CPO_CONVERSION,
@@ -5553,7 +5554,8 @@ build_conditional_expr_1 (const op_location_t &loc
 	   || (TYPE_PTRDATAMEM_P (arg2_type) && TYPE_PTRDATAMEM_P (arg3_type))
 	   || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
     {
-      result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
+      result_type = composite_pointer_type (loc,
+					    arg2_type, arg3_type, arg2,
 					    arg3, CPO_CONDITIONAL_EXPR,
 					    complain);
       if (result_type == error_mark_node)
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 277705)
+++ cp/cp-tree.h	(working copy)
@@ -7509,7 +7509,8 @@ extern tree build_ptrmemfunc1			(tree, tree, tree)
 extern void expand_ptrmemfunc_cst		(tree, tree *, tree *);
 extern tree type_after_usual_arithmetic_conversions (tree, tree);
 extern tree common_pointer_type                 (tree, tree);
-extern tree composite_pointer_type		(tree, tree, tree, tree,
+extern tree composite_pointer_type		(const op_location_t &,
+						 tree, tree, tree, tree,
 						 composite_pointer_operation,
 						 tsubst_flags_t);
 extern tree merge_types				(tree, tree);
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 277705)
+++ cp/typeck.c	(working copy)
@@ -450,25 +450,26 @@ type_after_usual_arithmetic_conversions (tree t1,
 }
 
 static void
-composite_pointer_error (diagnostic_t kind, tree t1, tree t2,
+composite_pointer_error (const op_location_t &location,
+			 diagnostic_t kind, tree t1, tree t2,
 			 composite_pointer_operation operation)
 {
   switch (operation)
     {
     case CPO_COMPARISON:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "comparison between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
       break;
     case CPO_CONVERSION:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "conversion between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
       break;
     case CPO_CONDITIONAL_EXPR:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "conditional expression between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
@@ -482,7 +483,8 @@ static void
    case.  See that function for documentation of the parameters.  */
 
 static tree
-composite_pointer_type_r (tree t1, tree t2, 
+composite_pointer_type_r (const op_location_t &location,
+			  tree t1, tree t2, 
 			  composite_pointer_operation operation,
 			  tsubst_flags_t complain)
 {
@@ -515,8 +517,8 @@ static tree
   else if ((TYPE_PTR_P (pointee1) && TYPE_PTR_P (pointee2))
 	   || (TYPE_PTRMEM_P (pointee1) && TYPE_PTRMEM_P (pointee2)))
     {
-      result_type = composite_pointer_type_r (pointee1, pointee2, operation,
-					      complain);
+      result_type = composite_pointer_type_r (location, pointee1, pointee2,
+					      operation, complain);
       if (result_type == error_mark_node)
 	return error_mark_node;
     }
@@ -523,7 +525,8 @@ static tree
   else
     {
       if (complain & tf_error)
-	composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+	composite_pointer_error (location, DK_PERMERROR,
+				 t1, t2, operation);
       else
 	return error_mark_node;
       result_type = void_type_node;
@@ -539,7 +542,8 @@ static tree
 			TYPE_PTRMEM_CLASS_TYPE (t2)))
 	{
 	  if (complain & tf_error)
-	    composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+	    composite_pointer_error (location, DK_PERMERROR,
+				     t1, t2, operation);
 	  else
 	    return error_mark_node;
 	}
@@ -563,7 +567,8 @@ static tree
    pointers-to-members as per [expr.eq].  */
 
 tree
-composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
+composite_pointer_type (const op_location_t &location,
+			tree t1, tree t2, tree arg1, tree arg2,
 			composite_pointer_operation operation, 
 			tsubst_flags_t complain)
 {
@@ -605,17 +610,17 @@ tree
 	      switch (operation)
 		{
 		case CPO_COMPARISON:
-		  pedwarn (input_location, OPT_Wpedantic, 
+		  pedwarn (location, OPT_Wpedantic, 
 			   "ISO C++ forbids comparison between pointer "
 			   "of type %<void *%> and pointer-to-function");
 		  break;
 		case CPO_CONVERSION:
-		  pedwarn (input_location, OPT_Wpedantic,
+		  pedwarn (location, OPT_Wpedantic,
 			   "ISO C++ forbids conversion between pointer "
 			   "of type %<void *%> and pointer-to-function");
 		  break;
 		case CPO_CONDITIONAL_EXPR:
-		  pedwarn (input_location, OPT_Wpedantic,
+		  pedwarn (location, OPT_Wpedantic,
 			   "ISO C++ forbids conditional expression between "
 			   "pointer of type %<void *%> and "
 			   "pointer-to-function");
@@ -672,7 +677,7 @@ tree
       else
         {
           if (complain & tf_error)
-	    composite_pointer_error (DK_ERROR, t1, t2, operation);
+	    composite_pointer_error (location, DK_ERROR, t1, t2, operation);
           return error_mark_node;
         }
     }
@@ -695,19 +700,19 @@ tree
             switch (operation)
               {
               case CPO_COMPARISON:
-                error ("comparison between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "comparison between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               case CPO_CONVERSION:
-                error ("conversion between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "conversion between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               case CPO_CONDITIONAL_EXPR:
-                error ("conditional expression between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "conditional expression between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               default:
                 gcc_unreachable ();
@@ -716,7 +721,7 @@ tree
         }
     }
 
-  return composite_pointer_type_r (t1, t2, operation, complain);
+  return composite_pointer_type_r (location, t1, t2, operation, complain);
 }
 
 /* Return the merged type of two types.
@@ -951,7 +956,8 @@ common_pointer_type (tree t1, tree t2)
               || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
 
-  return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
+  return composite_pointer_type (input_location, t1, t2,
+				 error_mark_node, error_mark_node,
                                  CPO_CONVERSION, tf_warning_or_error);
 }
 
@@ -1768,8 +1774,9 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain)
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        permerror (input_location, "ISO C++ forbids applying %<sizeof%> to an expression of "
-                   "function type");
+	permerror (cp_expr_loc_or_input_loc (e),
+		   "ISO C++ forbids applying %<sizeof%> to an expression "
+		   "of function type");
       else
         return error_mark_node;
       e = char_type_node;
@@ -1830,8 +1837,9 @@ cxx_alignof_expr (tree e, tsubst_flags_t complain)
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        permerror (input_location, "ISO C++ forbids applying %<__alignof%> to an expression of "
-                   "function type");
+	permerror (cp_expr_loc_or_input_loc (e),
+		   "ISO C++ forbids applying %<__alignof%> to an expression "
+		   "of function type");
       else
         return error_mark_node;
       if (TREE_CODE (e) == FUNCTION_DECL)
@@ -4935,7 +4943,8 @@ cp_build_binary_op (const op_location_t &location,
 		   && TYPE_PTR_P (type1) && integer_zerop (op1)))
 	{
 	  if (TYPE_PTR_P (type1))
-	    result_type = composite_pointer_type (type0, type1, op0, op1,
+	    result_type = composite_pointer_type (location,
+						  type0, type1, op0, op1,
 						  CPO_COMPARISON, complain);
 	  else
 	    result_type = type0;
@@ -4958,7 +4967,8 @@ cp_build_binary_op (const op_location_t &location,
 		   && TYPE_PTR_P (type0) && integer_zerop (op0)))
 	{
 	  if (TYPE_PTR_P (type0))
-	    result_type = composite_pointer_type (type0, type1, op0, op1,
+	    result_type = composite_pointer_type (location,
+						  type0, type1, op0, op1,
 						  CPO_COMPARISON, complain);
 	  else
 	    result_type = type1;
@@ -4976,7 +4986,8 @@ cp_build_binary_op (const op_location_t &location,
 	}
       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	       || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
 	/* One of the operands must be of nullptr_t type.  */
@@ -5055,7 +5066,7 @@ cp_build_binary_op (const op_location_t &location,
 	  tree delta0;
 	  tree delta1;
 
-	  type = composite_pointer_type (type0, type1, op0, op1, 
+	  type = composite_pointer_type (location, type0, type1, op0, op1, 
 					 CPO_COMPARISON, complain);
 
 	  if (!same_type_p (TREE_TYPE (op0), type))
@@ -5169,7 +5180,8 @@ cp_build_binary_op (const op_location_t &location,
 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
 	shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       break;
 
@@ -5252,7 +5264,8 @@ cp_build_binary_op (const op_location_t &location,
 	       || code1 == ENUMERAL_TYPE))
 	short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       else if (code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
 	{
@@ -10368,7 +10381,8 @@ lvalue_or_else (tree ref, enum lvalue_use use, tsu
       if (!(complain & tf_error))
 	return 0;
       /* Make this a permerror because we used to accept it.  */
-      permerror (input_location, "using rvalue as lvalue");
+      permerror (cp_expr_loc_or_input_loc (ref),
+		 "using rvalue as lvalue");
     }
   return 1;
 }
Index: testsuite/g++.dg/conversion/ptrmem9.C
===================================================================
--- testsuite/g++.dg/conversion/ptrmem9.C	(revision 277705)
+++ testsuite/g++.dg/conversion/ptrmem9.C	(working copy)
@@ -22,5 +22,5 @@ void f ()
 
   pd == pb;
   pd == pbv;  // { dg-error "" }
-  pd == pc;   // { dg-error "comparison between distinct pointer-to-member types" }
+  pd == pc;   // { dg-error "6:comparison between distinct pointer-to-member types" }
 }
Index: testsuite/g++.dg/cpp0x/rv-lvalue-req.C
===================================================================
--- testsuite/g++.dg/cpp0x/rv-lvalue-req.C	(revision 277705)
+++ testsuite/g++.dg/cpp0x/rv-lvalue-req.C	(working copy)
@@ -5,8 +5,8 @@ template <class T> T&& declval();
 int main()
 {
   &declval<int>();		        // { dg-error "rvalue" }
-  declval<int>() = declval<int>();	// { dg-error "rvalue" }
-  declval<int>()++;			// { dg-error "rvalue" }
-  --declval<int>();			// { dg-error "rvalue" }
+  declval<int>() = declval<int>();	// { dg-error "15:using rvalue as lvalue" }
+  declval<int>()++;			// { dg-error "15:using rvalue as lvalue" }
+  --declval<int>();			// { dg-error "17:using rvalue as lvalue" }
   declval<int>() += 1;			// { dg-error "rvalue" }
 }
Index: testsuite/g++.dg/diagnostic/alignof1.C
===================================================================
--- testsuite/g++.dg/diagnostic/alignof1.C	(nonexistent)
+++ testsuite/g++.dg/diagnostic/alignof1.C	(working copy)
@@ -0,0 +1,5 @@
+struct A
+{
+  int foo() { return __alignof(bar); } // { dg-error "32:ISO C\\+\\+ forbids applying .__alignof." }
+  int bar();
+};
Index: testsuite/g++.dg/expr/cond2.C
===================================================================
--- testsuite/g++.dg/expr/cond2.C	(revision 277705)
+++ testsuite/g++.dg/expr/cond2.C	(working copy)
@@ -8,5 +8,5 @@ struct IsZero : Term {
 Term*
 IsZero::eval()
 {
-  return true ? new Boolean(false) : this; // { dg-error "conditional expression" }
+  return true ? new Boolean(false) : this; // { dg-error "15:conditional expression" }
 }
Index: testsuite/g++.dg/expr/sizeof1.C
===================================================================
--- testsuite/g++.dg/expr/sizeof1.C	(revision 277705)
+++ testsuite/g++.dg/expr/sizeof1.C	(working copy)
@@ -2,6 +2,6 @@
 
 struct A
 {
-  int foo() { return sizeof(bar); } // { dg-error "" }
+  int foo() { return sizeof(bar); } // { dg-error "29:ISO C\\+\\+ forbids applying .sizeof." }
   int bar();
 };
Index: testsuite/g++.dg/warn/Waddress-1.C
===================================================================
--- testsuite/g++.dg/warn/Waddress-1.C	(revision 277705)
+++ testsuite/g++.dg/warn/Waddress-1.C	(working copy)
@@ -15,36 +15,38 @@ double d;
 
 void f()  { if (z) z(); }               // { dg-warning "address" }
 
-void gl() { if (z != 0) z(); }          // { dg-warning "address" }
-void hl() { if (z != (ptrf)0) z(); }    // { dg-warning "address" }
-void il() { if (z != (void*)0) z(); }   // { dg-warning "address|comparison" }
-void jl() { if (&n != (int*)0) z(); }   // { dg-warning "address" }
-void kl() { if (&m != (int*)0) z(); }   // { dg-warning "address" }
-void ll() { if (&s != (T*)0) z(); }     // { dg-warning "address" }
-void ml() { if (&t != (S*)0) z(); }     // { dg-warning "address" }
+void gl() { if (z != 0) z(); }          // { dg-warning "19:address" }
+void hl() { if (z != (ptrf)0) z(); }    // { dg-warning "19:address" }
+void il() { if (z != (void*)0) z(); }   // { dg-warning "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void jl() { if (&n != (int*)0) z(); }   // { dg-warning "20:address" }
+void kl() { if (&m != (int*)0) z(); }   // { dg-warning "20:address" }
+void ll() { if (&s != (T*)0) z(); }     // { dg-warning "20:address" }
+void ml() { if (&t != (S*)0) z(); }     // { dg-warning "20:address" }
 
-void nl() { if (z != (S*)0) z(); }      // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void pl() { if (z != (ptrfn)0) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void ql() { if (&d != (int*)0) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void rl() { if (&s != (U*)0) z(); }     // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
+void nl() { if (z != (S*)0) z(); }      // { dg-error "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void pl() { if (z != (ptrfn)0) z(); }   // { dg-error "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void ql() { if (&d != (int*)0) z(); }   // { dg-error "20:comparison" }
+// { dg-warning "20:address" "" { target *-*-* } .-1 }
+void rl() { if (&s != (U*)0) z(); }     // { dg-error "20:comparison" }
+// { dg-warning "20:address" "" { target *-*-* } .-1 }
 
-void gr() { if (0 != z) z(); }          // { dg-warning "address" }
-void hr() { if ((ptrf)0 != z) z(); }    // { dg-warning "address" }
-void ir() { if ((void*)0 != z) z(); }   // { dg-warning "address|comparison" }
-void jr() { if ((int*)0 != &n) z(); }   // { dg-warning "address" }
-void kr() { if ((int*)0 != &m) z(); }   // { dg-warning "address" }
-void lr() { if ((T*)0 != &s) z(); }     // { dg-warning "address" }
-void mr() { if ((S*)0 != &t) z(); }     // { dg-warning "address" }
+void gr() { if (0 != z) z(); }          // { dg-warning "19:address" }
+void hr() { if ((ptrf)0 != z) z(); }    // { dg-warning "25:address" }
+void ir() { if ((void*)0 != z) z(); }   // { dg-warning "26:comparison" }
+// { dg-warning "26:address" "" { target *-*-* } .-1 }
+void jr() { if ((int*)0 != &n) z(); }   // { dg-warning "25:address" }
+void kr() { if ((int*)0 != &m) z(); }   // { dg-warning "25:address" }
+void lr() { if ((T*)0 != &s) z(); }     // { dg-warning "23:address" }
+void mr() { if ((S*)0 != &t) z(); }     // { dg-warning "23:address" }
 
-void nr() { if ((S*)0 != z) z(); }      // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void pr() { if ((ptrfn)0 != z) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void qr() { if ((int*)0 != &d) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void rr() { if ((U*)0 != &s) z(); }     // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
+void nr() { if ((S*)0 != z) z(); }      // { dg-error "23:comparison" }
+// { dg-warning "23:address" "" { target *-*-* } .-1 }
+void pr() { if ((ptrfn)0 != z) z(); }   // { dg-error "26:comparison" }
+// { dg-warning "26:address" "" { target *-*-* } .-1 }
+void qr() { if ((int*)0 != &d) z(); }   // { dg-error "25:comparison" }
+// { dg-warning "25:address" "" { target *-*-* } .-1 }
+void rr() { if ((U*)0 != &s) z(); }     // { dg-error "23:comparison" }
+// { dg-warning "23:address" "" { target *-*-* } .-1 }
Index: testsuite/g++.old-deja/g++.bugs/900324_02.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900324_02.C	(revision 277705)
+++ testsuite/g++.old-deja/g++.bugs/900324_02.C	(working copy)
@@ -13,7 +13,7 @@ void (*fp)(void);
 
 void function_1 ()
 {
-  fp = 1 ? function_0 : fp;		// { dg-error "conditional expression|invalid conversion" } 
+  fp = 1 ? function_0 : fp;		// { dg-error "10:conditional expression|invalid conversion" } 
 }
 
 int main () { return 0; }
Index: testsuite/g++.old-deja/g++.jason/rfg20.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/rfg20.C	(revision 277705)
+++ testsuite/g++.old-deja/g++.jason/rfg20.C	(working copy)
@@ -6,5 +6,5 @@ void *vp;
 
 void example ()
 {
-    vp != fp;			// { dg-error "forbids comparison" } no conversion from pfn to void*
+    vp != fp;			// { dg-error "8:ISO C\\+\\+ forbids comparison" } no conversion from pfn to void*
 }
Index: testsuite/g++.old-deja/g++.law/typeck1.C
===================================================================
--- testsuite/g++.old-deja/g++.law/typeck1.C	(revision 277705)
+++ testsuite/g++.old-deja/g++.law/typeck1.C	(working copy)
@@ -13,6 +13,6 @@
 
         int test( const foo* f, const bar* b )
                 {
-                return f == b;// { dg-error "comparison between distinct pointer types" } 
+                return f == b;// { dg-error "26:comparison between distinct pointer types" } 
                 }
 
Index: testsuite/g++.old-deja/g++.rfg/00321_01-.C
===================================================================
--- testsuite/g++.old-deja/g++.rfg/00321_01-.C	(revision 277705)
+++ testsuite/g++.old-deja/g++.rfg/00321_01-.C	(working copy)
@@ -9,6 +9,6 @@ int (*p2)[5];
 void
 test ()
 {
-  p1 == p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
-  p1 > p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
+  p1 == p2;		// { dg-error "6:comparison between distinct pointer types" } comparison.*
+  p1 > p2;		// { dg-error "6:comparison between distinct pointer types" } comparison.*
 }
Index: testsuite/g++.old-deja/g++.rfg/00324_02-.C
===================================================================
--- testsuite/g++.old-deja/g++.rfg/00324_02-.C	(revision 277705)
+++ testsuite/g++.old-deja/g++.rfg/00324_02-.C	(working copy)
@@ -12,5 +12,5 @@ int i;
 void
 test ()
 {
-   i ? f : fp; // { dg-error "conditional expression|invalid conversion" } 
+   i ? f : fp; // { dg-error "6:conditional expression|invalid conversion" } 
 }
Jason Merrill Nov. 1, 2019, 7:53 p.m. | #2
On 11/1/19 10:06 AM, Paolo Carlini wrote:
> Hi again,

> 

> On 31/10/19 16:56, Paolo Carlini wrote:

>> Hi,

>>

>> yesterday I noticed that we want to forward the location parameter of 

>> cp_build_binary_op to composite_pointer_type and then 

>> composite_pointer_error. Note, for the time being at least, this is 

>> always for CPO_COMPARISON, the other two composite_pointer_operation 

>> cases aren't involved - and the various functions (eg, 

>> common_pointer_type) forward input_location - but I'm consistently 

>> changing all the pedwarn, emit_diagnostic, and error_at anyway to use 

>> the location.

> 

> In fact, build_conditional_expr_1, which passes CPO_CONDITIONAL_EXPR, 

> has available a suitable location, thus we can extend my previous patch 

> and forward that too instead of input_location. Tested as usual 

> x86_64-linux.

> 

> Thanks, Paolo.

> 

> /////////////////////

> 

OK.

Patch

Index: cp/call.c
===================================================================
--- cp/call.c	(revision 277657)
+++ cp/call.c	(working copy)
@@ -3029,7 +3029,8 @@  add_builtin_candidate (struct z_candidate **candid
     {
       if (TYPE_PTR_OR_PTRMEM_P (type1))
 	{
-	  tree cptype = composite_pointer_type (type1, type2,
+	  tree cptype = composite_pointer_type (input_location,
+						type1, type2,
 						error_mark_node,
 						error_mark_node,
 						CPO_CONVERSION,
@@ -5553,7 +5554,8 @@  build_conditional_expr_1 (const op_location_t &loc
 	   || (TYPE_PTRDATAMEM_P (arg2_type) && TYPE_PTRDATAMEM_P (arg3_type))
 	   || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
     {
-      result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
+      result_type = composite_pointer_type (input_location,
+					    arg2_type, arg3_type, arg2,
 					    arg3, CPO_CONDITIONAL_EXPR,
 					    complain);
       if (result_type == error_mark_node)
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 277657)
+++ cp/cp-tree.h	(working copy)
@@ -7509,7 +7509,8 @@  extern tree build_ptrmemfunc1			(tree, tree, tree)
 extern void expand_ptrmemfunc_cst		(tree, tree *, tree *);
 extern tree type_after_usual_arithmetic_conversions (tree, tree);
 extern tree common_pointer_type                 (tree, tree);
-extern tree composite_pointer_type		(tree, tree, tree, tree,
+extern tree composite_pointer_type		(const op_location_t &,
+						 tree, tree, tree, tree,
 						 composite_pointer_operation,
 						 tsubst_flags_t);
 extern tree merge_types				(tree, tree);
Index: cp/typeck.c
===================================================================
--- cp/typeck.c	(revision 277657)
+++ cp/typeck.c	(working copy)
@@ -450,25 +450,26 @@  type_after_usual_arithmetic_conversions (tree t1,
 }
 
 static void
-composite_pointer_error (diagnostic_t kind, tree t1, tree t2,
+composite_pointer_error (const op_location_t &location,
+			 diagnostic_t kind, tree t1, tree t2,
 			 composite_pointer_operation operation)
 {
   switch (operation)
     {
     case CPO_COMPARISON:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "comparison between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
       break;
     case CPO_CONVERSION:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "conversion between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
       break;
     case CPO_CONDITIONAL_EXPR:
-      emit_diagnostic (kind, input_location, 0,
+      emit_diagnostic (kind, location, 0,
 		       "conditional expression between "
 		       "distinct pointer types %qT and %qT lacks a cast",
 		       t1, t2);
@@ -482,7 +483,8 @@  static void
    case.  See that function for documentation of the parameters.  */
 
 static tree
-composite_pointer_type_r (tree t1, tree t2, 
+composite_pointer_type_r (const op_location_t &location,
+			  tree t1, tree t2, 
 			  composite_pointer_operation operation,
 			  tsubst_flags_t complain)
 {
@@ -515,8 +517,8 @@  static tree
   else if ((TYPE_PTR_P (pointee1) && TYPE_PTR_P (pointee2))
 	   || (TYPE_PTRMEM_P (pointee1) && TYPE_PTRMEM_P (pointee2)))
     {
-      result_type = composite_pointer_type_r (pointee1, pointee2, operation,
-					      complain);
+      result_type = composite_pointer_type_r (location, pointee1, pointee2,
+					      operation, complain);
       if (result_type == error_mark_node)
 	return error_mark_node;
     }
@@ -523,7 +525,8 @@  static tree
   else
     {
       if (complain & tf_error)
-	composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+	composite_pointer_error (location, DK_PERMERROR,
+				 t1, t2, operation);
       else
 	return error_mark_node;
       result_type = void_type_node;
@@ -539,7 +542,8 @@  static tree
 			TYPE_PTRMEM_CLASS_TYPE (t2)))
 	{
 	  if (complain & tf_error)
-	    composite_pointer_error (DK_PERMERROR, t1, t2, operation);
+	    composite_pointer_error (location, DK_PERMERROR,
+				     t1, t2, operation);
 	  else
 	    return error_mark_node;
 	}
@@ -563,7 +567,8 @@  static tree
    pointers-to-members as per [expr.eq].  */
 
 tree
-composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
+composite_pointer_type (const op_location_t &location,
+			tree t1, tree t2, tree arg1, tree arg2,
 			composite_pointer_operation operation, 
 			tsubst_flags_t complain)
 {
@@ -605,17 +610,17 @@  tree
 	      switch (operation)
 		{
 		case CPO_COMPARISON:
-		  pedwarn (input_location, OPT_Wpedantic, 
+		  pedwarn (location, OPT_Wpedantic, 
 			   "ISO C++ forbids comparison between pointer "
 			   "of type %<void *%> and pointer-to-function");
 		  break;
 		case CPO_CONVERSION:
-		  pedwarn (input_location, OPT_Wpedantic,
+		  pedwarn (location, OPT_Wpedantic,
 			   "ISO C++ forbids conversion between pointer "
 			   "of type %<void *%> and pointer-to-function");
 		  break;
 		case CPO_CONDITIONAL_EXPR:
-		  pedwarn (input_location, OPT_Wpedantic,
+		  pedwarn (location, OPT_Wpedantic,
 			   "ISO C++ forbids conditional expression between "
 			   "pointer of type %<void *%> and "
 			   "pointer-to-function");
@@ -672,7 +677,7 @@  tree
       else
         {
           if (complain & tf_error)
-	    composite_pointer_error (DK_ERROR, t1, t2, operation);
+	    composite_pointer_error (location, DK_ERROR, t1, t2, operation);
           return error_mark_node;
         }
     }
@@ -695,19 +700,19 @@  tree
             switch (operation)
               {
               case CPO_COMPARISON:
-                error ("comparison between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "comparison between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               case CPO_CONVERSION:
-                error ("conversion between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "conversion between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               case CPO_CONDITIONAL_EXPR:
-                error ("conditional expression between distinct "
-                       "pointer-to-member types %qT and %qT lacks a cast",
-                       t1, t2);
+                error_at (location, "conditional expression between distinct "
+			  "pointer-to-member types %qT and %qT lacks a cast",
+			  t1, t2);
                 break;
               default:
                 gcc_unreachable ();
@@ -716,7 +721,7 @@  tree
         }
     }
 
-  return composite_pointer_type_r (t1, t2, operation, complain);
+  return composite_pointer_type_r (location, t1, t2, operation, complain);
 }
 
 /* Return the merged type of two types.
@@ -951,7 +956,8 @@  common_pointer_type (tree t1, tree t2)
               || (TYPE_PTRDATAMEM_P (t1) && TYPE_PTRDATAMEM_P (t2))
               || (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)));
 
-  return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
+  return composite_pointer_type (input_location, t1, t2,
+				 error_mark_node, error_mark_node,
                                  CPO_CONVERSION, tf_warning_or_error);
 }
 
@@ -1768,8 +1774,9 @@  cxx_sizeof_expr (tree e, tsubst_flags_t complain)
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        permerror (input_location, "ISO C++ forbids applying %<sizeof%> to an expression of "
-                   "function type");
+	permerror (cp_expr_loc_or_input_loc (e),
+		   "ISO C++ forbids applying %<sizeof%> to an expression "
+		   "of function type");
       else
         return error_mark_node;
       e = char_type_node;
@@ -1830,8 +1837,9 @@  cxx_alignof_expr (tree e, tsubst_flags_t complain)
   else if (is_overloaded_fn (e))
     {
       if (complain & tf_error)
-        permerror (input_location, "ISO C++ forbids applying %<__alignof%> to an expression of "
-                   "function type");
+	permerror (cp_expr_loc_or_input_loc (e),
+		   "ISO C++ forbids applying %<__alignof%> to an expression "
+		   "of function type");
       else
         return error_mark_node;
       if (TREE_CODE (e) == FUNCTION_DECL)
@@ -4935,7 +4943,8 @@  cp_build_binary_op (const op_location_t &location,
 		   && TYPE_PTR_P (type1) && integer_zerop (op1)))
 	{
 	  if (TYPE_PTR_P (type1))
-	    result_type = composite_pointer_type (type0, type1, op0, op1,
+	    result_type = composite_pointer_type (location,
+						  type0, type1, op0, op1,
 						  CPO_COMPARISON, complain);
 	  else
 	    result_type = type0;
@@ -4958,7 +4967,8 @@  cp_build_binary_op (const op_location_t &location,
 		   && TYPE_PTR_P (type0) && integer_zerop (op0)))
 	{
 	  if (TYPE_PTR_P (type0))
-	    result_type = composite_pointer_type (type0, type1, op0, op1,
+	    result_type = composite_pointer_type (location,
+						  type0, type1, op0, op1,
 						  CPO_COMPARISON, complain);
 	  else
 	    result_type = type1;
@@ -4976,7 +4986,8 @@  cp_build_binary_op (const op_location_t &location,
 	}
       else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
 	       || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1)))
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       else if (null_ptr_cst_p (orig_op0) && null_ptr_cst_p (orig_op1))
 	/* One of the operands must be of nullptr_t type.  */
@@ -5055,7 +5066,7 @@  cp_build_binary_op (const op_location_t &location,
 	  tree delta0;
 	  tree delta1;
 
-	  type = composite_pointer_type (type0, type1, op0, op1, 
+	  type = composite_pointer_type (location, type0, type1, op0, op1, 
 					 CPO_COMPARISON, complain);
 
 	  if (!same_type_p (TREE_TYPE (op0), type))
@@ -5169,7 +5180,8 @@  cp_build_binary_op (const op_location_t &location,
 	   && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
 	shorten = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       break;
 
@@ -5252,7 +5264,8 @@  cp_build_binary_op (const op_location_t &location,
 	       || code1 == ENUMERAL_TYPE))
 	short_compare = 1;
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
-	result_type = composite_pointer_type (type0, type1, op0, op1,
+	result_type = composite_pointer_type (location,
+					      type0, type1, op0, op1,
 					      CPO_COMPARISON, complain);
       else if (code0 == POINTER_TYPE && null_ptr_cst_p (orig_op1))
 	{
@@ -10368,7 +10381,8 @@  lvalue_or_else (tree ref, enum lvalue_use use, tsu
       if (!(complain & tf_error))
 	return 0;
       /* Make this a permerror because we used to accept it.  */
-      permerror (input_location, "using rvalue as lvalue");
+      permerror (cp_expr_loc_or_input_loc (ref),
+		 "using rvalue as lvalue");
     }
   return 1;
 }
Index: testsuite/g++.dg/conversion/ptrmem9.C
===================================================================
--- testsuite/g++.dg/conversion/ptrmem9.C	(revision 277657)
+++ testsuite/g++.dg/conversion/ptrmem9.C	(working copy)
@@ -22,5 +22,5 @@  void f ()
 
   pd == pb;
   pd == pbv;  // { dg-error "" }
-  pd == pc;   // { dg-error "comparison between distinct pointer-to-member types" }
+  pd == pc;   // { dg-error "6:comparison between distinct pointer-to-member types" }
 }
Index: testsuite/g++.dg/cpp0x/rv-lvalue-req.C
===================================================================
--- testsuite/g++.dg/cpp0x/rv-lvalue-req.C	(revision 277657)
+++ testsuite/g++.dg/cpp0x/rv-lvalue-req.C	(working copy)
@@ -5,8 +5,8 @@  template <class T> T&& declval();
 int main()
 {
   &declval<int>();		        // { dg-error "rvalue" }
-  declval<int>() = declval<int>();	// { dg-error "rvalue" }
-  declval<int>()++;			// { dg-error "rvalue" }
-  --declval<int>();			// { dg-error "rvalue" }
+  declval<int>() = declval<int>();	// { dg-error "15:using rvalue as lvalue" }
+  declval<int>()++;			// { dg-error "15:using rvalue as lvalue" }
+  --declval<int>();			// { dg-error "17:using rvalue as lvalue" }
   declval<int>() += 1;			// { dg-error "rvalue" }
 }
Index: testsuite/g++.dg/diagnostic/alignof1.C
===================================================================
--- testsuite/g++.dg/diagnostic/alignof1.C	(nonexistent)
+++ testsuite/g++.dg/diagnostic/alignof1.C	(working copy)
@@ -0,0 +1,5 @@ 
+struct A
+{
+  int foo() { return __alignof(bar); } // { dg-error "32:ISO C\\+\\+ forbids applying .__alignof." }
+  int bar();
+};
Index: testsuite/g++.dg/expr/sizeof1.C
===================================================================
--- testsuite/g++.dg/expr/sizeof1.C	(revision 277657)
+++ testsuite/g++.dg/expr/sizeof1.C	(working copy)
@@ -2,6 +2,6 @@ 
 
 struct A
 {
-  int foo() { return sizeof(bar); } // { dg-error "" }
+  int foo() { return sizeof(bar); } // { dg-error "29:ISO C\\+\\+ forbids applying .sizeof." }
   int bar();
 };
Index: testsuite/g++.dg/warn/Waddress-1.C
===================================================================
--- testsuite/g++.dg/warn/Waddress-1.C	(revision 277657)
+++ testsuite/g++.dg/warn/Waddress-1.C	(working copy)
@@ -15,36 +15,38 @@  double d;
 
 void f()  { if (z) z(); }               // { dg-warning "address" }
 
-void gl() { if (z != 0) z(); }          // { dg-warning "address" }
-void hl() { if (z != (ptrf)0) z(); }    // { dg-warning "address" }
-void il() { if (z != (void*)0) z(); }   // { dg-warning "address|comparison" }
-void jl() { if (&n != (int*)0) z(); }   // { dg-warning "address" }
-void kl() { if (&m != (int*)0) z(); }   // { dg-warning "address" }
-void ll() { if (&s != (T*)0) z(); }     // { dg-warning "address" }
-void ml() { if (&t != (S*)0) z(); }     // { dg-warning "address" }
+void gl() { if (z != 0) z(); }          // { dg-warning "19:address" }
+void hl() { if (z != (ptrf)0) z(); }    // { dg-warning "19:address" }
+void il() { if (z != (void*)0) z(); }   // { dg-warning "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void jl() { if (&n != (int*)0) z(); }   // { dg-warning "20:address" }
+void kl() { if (&m != (int*)0) z(); }   // { dg-warning "20:address" }
+void ll() { if (&s != (T*)0) z(); }     // { dg-warning "20:address" }
+void ml() { if (&t != (S*)0) z(); }     // { dg-warning "20:address" }
 
-void nl() { if (z != (S*)0) z(); }      // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void pl() { if (z != (ptrfn)0) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void ql() { if (&d != (int*)0) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void rl() { if (&s != (U*)0) z(); }     // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
+void nl() { if (z != (S*)0) z(); }      // { dg-error "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void pl() { if (z != (ptrfn)0) z(); }   // { dg-error "19:comparison" }
+// { dg-warning "19:address" "" { target *-*-* } .-1 }
+void ql() { if (&d != (int*)0) z(); }   // { dg-error "20:comparison" }
+// { dg-warning "20:address" "" { target *-*-* } .-1 }
+void rl() { if (&s != (U*)0) z(); }     // { dg-error "20:comparison" }
+// { dg-warning "20:address" "" { target *-*-* } .-1 }
 
-void gr() { if (0 != z) z(); }          // { dg-warning "address" }
-void hr() { if ((ptrf)0 != z) z(); }    // { dg-warning "address" }
-void ir() { if ((void*)0 != z) z(); }   // { dg-warning "address|comparison" }
-void jr() { if ((int*)0 != &n) z(); }   // { dg-warning "address" }
-void kr() { if ((int*)0 != &m) z(); }   // { dg-warning "address" }
-void lr() { if ((T*)0 != &s) z(); }     // { dg-warning "address" }
-void mr() { if ((S*)0 != &t) z(); }     // { dg-warning "address" }
+void gr() { if (0 != z) z(); }          // { dg-warning "19:address" }
+void hr() { if ((ptrf)0 != z) z(); }    // { dg-warning "25:address" }
+void ir() { if ((void*)0 != z) z(); }   // { dg-warning "26:comparison" }
+// { dg-warning "26:address" "" { target *-*-* } .-1 }
+void jr() { if ((int*)0 != &n) z(); }   // { dg-warning "25:address" }
+void kr() { if ((int*)0 != &m) z(); }   // { dg-warning "25:address" }
+void lr() { if ((T*)0 != &s) z(); }     // { dg-warning "23:address" }
+void mr() { if ((S*)0 != &t) z(); }     // { dg-warning "23:address" }
 
-void nr() { if ((S*)0 != z) z(); }      // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void pr() { if ((ptrfn)0 != z) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void qr() { if ((int*)0 != &d) z(); }   // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
-void rr() { if ((U*)0 != &s) z(); }     // { dg-error "comparison" }
-// { dg-warning "address" "" { target *-*-* } .-1 }
+void nr() { if ((S*)0 != z) z(); }      // { dg-error "23:comparison" }
+// { dg-warning "23:address" "" { target *-*-* } .-1 }
+void pr() { if ((ptrfn)0 != z) z(); }   // { dg-error "26:comparison" }
+// { dg-warning "26:address" "" { target *-*-* } .-1 }
+void qr() { if ((int*)0 != &d) z(); }   // { dg-error "25:comparison" }
+// { dg-warning "25:address" "" { target *-*-* } .-1 }
+void rr() { if ((U*)0 != &s) z(); }     // { dg-error "23:comparison" }
+// { dg-warning "23:address" "" { target *-*-* } .-1 }
Index: testsuite/g++.old-deja/g++.jason/rfg20.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/rfg20.C	(revision 277657)
+++ testsuite/g++.old-deja/g++.jason/rfg20.C	(working copy)
@@ -6,5 +6,5 @@  void *vp;
 
 void example ()
 {
-    vp != fp;			// { dg-error "forbids comparison" } no conversion from pfn to void*
+    vp != fp;			// { dg-error "8:ISO C\\+\\+ forbids comparison" } no conversion from pfn to void*
 }
Index: testsuite/g++.old-deja/g++.law/typeck1.C
===================================================================
--- testsuite/g++.old-deja/g++.law/typeck1.C	(revision 277657)
+++ testsuite/g++.old-deja/g++.law/typeck1.C	(working copy)
@@ -13,6 +13,6 @@ 
 
         int test( const foo* f, const bar* b )
                 {
-                return f == b;// { dg-error "comparison between distinct pointer types" } 
+                return f == b;// { dg-error "26:comparison between distinct pointer types" } 
                 }
 
Index: testsuite/g++.old-deja/g++.rfg/00321_01-.C
===================================================================
--- testsuite/g++.old-deja/g++.rfg/00321_01-.C	(revision 277657)
+++ testsuite/g++.old-deja/g++.rfg/00321_01-.C	(working copy)
@@ -9,6 +9,6 @@  int (*p2)[5];
 void
 test ()
 {
-  p1 == p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
-  p1 > p2;		// { dg-error "comparison between distinct pointer types" } comparison.*
+  p1 == p2;		// { dg-error "6:comparison between distinct pointer types" } comparison.*
+  p1 > p2;		// { dg-error "6:comparison between distinct pointer types" } comparison.*
 }