Commit fafd0db1 by Paolo Carlini Committed by Paolo Carlini

decl.c (grok_op_properties): Consistently use the location of the decl...

/cp
2018-06-11  Paolo Carlini  <paolo.carlini@oracle.com>

	* 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  <paolo.carlini@oracle.com>

	* 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.

From-SVN: r261455
parent 9b0607de
2018-06-11 Paolo Carlini <paolo.carlini@oracle.com>
* 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 <jason@redhat.com> 2018-06-05 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_binary_expression): Special case comparison * constexpr.c (cxx_eval_binary_expression): Special case comparison
......
...@@ -13078,6 +13078,7 @@ grok_op_properties (tree decl, bool complain) ...@@ -13078,6 +13078,7 @@ grok_op_properties (tree decl, bool complain)
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE; bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE;
tree name = DECL_NAME (decl); tree name = DECL_NAME (decl);
location_t loc = DECL_SOURCE_LOCATION (decl);
tree class_type = DECL_CONTEXT (decl); tree class_type = DECL_CONTEXT (decl);
if (class_type && !CLASS_TYPE_P (class_type)) if (class_type && !CLASS_TYPE_P (class_type))
...@@ -13139,13 +13140,14 @@ grok_op_properties (tree decl, bool complain) ...@@ -13139,13 +13140,14 @@ grok_op_properties (tree decl, bool complain)
{ {
if (CP_DECL_CONTEXT (decl) != global_namespace) 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; return false;
} }
if (!TREE_PUBLIC (decl)) 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; return false;
} }
} }
...@@ -13172,14 +13174,14 @@ grok_op_properties (tree decl, bool complain) ...@@ -13172,14 +13174,14 @@ grok_op_properties (tree decl, bool complain)
|| operator_code == ARRAY_REF || operator_code == ARRAY_REF
|| operator_code == NOP_EXPR) || 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; return false;
} }
if (DECL_STATIC_FUNCTION_P (decl)) if (DECL_STATIC_FUNCTION_P (decl))
{ {
error ("%qD must be either a non-static member " error_at (loc, "%qD must be either a non-static member "
"function or a non-member function", decl); "function or a non-member function", decl);
return false; return false;
} }
...@@ -13188,8 +13190,8 @@ grok_op_properties (tree decl, bool complain) ...@@ -13188,8 +13190,8 @@ grok_op_properties (tree decl, bool complain)
if (!arg || arg == void_list_node) if (!arg || arg == void_list_node)
{ {
if (complain) if (complain)
error ("%qD must have an argument of class or " error_at(loc, "%qD must have an argument of class or "
"enumerated type", decl); "enumerated type", decl);
return false; return false;
} }
...@@ -13214,7 +13216,7 @@ grok_op_properties (tree decl, bool complain) ...@@ -13214,7 +13216,7 @@ grok_op_properties (tree decl, bool complain)
if (operator_code == COND_EXPR) if (operator_code == COND_EXPR)
{ {
/* 13.4.0.3 */ /* 13.4.0.3 */
error ("ISO C++ prohibits overloading operator ?:"); error_at (loc, "ISO C++ prohibits overloading operator ?:");
return false; return false;
} }
...@@ -13225,7 +13227,8 @@ grok_op_properties (tree decl, bool complain) ...@@ -13225,7 +13227,8 @@ grok_op_properties (tree decl, bool complain)
if (!arg) if (!arg)
{ {
/* Variadic. */ /* 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; return false;
} }
++arity; ++arity;
...@@ -13248,9 +13251,10 @@ grok_op_properties (tree decl, bool complain) ...@@ -13248,9 +13251,10 @@ grok_op_properties (tree decl, bool complain)
else if (arity != 2) else if (arity != 2)
{ {
/* This was an ambiguous operator but is invalid. */ /* This was an ambiguous operator but is invalid. */
error (methodp error_at (loc,
? G_("%qD must have either zero or one argument") methodp
: G_("%qD must have either one or two arguments"), decl); ? G_("%qD must have either zero or one argument")
: G_("%qD must have either one or two arguments"), decl);
return false; return false;
} }
else if ((operator_code == POSTINCREMENT_EXPR else if ((operator_code == POSTINCREMENT_EXPR
...@@ -13260,10 +13264,11 @@ grok_op_properties (tree decl, bool complain) ...@@ -13260,10 +13264,11 @@ grok_op_properties (tree decl, bool complain)
&& ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)),
integer_type_node)) integer_type_node))
{ {
error (methodp error_at (loc,
? G_("postfix %qD must have %<int%> as its argument") methodp
: G_("postfix %qD must have %<int%> as its second argument"), ? G_("postfix %qD must have %<int%> as its argument")
decl); : G_("postfix %qD must have %<int%> as its second argument"),
decl);
return false; return false;
} }
break; break;
...@@ -13271,9 +13276,10 @@ grok_op_properties (tree decl, bool complain) ...@@ -13271,9 +13276,10 @@ grok_op_properties (tree decl, bool complain)
case OVL_OP_FLAG_UNARY: case OVL_OP_FLAG_UNARY:
if (arity != 1) if (arity != 1)
{ {
error (methodp error_at (loc,
? G_("%qD must have no arguments") methodp
: G_("%qD must have exactly one argument"), decl); ? G_("%qD must have no arguments")
: G_("%qD must have exactly one argument"), decl);
return false; return false;
} }
break; break;
...@@ -13281,9 +13287,10 @@ grok_op_properties (tree decl, bool complain) ...@@ -13281,9 +13287,10 @@ grok_op_properties (tree decl, bool complain)
case OVL_OP_FLAG_BINARY: case OVL_OP_FLAG_BINARY:
if (arity != 2) if (arity != 2)
{ {
error (methodp error_at (loc,
? G_("%qD must have exactly one argument") methodp
: G_("%qD must have exactly two arguments"), decl); ? G_("%qD must have exactly one argument")
: G_("%qD must have exactly two arguments"), decl);
return false; return false;
} }
break; break;
...@@ -13297,15 +13304,8 @@ grok_op_properties (tree decl, bool complain) ...@@ -13297,15 +13304,8 @@ grok_op_properties (tree decl, bool complain)
if (TREE_PURPOSE (arg)) if (TREE_PURPOSE (arg))
{ {
TREE_PURPOSE (arg) = NULL_TREE; TREE_PURPOSE (arg) = NULL_TREE;
if (operator_code == POSTINCREMENT_EXPR error_at (loc, "%qD cannot have default arguments", decl);
|| operator_code == POSTDECREMENT_EXPR) return false;
pedwarn (input_location, OPT_Wpedantic,
"%qD cannot have default arguments", decl);
else
{
error ("%qD cannot have default arguments", decl);
return false;
}
} }
/* At this point the declaration is well-formed. It may not be /* At this point the declaration is well-formed. It may not be
...@@ -13328,31 +13328,31 @@ grok_op_properties (tree decl, bool complain) ...@@ -13328,31 +13328,31 @@ grok_op_properties (tree decl, bool complain)
t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
if (VOID_TYPE_P (t)) if (VOID_TYPE_P (t))
warning (OPT_Wconversion, warning_at (loc, OPT_Wconversion,
ref ref
? G_("conversion to a reference to void " ? G_("conversion to a reference to void "
"will never use a type conversion operator") "will never use a type conversion operator")
: G_("conversion to void " : G_("conversion to void "
"will never use a type conversion operator")); "will never use a type conversion operator"));
else if (class_type) else if (class_type)
{ {
if (t == class_type) if (t == class_type)
warning (OPT_Wconversion, warning_at (loc, OPT_Wconversion,
ref ref
? G_("conversion to a reference to the same type " ? G_("conversion to a reference to the same type "
"will never use a type conversion operator") "will never use a type conversion operator")
: G_("conversion to the same type " : G_("conversion to the same type "
"will never use a type conversion operator")); "will never use a type conversion operator"));
/* Don't force t to be complete here. */ /* Don't force t to be complete here. */
else if (MAYBE_CLASS_TYPE_P (t) else if (MAYBE_CLASS_TYPE_P (t)
&& COMPLETE_TYPE_P (t) && COMPLETE_TYPE_P (t)
&& DERIVED_FROM_P (t, class_type)) && DERIVED_FROM_P (t, class_type))
warning (OPT_Wconversion, warning_at (loc, OPT_Wconversion,
ref ref
? G_("conversion to a reference to a base class " ? G_("conversion to a reference to a base class "
"will never use a type conversion operator") "will never use a type conversion operator")
: G_("conversion to a base class " : G_("conversion to a base class "
"will never use a type conversion operator")); "will never use a type conversion operator"));
} }
} }
...@@ -13365,8 +13365,8 @@ grok_op_properties (tree decl, bool complain) ...@@ -13365,8 +13365,8 @@ grok_op_properties (tree decl, bool complain)
if (operator_code == TRUTH_ANDIF_EXPR if (operator_code == TRUTH_ANDIF_EXPR
|| operator_code == TRUTH_ORIF_EXPR || operator_code == TRUTH_ORIF_EXPR
|| operator_code == COMPOUND_EXPR) || operator_code == COMPOUND_EXPR)
warning (OPT_Weffc__, warning_at (loc, OPT_Weffc__,
"user-defined %qD always evaluates both arguments", decl); "user-defined %qD always evaluates both arguments", decl);
/* More Effective C++ rule 6. */ /* More Effective C++ rule 6. */
if (operator_code == POSTINCREMENT_EXPR if (operator_code == POSTINCREMENT_EXPR
...@@ -13385,13 +13385,14 @@ grok_op_properties (tree decl, bool complain) ...@@ -13385,13 +13385,14 @@ grok_op_properties (tree decl, bool complain)
{ {
if (!TYPE_REF_P (ret) if (!TYPE_REF_P (ret)
|| !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg)) || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg))
warning (OPT_Weffc__, "prefix %qD should return %qT", decl, warning_at (loc, OPT_Weffc__, "prefix %qD should return %qT", decl,
build_reference_type (arg)); build_reference_type (arg));
} }
else else
{ {
if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) 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) ...@@ -13403,7 +13404,7 @@ grok_op_properties (tree decl, bool complain)
|| operator_code == MULT_EXPR || operator_code == MULT_EXPR
|| operator_code == TRUNC_MOD_EXPR) || operator_code == TRUNC_MOD_EXPR)
&& TYPE_REF_P (TREE_TYPE (TREE_TYPE (decl)))) && 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; return true;
} }
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
namespace A { namespace A {
void* operator new(__SIZE_TYPE__ s, int* p); // { dg-error "namespace" } 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 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" }
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
struct A struct A
{ {
A& operator= (A,...); // { dg-error "variable number of arguments" } A& operator= (A,...); // { dg-error "8:.A& A::operator=\\(A, ...\\). must not have variable number of arguments" }
A operator+ (...); // { dg-error "variable number of arguments" } A operator+ (...); // { dg-error "7:.A A::operator\\+\\(...\\). must not have variable number of arguments" }
operator int(...); // { dg-error "variable number of arguments" } operator int(...); // { dg-error "5:.A::operator int\\(...\\). must not have variable number of arguments" }
int operator() (...); int operator() (...);
}; };
A operator- (A,...); // { dg-error "variable number of arguments" } A operator- (A,...); // { dg-error "3:.A operator-\\(A, ...\\). must not have variable number of arguments" }
// PR c++/27547 // PR c++/27547
// { dg-do compile } // { 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() void foo()
{ {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
struct A 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; A a;
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
struct A struct A
{ {
static operator int(); // { dg-error "must be a nonstatic" } static operator int(); // { dg-error "10:.static A::operator int\\(\\). must be a nonstatic member function" }
}; };
struct B struct B
{ {
static int operator*(); // { dg-error "must be either" } 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 "must be a nonstatic" } static operator int(); // { dg-error "8:.operator int\\(\\). must be a nonstatic member function" }
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
class foo { class foo {
public: public:
void operator& (int = 1); // { dg-error "default argument" } void operator& (int = 1); // { dg-error "8:.void foo::operator&\\(int\\). cannot have default arguments" }
void operator++ (int = 2); // { dg-warning "default argument" } void operator++ (int = 2); // { dg-error "8:.void foo::operator\\+\\+\\(int\\). cannot have default arguments" }
void operator-- (int = 3); // { dg-warning "default argument" } void operator-- (int = 3); // { dg-error "8:.void foo::operator--\\(int\\). cannot have default arguments" }
}; };
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" }
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
template<int> struct A; template<int> struct A;
template<template<typename> class B> A<B<int>::x> operator() (); // { dg-error "A<B<int>::x>" } template<template<typename> class B> A<B<int>::x> operator() (); // { dg-error "51:.A<B<int>::x> operator\\(\\)\\(\\). must be a nonstatic member function" }
...@@ -4,7 +4,7 @@ template <class T> ...@@ -4,7 +4,7 @@ template <class T>
struct A { }; struct A { };
template <class T> template <class T>
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() int main()
{ {
......
...@@ -10,7 +10,7 @@ class A ...@@ -10,7 +10,7 @@ class A
{ {
public: public:
A & operator+=( int ); 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 );
A operator+( float ); A operator+( float );
}; };
...@@ -4,7 +4,10 @@ class foo { ...@@ -4,7 +4,10 @@ class foo {
public: public:
operator ++ (); // { dg-error "" } no type or storage class operator ++ (); // { dg-error "" } no type or storage class
operator ++ (int); // { dg-error "" } no type or storage class operator ++ (int); // { dg-error "" } no type or storage class
operator ++ (char); // illegal// { dg-error "" } .* operator ++ (char); // { dg-error "no type" }
operator ++ (short); // illegal// { dg-error "" } .* // { dg-error "7:postfix .int foo::operator\\+\\+\\(char\\). must have .int. as its argument" "sec" { target *-*-* } .-1 }
operator ++ (long); // illegal// { dg-error "" } .* 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 }
}; };
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
class Y { class Y {
public: public:
friend Y operator++ (Y&); 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" }
}; };
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
struct struct0 { 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; int exit_status = 1;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
struct A { }; struct A { };
struct B: public A { struct B: public A {
A 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 f (const A&);
void g() void g()
......
...@@ -6,27 +6,27 @@ typedef __SIZE_TYPE__ size_t; ...@@ -6,27 +6,27 @@ typedef __SIZE_TYPE__ size_t;
struct A { struct A {
int operator?:(int a, int b); // { dg-error "expected type-specifier" } 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()(int a); // { dg-error "14:.static int A::operator\\(\\)\\(int\\). must be a nonstatic member function" }
static int operator+(A,A); // { dg-error "either a non-static member" } 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 "either zero or one" } 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 "must have 'int'" } 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 *);
void operator delete (void *, unsigned long); void operator delete (void *, unsigned long);
}; };
struct B { struct B {
void * operator new (size_t, void *); 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); int operator+ (int);
void operator()(); void operator()();
char * operator[](int); char * operator[](int);
B * operator->(); 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 new (A a); // { dg-error "first parameter" }
void operator delete (A a); // { dg-error "first parameter" } void operator delete (A a); // { dg-error "first parameter" }
char * operator char * (int); // { dg-error "return type" "ret" } 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 }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment