From be54637ac82d820f62ad51e876146e5df86aded9 Mon Sep 17 00:00:00 2001 From: paolo Date: Mon, 11 Jun 2018 21:13:19 +0000 Subject: [PATCH] /cp 2018-06-11 Paolo Carlini * decl.c (grok_op_properties): Consistently use the location of the decl; remove special casing of POSTINCREMENT_EXPR and POSTDECREMENT_EXPR wrt default arguments. /testsuite 2018-06-11 Paolo Carlini * g++.dg/lookup/new2.C: Test locations too. * g++.dg/other/ellipsis1.C: Likewise. * g++.dg/other/operator1.C: Likewise. * g++.dg/other/operator2.C: Likewise. * g++.dg/overload/operator2.C: Likewise. * g++.dg/parse/defarg11.C: Likewise. * g++.dg/parse/operator4.C: Likewise. * g++.dg/template/error30.C: Likewise. * g++.dg/template/explicit-args3.C: Likewise. * g++.dg/warn/effc1.C: Likewise. * g++.old-deja/g++.brendan/prepost2.C: Likewise. * g++.old-deja/g++.brendan/prepost3.C: Likewise. * g++.old-deja/g++.bugs/900215_01.C: Likewise. * g++.old-deja/g++.jason/conversion5.C: Likewise. * g++.old-deja/g++.jason/operator.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@261455 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 ++ gcc/cp/decl.c | 111 +++++++++++---------- gcc/testsuite/g++.dg/lookup/new2.C | 4 +- gcc/testsuite/g++.dg/other/ellipsis1.C | 24 ++--- gcc/testsuite/g++.dg/other/operator1.C | 2 +- gcc/testsuite/g++.dg/other/operator2.C | 2 +- gcc/testsuite/g++.dg/overload/operator2.C | 28 +++--- gcc/testsuite/g++.dg/parse/defarg11.C | 18 ++-- gcc/testsuite/g++.dg/parse/operator4.C | 2 +- gcc/testsuite/g++.dg/template/error30.C | 2 +- gcc/testsuite/g++.dg/template/explicit-args3.C | 2 +- gcc/testsuite/g++.dg/warn/effc1.C | 2 +- gcc/testsuite/g++.old-deja/g++.brendan/prepost2.C | 9 +- gcc/testsuite/g++.old-deja/g++.brendan/prepost3.C | 2 +- gcc/testsuite/g++.old-deja/g++.bugs/900215_01.C | 2 +- gcc/testsuite/g++.old-deja/g++.jason/conversion5.C | 2 +- gcc/testsuite/g++.old-deja/g++.jason/operator.C | 14 +-- 17 files changed, 121 insertions(+), 111 deletions(-) rewrite gcc/testsuite/g++.dg/other/ellipsis1.C (78%) rewrite gcc/testsuite/g++.dg/overload/operator2.C (72%) rewrite gcc/testsuite/g++.dg/parse/defarg11.C (72%) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4c7041b6cc4..9458b4150a8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-06-11 Paolo Carlini + + * decl.c (grok_op_properties): Consistently use the location + of the decl; remove special casing of POSTINCREMENT_EXPR and + POSTDECREMENT_EXPR wrt default arguments. + 2018-06-05 Jason Merrill * constexpr.c (cxx_eval_binary_expression): Special case comparison diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 688ba4a1442..c8353405a1a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13078,6 +13078,7 @@ grok_op_properties (tree decl, bool complain) tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE; tree name = DECL_NAME (decl); + location_t loc = DECL_SOURCE_LOCATION (decl); tree class_type = DECL_CONTEXT (decl); if (class_type && !CLASS_TYPE_P (class_type)) @@ -13139,13 +13140,14 @@ grok_op_properties (tree decl, bool complain) { if (CP_DECL_CONTEXT (decl) != global_namespace) { - error ("%qD may not be declared within a namespace", decl); + error_at (loc, "%qD may not be declared within a namespace", + decl); return false; } if (!TREE_PUBLIC (decl)) { - error ("%qD may not be declared as static", decl); + error_at (loc, "%qD may not be declared as static", decl); return false; } } @@ -13172,14 +13174,14 @@ grok_op_properties (tree decl, bool complain) || operator_code == ARRAY_REF || operator_code == NOP_EXPR) { - error ("%qD must be a nonstatic member function", decl); + error_at (loc, "%qD must be a nonstatic member function", decl); return false; } if (DECL_STATIC_FUNCTION_P (decl)) { - error ("%qD must be either a non-static member " - "function or a non-member function", decl); + error_at (loc, "%qD must be either a non-static member " + "function or a non-member function", decl); return false; } @@ -13188,8 +13190,8 @@ grok_op_properties (tree decl, bool complain) if (!arg || arg == void_list_node) { if (complain) - error ("%qD must have an argument of class or " - "enumerated type", decl); + error_at(loc, "%qD must have an argument of class or " + "enumerated type", decl); return false; } @@ -13214,7 +13216,7 @@ grok_op_properties (tree decl, bool complain) if (operator_code == COND_EXPR) { /* 13.4.0.3 */ - error ("ISO C++ prohibits overloading operator ?:"); + error_at (loc, "ISO C++ prohibits overloading operator ?:"); return false; } @@ -13225,7 +13227,8 @@ grok_op_properties (tree decl, bool complain) if (!arg) { /* Variadic. */ - error ("%qD must not have variable number of arguments", decl); + error_at (loc, "%qD must not have variable number of arguments", + decl); return false; } ++arity; @@ -13248,9 +13251,10 @@ grok_op_properties (tree decl, bool complain) else if (arity != 2) { /* This was an ambiguous operator but is invalid. */ - error (methodp - ? G_("%qD must have either zero or one argument") - : G_("%qD must have either one or two arguments"), decl); + error_at (loc, + methodp + ? G_("%qD must have either zero or one argument") + : G_("%qD must have either one or two arguments"), decl); return false; } else if ((operator_code == POSTINCREMENT_EXPR @@ -13260,10 +13264,11 @@ grok_op_properties (tree decl, bool complain) && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node)) { - error (methodp - ? G_("postfix %qD must have % as its argument") - : G_("postfix %qD must have % as its second argument"), - decl); + error_at (loc, + methodp + ? G_("postfix %qD must have % as its argument") + : G_("postfix %qD must have % as its second argument"), + decl); return false; } break; @@ -13271,9 +13276,10 @@ grok_op_properties (tree decl, bool complain) case OVL_OP_FLAG_UNARY: if (arity != 1) { - error (methodp - ? G_("%qD must have no arguments") - : G_("%qD must have exactly one argument"), decl); + error_at (loc, + methodp + ? G_("%qD must have no arguments") + : G_("%qD must have exactly one argument"), decl); return false; } break; @@ -13281,9 +13287,10 @@ grok_op_properties (tree decl, bool complain) case OVL_OP_FLAG_BINARY: if (arity != 2) { - error (methodp - ? G_("%qD must have exactly one argument") - : G_("%qD must have exactly two arguments"), decl); + error_at (loc, + methodp + ? G_("%qD must have exactly one argument") + : G_("%qD must have exactly two arguments"), decl); return false; } break; @@ -13297,15 +13304,8 @@ grok_op_properties (tree decl, bool complain) if (TREE_PURPOSE (arg)) { TREE_PURPOSE (arg) = NULL_TREE; - if (operator_code == POSTINCREMENT_EXPR - || operator_code == POSTDECREMENT_EXPR) - pedwarn (input_location, OPT_Wpedantic, - "%qD cannot have default arguments", decl); - else - { - error ("%qD cannot have default arguments", decl); - return false; - } + error_at (loc, "%qD cannot have default arguments", decl); + return false; } /* At this point the declaration is well-formed. It may not be @@ -13328,31 +13328,31 @@ grok_op_properties (tree decl, bool complain) t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); if (VOID_TYPE_P (t)) - warning (OPT_Wconversion, - ref - ? G_("conversion to a reference to void " - "will never use a type conversion operator") - : G_("conversion to void " - "will never use a type conversion operator")); + warning_at (loc, OPT_Wconversion, + ref + ? G_("conversion to a reference to void " + "will never use a type conversion operator") + : G_("conversion to void " + "will never use a type conversion operator")); else if (class_type) { if (t == class_type) - warning (OPT_Wconversion, - ref - ? G_("conversion to a reference to the same type " - "will never use a type conversion operator") - : G_("conversion to the same type " - "will never use a type conversion operator")); + warning_at (loc, OPT_Wconversion, + ref + ? G_("conversion to a reference to the same type " + "will never use a type conversion operator") + : G_("conversion to the same type " + "will never use a type conversion operator")); /* Don't force t to be complete here. */ else if (MAYBE_CLASS_TYPE_P (t) && COMPLETE_TYPE_P (t) && DERIVED_FROM_P (t, class_type)) - warning (OPT_Wconversion, - ref - ? G_("conversion to a reference to a base class " - "will never use a type conversion operator") - : G_("conversion to a base class " - "will never use a type conversion operator")); + warning_at (loc, OPT_Wconversion, + ref + ? G_("conversion to a reference to a base class " + "will never use a type conversion operator") + : G_("conversion to a base class " + "will never use a type conversion operator")); } } @@ -13365,8 +13365,8 @@ grok_op_properties (tree decl, bool complain) if (operator_code == TRUTH_ANDIF_EXPR || operator_code == TRUTH_ORIF_EXPR || operator_code == COMPOUND_EXPR) - warning (OPT_Weffc__, - "user-defined %qD always evaluates both arguments", decl); + warning_at (loc, OPT_Weffc__, + "user-defined %qD always evaluates both arguments", decl); /* More Effective C++ rule 6. */ if (operator_code == POSTINCREMENT_EXPR @@ -13385,13 +13385,14 @@ grok_op_properties (tree decl, bool complain) { if (!TYPE_REF_P (ret) || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg)) - warning (OPT_Weffc__, "prefix %qD should return %qT", decl, - build_reference_type (arg)); + warning_at (loc, OPT_Weffc__, "prefix %qD should return %qT", decl, + build_reference_type (arg)); } else { if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) - warning (OPT_Weffc__, "postfix %qD should return %qT", decl, arg); + warning_at (loc, OPT_Weffc__, + "postfix %qD should return %qT", decl, arg); } } @@ -13403,7 +13404,7 @@ grok_op_properties (tree decl, bool complain) || operator_code == MULT_EXPR || operator_code == TRUNC_MOD_EXPR) && TYPE_REF_P (TREE_TYPE (TREE_TYPE (decl)))) - warning (OPT_Weffc__, "%qD should return by value", decl); + warning_at (loc, OPT_Weffc__, "%qD should return by value", decl); return true; } diff --git a/gcc/testsuite/g++.dg/lookup/new2.C b/gcc/testsuite/g++.dg/lookup/new2.C index d468182c18b..0eee4a0018d 100644 --- a/gcc/testsuite/g++.dg/lookup/new2.C +++ b/gcc/testsuite/g++.dg/lookup/new2.C @@ -4,8 +4,8 @@ namespace A { void* operator new(__SIZE_TYPE__ s, int* p); // { dg-error "namespace" } - void operator delete(void*); // { dg-error "namespace" } + void operator delete(void*); // { dg-error "9:.void A::operator delete\\(void\\*\\). may not be declared within a namespace" } } static void* operator new(__SIZE_TYPE__ s, int* p); // { dg-error "static" } -static void operator delete(void*); // { dg-error "static" } +static void operator delete(void*); // { dg-error "14:.void operator delete\\(void\\*\\). may not be declared as static" } diff --git a/gcc/testsuite/g++.dg/other/ellipsis1.C b/gcc/testsuite/g++.dg/other/ellipsis1.C dissimilarity index 78% index d2501ca85e2..54756b8d27c 100644 --- a/gcc/testsuite/g++.dg/other/ellipsis1.C +++ b/gcc/testsuite/g++.dg/other/ellipsis1.C @@ -1,12 +1,12 @@ -// PR c++/26291 -// { dg-do compile } - -struct A -{ - A& operator= (A,...); // { dg-error "variable number of arguments" } - A operator+ (...); // { dg-error "variable number of arguments" } - operator int(...); // { dg-error "variable number of arguments" } - int operator() (...); -}; - -A operator- (A,...); // { dg-error "variable number of arguments" } +// PR c++/26291 +// { dg-do compile } + +struct A +{ + A& operator= (A,...); // { dg-error "8:.A& A::operator=\\(A, ...\\). must not have variable number of arguments" } + A operator+ (...); // { dg-error "7:.A A::operator\\+\\(...\\). must not have variable number of arguments" } + operator int(...); // { dg-error "5:.A::operator int\\(...\\). must not have variable number of arguments" } + int operator() (...); +}; + +A operator- (A,...); // { dg-error "3:.A operator-\\(A, ...\\). must not have variable number of arguments" } diff --git a/gcc/testsuite/g++.dg/other/operator1.C b/gcc/testsuite/g++.dg/other/operator1.C index 86841c99956..d0b0cb25f8c 100644 --- a/gcc/testsuite/g++.dg/other/operator1.C +++ b/gcc/testsuite/g++.dg/other/operator1.C @@ -1,7 +1,7 @@ // PR c++/27547 // { dg-do compile } -int operator=(int); // { dg-error "member function" } +int operator=(int); // { dg-error "5:.int operator=\\(int\\). must be a nonstatic member function" } void foo() { diff --git a/gcc/testsuite/g++.dg/other/operator2.C b/gcc/testsuite/g++.dg/other/operator2.C index cc68d53354e..35873112718 100644 --- a/gcc/testsuite/g++.dg/other/operator2.C +++ b/gcc/testsuite/g++.dg/other/operator2.C @@ -3,7 +3,7 @@ struct A { - operator int&(int); // { dg-error "no arguments" } + operator int&(int); // { dg-error "3:.A::operator int&\\(int\\). must have no arguments" } }; A a; diff --git a/gcc/testsuite/g++.dg/overload/operator2.C b/gcc/testsuite/g++.dg/overload/operator2.C dissimilarity index 72% index aba1622442c..b60c629744e 100644 --- a/gcc/testsuite/g++.dg/overload/operator2.C +++ b/gcc/testsuite/g++.dg/overload/operator2.C @@ -1,14 +1,14 @@ -// PR c++/19966 -// { dg-do compile } - -struct A -{ - static operator int(); // { dg-error "must be a nonstatic" } -}; - -struct B -{ - static int operator*(); // { dg-error "must be either" } -}; - -static operator int(); // { dg-error "must be a nonstatic" } +// PR c++/19966 +// { dg-do compile } + +struct A +{ + static operator int(); // { dg-error "10:.static A::operator int\\(\\). must be a nonstatic member function" } +}; + +struct B +{ + static int operator*(); // { dg-error "14:.static int B::operator\\*\\(\\). must be either a non-static member function or a non-member function" } +}; + +static operator int(); // { dg-error "8:.operator int\\(\\). must be a nonstatic member function" } diff --git a/gcc/testsuite/g++.dg/parse/defarg11.C b/gcc/testsuite/g++.dg/parse/defarg11.C dissimilarity index 72% index 60199c2e20c..33f4b8ac70a 100644 --- a/gcc/testsuite/g++.dg/parse/defarg11.C +++ b/gcc/testsuite/g++.dg/parse/defarg11.C @@ -1,9 +1,9 @@ -// { dg-do compile } -// { dg-options "-pedantic" } - -class foo { -public: - void operator& (int = 1); // { dg-error "default argument" } - void operator++ (int = 2); // { dg-warning "default argument" } - void operator-- (int = 3); // { dg-warning "default argument" } -}; +// { dg-do compile } +// { dg-options "-pedantic" } + +class foo { +public: + void operator& (int = 1); // { dg-error "8:.void foo::operator&\\(int\\). cannot have default arguments" } + void operator++ (int = 2); // { dg-error "8:.void foo::operator\\+\\+\\(int\\). cannot have default arguments" } + void operator-- (int = 3); // { dg-error "8:.void foo::operator--\\(int\\). cannot have default arguments" } +}; diff --git a/gcc/testsuite/g++.dg/parse/operator4.C b/gcc/testsuite/g++.dg/parse/operator4.C index 054ddc8354f..1c81fbf2b44 100644 --- a/gcc/testsuite/g++.dg/parse/operator4.C +++ b/gcc/testsuite/g++.dg/parse/operator4.C @@ -1 +1 @@ -int operator *(int, ...); // { dg-error "class|variable number of arguments" } +int operator *(int, ...); // { dg-error ".int operator\\*\\(int, ...\\). must have an argument of class or enumerated type" } diff --git a/gcc/testsuite/g++.dg/template/error30.C b/gcc/testsuite/g++.dg/template/error30.C index e1138d052ec..e1706af0b7a 100644 --- a/gcc/testsuite/g++.dg/template/error30.C +++ b/gcc/testsuite/g++.dg/template/error30.C @@ -2,4 +2,4 @@ template struct A; -template class B> A::x> operator() (); // { dg-error "A::x>" } +template class B> A::x> operator() (); // { dg-error "51:.A::x> operator\\(\\)\\(\\). must be a nonstatic member function" } diff --git a/gcc/testsuite/g++.dg/template/explicit-args3.C b/gcc/testsuite/g++.dg/template/explicit-args3.C index c095e6688fd..5e16c21b3fd 100644 --- a/gcc/testsuite/g++.dg/template/explicit-args3.C +++ b/gcc/testsuite/g++.dg/template/explicit-args3.C @@ -4,7 +4,7 @@ template struct A { }; template -void operator+(T, T); // { dg-error "class or enum" } +void operator+(T, T); // { dg-error "6:.void operator\\+\\(T, T\\) \\\[with T = int\\\]. must have an argument of class or enumerated type" } int main() { diff --git a/gcc/testsuite/g++.dg/warn/effc1.C b/gcc/testsuite/g++.dg/warn/effc1.C index db36b121304..2911451ee6d 100644 --- a/gcc/testsuite/g++.dg/warn/effc1.C +++ b/gcc/testsuite/g++.dg/warn/effc1.C @@ -10,7 +10,7 @@ class A { public: A & operator+=( int ); - A & operator+( int ); // { dg-warning ".* should return by value" } + A & operator+( int ); // { dg-warning "7:.A& A::operator\\+\\(int\\). should return by value" } A operator+=( float ); A operator+( float ); }; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/prepost2.C b/gcc/testsuite/g++.old-deja/g++.brendan/prepost2.C index 3156749cff9..cbd05e647b1 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/prepost2.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/prepost2.C @@ -4,7 +4,10 @@ class foo { public: operator ++ (); // { dg-error "" } no type or storage class operator ++ (int); // { dg-error "" } no type or storage class - operator ++ (char); // illegal// { dg-error "" } .* - operator ++ (short); // illegal// { dg-error "" } .* - operator ++ (long); // illegal// { dg-error "" } .* + operator ++ (char); // { dg-error "no type" } +// { dg-error "7:postfix .int foo::operator\\+\\+\\(char\\). must have .int. as its argument" "sec" { target *-*-* } .-1 } + operator ++ (short); // { dg-error "no type" } +// { dg-error "7:postfix .int foo::operator\\+\\+\\(short int\\). must have .int. as its argument" "sec" { target *-*-* } .-1 } + operator ++ (long); // { dg-error "no type" } +// { dg-error "7:postfix .int foo::operator\\+\\+\\(long int\\). must have .int. as its argument" "sec" { target *-*-* } .-1 } }; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/prepost3.C b/gcc/testsuite/g++.old-deja/g++.brendan/prepost3.C index d11624b2d08..f55c3dc35b3 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/prepost3.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/prepost3.C @@ -3,5 +3,5 @@ class Y { public: friend Y operator++ (Y&); - friend Y operator++ (Y&, char); // illegal// { dg-error "" } .* + friend Y operator++ (Y&, char); // { dg-error "13:postfix .Y operator\\+\\+\\(Y&, char\\). must have .int. as its second argument" } }; diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900215_01.C b/gcc/testsuite/g++.old-deja/g++.bugs/900215_01.C index c79a7035f99..0cd9b321e3e 100644 --- a/gcc/testsuite/g++.old-deja/g++.bugs/900215_01.C +++ b/gcc/testsuite/g++.old-deja/g++.bugs/900215_01.C @@ -24,7 +24,7 @@ struct struct0 { - operator void (); // { dg-warning "" } operator void + operator void (); // { dg-warning "3:conversion to void will never use a type conversion operator" } }; int exit_status = 1; diff --git a/gcc/testsuite/g++.old-deja/g++.jason/conversion5.C b/gcc/testsuite/g++.old-deja/g++.jason/conversion5.C index 0031084db00..a9531a6d209 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/conversion5.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/conversion5.C @@ -3,7 +3,7 @@ struct A { }; struct B: public A { A a; - operator A () { return a; } // { dg-warning "" } never used implicitly + operator A () { return a; } // { dg-warning "3:conversion to a base class will never use a type conversion operator" } }; void f (const A&); void g() diff --git a/gcc/testsuite/g++.old-deja/g++.jason/operator.C b/gcc/testsuite/g++.old-deja/g++.jason/operator.C index bdcd5493a97..ba6d407d1b9 100644 --- a/gcc/testsuite/g++.old-deja/g++.jason/operator.C +++ b/gcc/testsuite/g++.old-deja/g++.jason/operator.C @@ -6,27 +6,27 @@ typedef __SIZE_TYPE__ size_t; struct A { int operator?:(int a, int b); // { dg-error "expected type-specifier" } - static int operator()(int a); // { dg-error "must be a nonstatic member" } - static int operator+(A,A); // { dg-error "either a non-static member" } - int operator+(int a, int b = 1); // { dg-error "either zero or one" } - int operator++(char); // { dg-error "must have 'int'" } + static int operator()(int a); // { dg-error "14:.static int A::operator\\(\\)\\(int\\). must be a nonstatic member function" } + static int operator+(A,A); // { dg-error "14:.static int A::operator\\+\\(A, A\\). must be either a non-static member function or a non-member function" } + int operator+(int a, int b = 1); // { dg-error "7:.int A::operator\\+\\(int, int\\). must have either zero or one argument" } + int operator++(char); // { dg-error "7:postfix .int A::operator\\+\\+\\(char\\). must have .int. as its argument" } void operator delete (void *); void operator delete (void *, unsigned long); }; struct B { void * operator new (size_t, void *); - int operator++(int = 0); + int operator++(int = 0); // { dg-error "7:.int B::operator\\+\\+\\(int\\). cannot have default arguments" } int operator+ (int); void operator()(); char * operator[](int); B * operator->(); }; -int operator-(int a, int b); // { dg-error "argument of class or" } +int operator-(int a, int b); // { dg-error "5:.int operator-\\(int, int\\). must have an argument of class or enumerated type" } void * operator new (A a); // { dg-error "first parameter" } void operator delete (A a); // { dg-error "first parameter" } char * operator char * (int); // { dg-error "return type" "ret" } -// { dg-error "nonstatic member function" "mem" { target *-*-* } .-1 } +// { dg-error "8:.operator char\\*\\*\\(int\\). must be a nonstatic member function" "mem" { target *-*-* } .-1 } -- 2.11.4.GIT