Message ID | 4d09ce98-58b8-1506-0dc5-2f7ff20241b1@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++] A few more cp_expr_loc_or_input_loc and a diagnostic regression fix | expand |
On 11/29/19 8:08 AM, Paolo Carlini wrote: > Hi, > > a few more rather straightforward uses for cp_expr_loc_or_input_loc. > > Additionally, while working on the latter, I noticed that, compared to > say, gcc-7, lately the code we have in cp_build_addr_expr_1 to diagnose > taking the address of 'main' often doesn't work anymore, when the > argument is wrapped in a location_wrapper. The below fixes that by using > tree_strip_any_location_wrapper in the DECL_MAIN_P check, which works > fine, but I can imagine various other ways to solve the issue... Maybe location_t loc = cp_expr_loc_or_input_loc (arg); STRIP_ANY_LOCATION_WRAPPER (arg); at the top? In general I prefer the local variable to writing cp_expr_loc_or_input_loc in lots of places, whether or not we then strip wrappers. Jason
Hi, On 02/12/19 19:58, Jason Merrill wrote: > On 11/29/19 8:08 AM, Paolo Carlini wrote: >> Hi, >> >> a few more rather straightforward uses for cp_expr_loc_or_input_loc. >> >> Additionally, while working on the latter, I noticed that, compared >> to say, gcc-7, lately the code we have in cp_build_addr_expr_1 to >> diagnose taking the address of 'main' often doesn't work anymore, >> when the argument is wrapped in a location_wrapper. The below fixes >> that by using tree_strip_any_location_wrapper in the DECL_MAIN_P >> check, which works fine, but I can imagine various other ways to >> solve the issue... > > Maybe > > location_t loc = cp_expr_loc_or_input_loc (arg); > STRIP_ANY_LOCATION_WRAPPER (arg); > > at the top? In general I prefer the local variable to writing > cp_expr_loc_or_input_loc in lots of places, whether or not we then > strip wrappers. Sure. In a few circumstances I hesitated because cp_expr_loc_or_input_loc isn't really trivial, boils down to quite a few conditionals, and adds a bit to the complexity of simple functions when in fact no errors nor warnings are issued. But certainly calling it at the top is often much cleaner. I changed both the functions. However, using STRIP_ANY_LOCATION_WRAPPER at the beginning of cp_build_addr_expr_1 doesn't seem straightforward, causes a few regressions (wrong location for conversion/Wwrite-strings.C; even an ICE for cpp1z/constexpr-lambda23.C; cpp1z/decomp48.C). The function doesn't seem trivial from this point of view, there is already a localized tree_strip_any_location_wrapper near the end, for processing_template_decl. I would rather further investigate that kind of simplification in a separate patch, beyond the regression fix. (before I would like to improve the locations for all the various kinds of cast, quite a few changes) Thanks, Paolo. /////////////////////// Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 278911) +++ cp/typeck.c (working copy) @@ -6061,6 +6061,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue { tree argtype; tree val; + location_t loc; if (!arg || error_operand_p (arg)) return error_mark_node; @@ -6070,6 +6071,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue return error_mark_node; argtype = lvalue_type (arg); + loc = cp_expr_loc_or_input_loc (arg); gcc_assert (!(identifier_p (arg) && IDENTIFIER_ANY_OP_P (arg))); @@ -6103,12 +6105,14 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue else if (current_class_type && TREE_OPERAND (arg, 0) == current_class_ref) /* An expression like &memfn. */ - permerror (input_location, "ISO C++ forbids taking the address of an unqualified" + permerror (loc, + "ISO C++ forbids taking the address of an unqualified" " or parenthesized non-static member function to form" " a pointer to member function. Say %<&%T::%D%>", base, name); else - permerror (input_location, "ISO C++ forbids taking the address of a bound member" + permerror (loc, + "ISO C++ forbids taking the address of a bound member" " function to form a pointer to member function." " Say %<&%T::%D%>", base, name); @@ -6135,7 +6139,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue if (kind == clk_none) { if (complain & tf_error) - lvalue_error (cp_expr_loc_or_input_loc (arg), lv_addressof); + lvalue_error (loc, lv_addressof); return error_mark_node; } if (strict_lvalue && (kind & (clk_rvalueref|clk_class))) @@ -6143,8 +6147,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue if (!(complain & tf_error)) return error_mark_node; /* Make this a permerror because we used to accept it. */ - permerror (cp_expr_loc_or_input_loc (arg), - "taking address of rvalue"); + permerror (loc, "taking address of rvalue"); } } @@ -6154,13 +6157,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue arg = build1 (CONVERT_EXPR, type, arg); return arg; } - else if (pedantic && DECL_MAIN_P (arg)) + else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg))) { /* ARM $3.4 */ /* Apparently a lot of autoconf scripts for C++ packages do this, so only complain if -Wpedantic. */ if (complain & (flag_pedantic_errors ? tf_error : tf_warning)) - pedwarn (input_location, OPT_Wpedantic, + pedwarn (loc, OPT_Wpedantic, "ISO C++ forbids taking address of function %<::main%>"); else if (flag_pedantic_errors) return error_mark_node; @@ -6218,7 +6221,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue if (TYPE_REF_P (TREE_TYPE (t))) { if (complain & tf_error) - error ("cannot create pointer to reference member %qD", t); + error_at (loc, + "cannot create pointer to reference member %qD", t); return error_mark_node; } @@ -6238,8 +6242,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue if (bitfield_p (arg)) { if (complain & tf_error) - error_at (cp_expr_loc_or_input_loc (arg), - "attempt to take address of bit-field"); + error_at (loc, "attempt to take address of bit-field"); return error_mark_node; } @@ -6254,8 +6257,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))) { if (complain & tf_error) - error ("taking address of an immediate function %qD", - stripped_arg); + error_at (loc, "taking address of an immediate function %qD", + stripped_arg); return error_mark_node; } if (TREE_CODE (stripped_arg) == FUNCTION_DECL @@ -9676,6 +9679,7 @@ check_return_expr (tree retval, bool *no_warning) the declared type is incomplete. */ tree functype; int fn_returns_value_p; + location_t loc = cp_expr_loc_or_input_loc (retval); *no_warning = false; @@ -9689,7 +9693,7 @@ check_return_expr (tree retval, bool *no_warning) if (DECL_DESTRUCTOR_P (current_function_decl)) { if (retval) - error ("returning a value from a destructor"); + error_at (loc, "returning a value from a destructor"); return NULL_TREE; } else if (DECL_CONSTRUCTOR_P (current_function_decl)) @@ -9700,7 +9704,7 @@ check_return_expr (tree retval, bool *no_warning) error ("cannot return from a handler of a function-try-block of a constructor"); else if (retval) /* You can't return a value from a constructor. */ - error ("returning a value from a constructor"); + error_at (loc, "returning a value from a constructor"); return NULL_TREE; } @@ -9762,11 +9766,11 @@ check_return_expr (tree retval, bool *no_warning) else if (!same_type_p (type, functype)) { if (LAMBDA_FUNCTION_P (current_function_decl)) - error ("inconsistent types %qT and %qT deduced for " - "lambda return type", functype, type); + error_at (loc, "inconsistent types %qT and %qT deduced for " + "lambda return type", functype, type); else - error ("inconsistent deduction for auto return type: " - "%qT and then %qT", functype, type); + error_at (loc, "inconsistent deduction for auto return type: " + "%qT and then %qT", functype, type); } functype = type; } @@ -9800,8 +9804,7 @@ check_return_expr (tree retval, bool *no_warning) its side-effects. */ finish_expr_stmt (retval); else if (retval != error_mark_node) - permerror (input_location, - "return-statement with a value, in function " + permerror (loc, "return-statement with a value, in function " "returning %qT", valtype); current_function_returns_null = 1; @@ -9857,7 +9860,8 @@ check_return_expr (tree retval, bool *no_warning) } if (warn) - warning (OPT_Weffc__, "%<operator=%> should return a reference to %<*this%>"); + warning_at (loc, OPT_Weffc__, + "%<operator=%> should return a reference to %<*this%>"); } if (dependent_type_p (functype) Index: testsuite/g++.dg/cpp0x/decltype3.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype3.C (revision 278911) +++ testsuite/g++.dg/cpp0x/decltype3.C (working copy) @@ -54,7 +54,7 @@ class B { }; CHECK_DECLTYPE(decltype(aa.*&A::a), int&); -decltype(aa.*&A::b) zz; // { dg-error "cannot create pointer to reference member" "cannot" } +decltype(aa.*&A::b) zz; // { dg-error "18:cannot create pointer to reference member" "cannot" } CHECK_DECLTYPE(decltype(caa.*&A::a), const int&); Index: testsuite/g++.dg/cpp0x/decltype4.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype4.C (revision 278911) +++ testsuite/g++.dg/cpp0x/decltype4.C (working copy) @@ -23,7 +23,7 @@ struct A { }; CHECK_DECLTYPE(decltype(&A::x), int A::*); -decltype(&A::y) Ay; // { dg-error "cannot create pointer to reference member|invalid type" } +decltype(&A::y) Ay; // { dg-error "14:cannot create pointer to reference member|invalid type" } CHECK_DECLTYPE(decltype(&A::foo), int (A::*) (char)); CHECK_DECLTYPE(decltype(&A::bar), int& (A::*) () const); Index: testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C =================================================================== --- testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C (revision 278911) +++ testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C (working copy) @@ -11,7 +11,7 @@ template <class T> int f (T t) { if (b) return t.fn1(); else - return t.fn2(); // { dg-error "inconsistent types" } + return t.fn2(); // { dg-error "19:inconsistent types" } }(t); } Index: testsuite/g++.dg/cpp2a/consteval13.C =================================================================== --- testsuite/g++.dg/cpp2a/consteval13.C (revision 278911) +++ testsuite/g++.dg/cpp2a/consteval13.C (working copy) @@ -10,8 +10,8 @@ void foo () { auto qux = [] (fnptr a = quux ()) consteval { return a (); }; - constexpr auto c = qux (baz); // { dg-error "taking address of an immediate function" } - constexpr auto d = qux (bar); // { dg-error "taking address of an immediate function" } + constexpr auto c = qux (baz); // { dg-error "28:taking address of an immediate function" } + constexpr auto d = qux (bar); // { dg-error "28:taking address of an immediate function" } static_assert (c == 1); static_assert (d == 42); } Index: testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C =================================================================== --- testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C (working copy) @@ -0,0 +1,10 @@ +// { dg-do compile { target c++14 } } + +void foo(); + +auto bar(bool b) +{ + if (b) + return 0; + return foo(); // { dg-error "13:inconsistent deduction for auto return type: .int. and then .void." } +} Index: testsuite/g++.dg/diagnostic/main2.C =================================================================== --- testsuite/g++.dg/diagnostic/main2.C (nonexistent) +++ testsuite/g++.dg/diagnostic/main2.C (working copy) @@ -0,0 +1,12 @@ +int main (); + +typedef int (*fptr) (); + +void foo (fptr); + +fptr bar () +{ + foo (main); // { dg-error "8:ISO C\\+\\+ forbids taking address of function" } + + return main; // { dg-error "10:ISO C\\+\\+ forbids taking address of function" } +} Index: testsuite/g++.dg/diagnostic/returning-a-value-1.C =================================================================== --- testsuite/g++.dg/diagnostic/returning-a-value-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/returning-a-value-1.C (working copy) @@ -0,0 +1,8 @@ +int foo(); + +struct A +{ + A() { return foo(); } // { dg-error "19:returning a value" } + ~A() { return foo(); } // { dg-error "20:returning a value" } + void bar() { return foo(); } // { dg-error "26:return-statement with a value" } +}; Index: testsuite/g++.dg/expr/pmf-1.C =================================================================== --- testsuite/g++.dg/expr/pmf-1.C (revision 278911) +++ testsuite/g++.dg/expr/pmf-1.C (working copy) @@ -13,7 +13,7 @@ struct A void h() { void (A::*p)() = &A::f; - void (A::*q)() = &(A::f); // { dg-error "parenthesized" } + void (A::*q)() = &(A::f); // { dg-error "27:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized" } foo(&g<int>); // { dg-error "cannot convert" } } }; Index: testsuite/g++.dg/other/ptrmem2.C =================================================================== --- testsuite/g++.dg/other/ptrmem2.C (revision 278911) +++ testsuite/g++.dg/other/ptrmem2.C (working copy) @@ -19,7 +19,7 @@ template<class T> int f2(T x); int D::Foo () { - f1( &D::m); // { dg-error "cannot create pointer to ref" } + f1( &D::m); // { dg-error "11:cannot create pointer to ref" } f1( &(D::m)); // ok f2( &D::s); // ok f2( &(D::s)); // ok @@ -28,7 +28,7 @@ int D::Foo () int Foo () { - f1( &D::m); // { dg-error "cannot create pointer to ref" } + f1( &D::m); // { dg-error "11:cannot create pointer to ref" } f1( &(D::m)); // { dg-error "non-static" } f2( &D::s); // ok f2( &(D::s)); // ok Index: testsuite/g++.dg/template/ptrmem17.C =================================================================== --- testsuite/g++.dg/template/ptrmem17.C (revision 278911) +++ testsuite/g++.dg/template/ptrmem17.C (working copy) @@ -4,7 +4,7 @@ template<int> struct A { int& i; A(); - ~A() { &A::i; } // { dg-error "reference" } + ~A() { &A::i; } // { dg-error "14:cannot create pointer to reference" } }; A<0> a; Index: testsuite/g++.old-deja/g++.bugs/900213_03.C =================================================================== --- testsuite/g++.old-deja/g++.bugs/900213_03.C (revision 278911) +++ testsuite/g++.old-deja/g++.bugs/900213_03.C (working copy) @@ -21,7 +21,7 @@ struct0 *ptr; void global_function_0 () { - fmp = &ptr->function_member; // { dg-error "" } + fmp = &ptr->function_member; // { dg-error "15:ISO C\\+\\+ forbids taking the address of a bound member function" } //dmp = &ptr->data_member; // caught by g++, missed by cfront } Index: testsuite/g++.old-deja/g++.other/pmf7.C =================================================================== --- testsuite/g++.old-deja/g++.other/pmf7.C (revision 278911) +++ testsuite/g++.old-deja/g++.other/pmf7.C (working copy) @@ -12,5 +12,5 @@ int main () { A a; &a.f; // { dg-error "" } overloaded - &a.g; // { dg-error "" } can't write a pmf like this + &a.g; // { dg-error "6:ISO C\\+\\+ forbids taking the address of a bound member function" } can't write a pmf like this } Index: testsuite/g++.old-deja/g++.other/ptrmem7.C =================================================================== --- testsuite/g++.old-deja/g++.other/ptrmem7.C (revision 278911) +++ testsuite/g++.old-deja/g++.other/ptrmem7.C (working copy) @@ -36,7 +36,7 @@ void A::foo () int (A::*ptr14) (int) = single; // { dg-error "cannot convert" } int (A::*ptr20) (int) = &(A::ns); // { dg-error "pointer to member" } - int (A::*ptr21) (int) = &(A::single); // { dg-error "pointer to member" } + int (A::*ptr21) (int) = &(A::single); // { dg-error "32:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member" } int (*ptr31) (short) = &A::sole; int (*ptr32) (short) = A::sole;
On 12/2/19 5:22 PM, Paolo Carlini wrote: > Hi, > > On 02/12/19 19:58, Jason Merrill wrote: >> On 11/29/19 8:08 AM, Paolo Carlini wrote: >>> Hi, >>> >>> a few more rather straightforward uses for cp_expr_loc_or_input_loc. >>> >>> Additionally, while working on the latter, I noticed that, compared >>> to say, gcc-7, lately the code we have in cp_build_addr_expr_1 to >>> diagnose taking the address of 'main' often doesn't work anymore, >>> when the argument is wrapped in a location_wrapper. The below fixes >>> that by using tree_strip_any_location_wrapper in the DECL_MAIN_P >>> check, which works fine, but I can imagine various other ways to >>> solve the issue... >> >> Maybe >> >> location_t loc = cp_expr_loc_or_input_loc (arg); >> STRIP_ANY_LOCATION_WRAPPER (arg); >> >> at the top? In general I prefer the local variable to writing >> cp_expr_loc_or_input_loc in lots of places, whether or not we then >> strip wrappers. > > Sure. In a few circumstances I hesitated because > cp_expr_loc_or_input_loc isn't really trivial, boils down to quite a few > conditionals, and adds a bit to the complexity of simple functions when > in fact no errors nor warnings are issued. But certainly calling it at > the top is often much cleaner. I changed both the functions. > > However, using STRIP_ANY_LOCATION_WRAPPER at the beginning of > cp_build_addr_expr_1 doesn't seem straightforward, causes a few > regressions (wrong location for conversion/Wwrite-strings.C; even an ICE > for cpp1z/constexpr-lambda23.C; cpp1z/decomp48.C). The function doesn't > seem trivial from this point of view, there is already a localized > tree_strip_any_location_wrapper near the end, for > processing_template_decl. I would rather further investigate that kind > of simplification in a separate patch, beyond the regression fix. > (before I would like to improve the locations for all the various kinds > of cast, quite a few changes) Absolutely, if it isn't simple don't bother. > @@ -6061,6 +6061,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue > { > tree argtype; > tree val; > + location_t loc; > > if (!arg || error_operand_p (arg)) > return error_mark_node; > @@ -6070,6 +6071,7 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue > return error_mark_node; > > argtype = lvalue_type (arg); > + loc = cp_expr_loc_or_input_loc (arg); You don't need to separately declare the variable at the top of the function anymore. OK with that change. Jason
Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 278834) +++ cp/typeck.c (working copy) @@ -6103,12 +6103,14 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue else if (current_class_type && TREE_OPERAND (arg, 0) == current_class_ref) /* An expression like &memfn. */ - permerror (input_location, "ISO C++ forbids taking the address of an unqualified" + permerror (cp_expr_loc_or_input_loc (arg), + "ISO C++ forbids taking the address of an unqualified" " or parenthesized non-static member function to form" " a pointer to member function. Say %<&%T::%D%>", base, name); else - permerror (input_location, "ISO C++ forbids taking the address of a bound member" + permerror (cp_expr_loc_or_input_loc (arg), + "ISO C++ forbids taking the address of a bound member" " function to form a pointer to member function." " Say %<&%T::%D%>", base, name); @@ -6154,13 +6156,13 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue arg = build1 (CONVERT_EXPR, type, arg); return arg; } - else if (pedantic && DECL_MAIN_P (arg)) + else if (pedantic && DECL_MAIN_P (tree_strip_any_location_wrapper (arg))) { /* ARM $3.4 */ /* Apparently a lot of autoconf scripts for C++ packages do this, so only complain if -Wpedantic. */ if (complain & (flag_pedantic_errors ? tf_error : tf_warning)) - pedwarn (input_location, OPT_Wpedantic, + pedwarn (cp_expr_loc_or_input_loc (arg), OPT_Wpedantic, "ISO C++ forbids taking address of function %<::main%>"); else if (flag_pedantic_errors) return error_mark_node; @@ -6218,7 +6220,8 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue if (TYPE_REF_P (TREE_TYPE (t))) { if (complain & tf_error) - error ("cannot create pointer to reference member %qD", t); + error_at (cp_expr_loc_or_input_loc (arg), + "cannot create pointer to reference member %qD", t); return error_mark_node; } @@ -6254,8 +6257,9 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue || !DECL_IMMEDIATE_FUNCTION_P (current_function_decl))) { if (complain & tf_error) - error ("taking address of an immediate function %qD", - stripped_arg); + error_at (cp_expr_loc_or_input_loc (arg), + "taking address of an immediate function %qD", + stripped_arg); return error_mark_node; } if (TREE_CODE (stripped_arg) == FUNCTION_DECL @@ -9689,7 +9693,8 @@ check_return_expr (tree retval, bool *no_warning) if (DECL_DESTRUCTOR_P (current_function_decl)) { if (retval) - error ("returning a value from a destructor"); + error_at (cp_expr_loc_or_input_loc (retval), + "returning a value from a destructor"); return NULL_TREE; } else if (DECL_CONSTRUCTOR_P (current_function_decl)) @@ -9700,7 +9705,8 @@ check_return_expr (tree retval, bool *no_warning) error ("cannot return from a handler of a function-try-block of a constructor"); else if (retval) /* You can't return a value from a constructor. */ - error ("returning a value from a constructor"); + error_at (cp_expr_loc_or_input_loc (retval), + "returning a value from a constructor"); return NULL_TREE; } @@ -9762,11 +9768,13 @@ check_return_expr (tree retval, bool *no_warning) else if (!same_type_p (type, functype)) { if (LAMBDA_FUNCTION_P (current_function_decl)) - error ("inconsistent types %qT and %qT deduced for " - "lambda return type", functype, type); + error_at (cp_expr_loc_or_input_loc (retval), + "inconsistent types %qT and %qT deduced for " + "lambda return type", functype, type); else - error ("inconsistent deduction for auto return type: " - "%qT and then %qT", functype, type); + error_at (cp_expr_loc_or_input_loc (retval), + "inconsistent deduction for auto return type: " + "%qT and then %qT", functype, type); } functype = type; } @@ -9800,7 +9808,7 @@ check_return_expr (tree retval, bool *no_warning) its side-effects. */ finish_expr_stmt (retval); else if (retval != error_mark_node) - permerror (input_location, + permerror (cp_expr_loc_or_input_loc (retval), "return-statement with a value, in function " "returning %qT", valtype); current_function_returns_null = 1; Index: testsuite/g++.dg/cpp0x/decltype3.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype3.C (revision 278834) +++ testsuite/g++.dg/cpp0x/decltype3.C (working copy) @@ -54,7 +54,7 @@ class B { }; CHECK_DECLTYPE(decltype(aa.*&A::a), int&); -decltype(aa.*&A::b) zz; // { dg-error "cannot create pointer to reference member" "cannot" } +decltype(aa.*&A::b) zz; // { dg-error "18:cannot create pointer to reference member" "cannot" } CHECK_DECLTYPE(decltype(caa.*&A::a), const int&); Index: testsuite/g++.dg/cpp0x/decltype4.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype4.C (revision 278834) +++ testsuite/g++.dg/cpp0x/decltype4.C (working copy) @@ -23,7 +23,7 @@ struct A { }; CHECK_DECLTYPE(decltype(&A::x), int A::*); -decltype(&A::y) Ay; // { dg-error "cannot create pointer to reference member|invalid type" } +decltype(&A::y) Ay; // { dg-error "14:cannot create pointer to reference member|invalid type" } CHECK_DECLTYPE(decltype(&A::foo), int (A::*) (char)); CHECK_DECLTYPE(decltype(&A::bar), int& (A::*) () const); Index: testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C =================================================================== --- testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C (revision 278834) +++ testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext-neg.C (working copy) @@ -11,7 +11,7 @@ template <class T> int f (T t) { if (b) return t.fn1(); else - return t.fn2(); // { dg-error "inconsistent types" } + return t.fn2(); // { dg-error "19:inconsistent types" } }(t); } Index: testsuite/g++.dg/cpp2a/consteval13.C =================================================================== --- testsuite/g++.dg/cpp2a/consteval13.C (revision 278834) +++ testsuite/g++.dg/cpp2a/consteval13.C (working copy) @@ -10,8 +10,8 @@ void foo () { auto qux = [] (fnptr a = quux ()) consteval { return a (); }; - constexpr auto c = qux (baz); // { dg-error "taking address of an immediate function" } - constexpr auto d = qux (bar); // { dg-error "taking address of an immediate function" } + constexpr auto c = qux (baz); // { dg-error "28:taking address of an immediate function" } + constexpr auto d = qux (bar); // { dg-error "28:taking address of an immediate function" } static_assert (c == 1); static_assert (d == 42); } Index: testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C =================================================================== --- testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/inconsistent-deduction-1.C (working copy) @@ -0,0 +1,9 @@ +// { dg-do compile { target c++14 } } + +void foo(); +auto bar(bool b) +{ + if (b) + return 0; + return foo(); // { dg-error "13:inconsistent deduction for auto return type: .int. and then .void." } +} Index: testsuite/g++.dg/diagnostic/main2.C =================================================================== --- testsuite/g++.dg/diagnostic/main2.C (nonexistent) +++ testsuite/g++.dg/diagnostic/main2.C (working copy) @@ -0,0 +1,8 @@ +int main (); + +void foo (int (*) ()); + +void bar () +{ + foo (main); // { dg-error "8:ISO C\\+\\+ forbids taking address of function" } +} Index: testsuite/g++.dg/diagnostic/returning-a-value-1.C =================================================================== --- testsuite/g++.dg/diagnostic/returning-a-value-1.C (nonexistent) +++ testsuite/g++.dg/diagnostic/returning-a-value-1.C (working copy) @@ -0,0 +1,8 @@ +int foo(); + +struct A +{ + A() { return foo(); } // { dg-error "19:returning a value" } + ~A() { return foo(); } // { dg-error "20:returning a value" } + void bar() { return foo(); } // { dg-error "26:return-statement with a value" } +}; Index: testsuite/g++.dg/expr/pmf-1.C =================================================================== --- testsuite/g++.dg/expr/pmf-1.C (revision 278834) +++ testsuite/g++.dg/expr/pmf-1.C (working copy) @@ -13,7 +13,7 @@ struct A void h() { void (A::*p)() = &A::f; - void (A::*q)() = &(A::f); // { dg-error "parenthesized" } + void (A::*q)() = &(A::f); // { dg-error "27:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized" } foo(&g<int>); // { dg-error "cannot convert" } } }; Index: testsuite/g++.dg/other/ptrmem2.C =================================================================== --- testsuite/g++.dg/other/ptrmem2.C (revision 278834) +++ testsuite/g++.dg/other/ptrmem2.C (working copy) @@ -19,7 +19,7 @@ template<class T> int f2(T x); int D::Foo () { - f1( &D::m); // { dg-error "cannot create pointer to ref" } + f1( &D::m); // { dg-error "11:cannot create pointer to ref" } f1( &(D::m)); // ok f2( &D::s); // ok f2( &(D::s)); // ok @@ -28,7 +28,7 @@ int D::Foo () int Foo () { - f1( &D::m); // { dg-error "cannot create pointer to ref" } + f1( &D::m); // { dg-error "11:cannot create pointer to ref" } f1( &(D::m)); // { dg-error "non-static" } f2( &D::s); // ok f2( &(D::s)); // ok Index: testsuite/g++.dg/template/ptrmem17.C =================================================================== --- testsuite/g++.dg/template/ptrmem17.C (revision 278834) +++ testsuite/g++.dg/template/ptrmem17.C (working copy) @@ -4,7 +4,7 @@ template<int> struct A { int& i; A(); - ~A() { &A::i; } // { dg-error "reference" } + ~A() { &A::i; } // { dg-error "14:cannot create pointer to reference" } }; A<0> a; Index: testsuite/g++.old-deja/g++.bugs/900213_03.C =================================================================== --- testsuite/g++.old-deja/g++.bugs/900213_03.C (revision 278834) +++ testsuite/g++.old-deja/g++.bugs/900213_03.C (working copy) @@ -21,7 +21,7 @@ struct0 *ptr; void global_function_0 () { - fmp = &ptr->function_member; // { dg-error "" } + fmp = &ptr->function_member; // { dg-error "15:ISO C\\+\\+ forbids taking the address of a bound member function" } //dmp = &ptr->data_member; // caught by g++, missed by cfront } Index: testsuite/g++.old-deja/g++.other/pmf7.C =================================================================== --- testsuite/g++.old-deja/g++.other/pmf7.C (revision 278834) +++ testsuite/g++.old-deja/g++.other/pmf7.C (working copy) @@ -12,5 +12,5 @@ int main () { A a; &a.f; // { dg-error "" } overloaded - &a.g; // { dg-error "" } can't write a pmf like this + &a.g; // { dg-error "6:ISO C\\+\\+ forbids taking the address of a bound member function" } can't write a pmf like this } Index: testsuite/g++.old-deja/g++.other/ptrmem7.C =================================================================== --- testsuite/g++.old-deja/g++.other/ptrmem7.C (revision 278834) +++ testsuite/g++.old-deja/g++.other/ptrmem7.C (working copy) @@ -36,7 +36,7 @@ void A::foo () int (A::*ptr14) (int) = single; // { dg-error "cannot convert" } int (A::*ptr20) (int) = &(A::ns); // { dg-error "pointer to member" } - int (A::*ptr21) (int) = &(A::single); // { dg-error "pointer to member" } + int (A::*ptr21) (int) = &(A::single); // { dg-error "32:ISO C\\+\\+ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member" } int (*ptr31) (short) = &A::sole; int (*ptr32) (short) = A::sole;