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 | expand |
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" } }
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.
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.* }