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.carl...@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.carl...@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.
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.*
}