[C++] Fix grok_op_properties locations

Message ID a03c224d-fbdf-2b43-8c53-cf4e3dbe30a9@oracle.com
State New
Headers show
Series
  • [C++] Fix grok_op_properties locations
Related show

Commit Message

Paolo Carlini June 11, 2018, 7:29 p.m.
Hi,

this consistently fixes all the locations and at the same time removes 
the special casing of POSTINCREMENT_EXPR and POSTDECREMENT_EXPR as 
agreed a few days ago. Tested x86_64-linux.

Thanks, Paolo.

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

Comments

Jason Merrill June 11, 2018, 7:39 p.m. | #1
OK.

On Mon, Jun 11, 2018 at 3:29 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi,
>
> this consistently fixes all the locations and at the same time removes the
> special casing of POSTINCREMENT_EXPR and POSTDECREMENT_EXPR as agreed a few
> days ago. Tested x86_64-linux.
>
> Thanks, Paolo.
>
> //////////////////////
>

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 261431)
+++ cp/decl.c	(working copy)
@@ -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 %<int%> as its argument")
-		 : G_("postfix %qD must have %<int%> as its second argument"),
-		 decl);
+	  error_at (loc,
+		    methodp
+		    ? G_("postfix %qD must have %<int%> as its argument")
+		    : G_("postfix %qD must have %<int%> 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;
 }
Index: testsuite/g++.dg/lookup/new2.C
===================================================================
--- testsuite/g++.dg/lookup/new2.C	(revision 261434)
+++ testsuite/g++.dg/lookup/new2.C	(working copy)
@@ -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" }
Index: testsuite/g++.dg/other/ellipsis1.C
===================================================================
--- testsuite/g++.dg/other/ellipsis1.C	(revision 261431)
+++ testsuite/g++.dg/other/ellipsis1.C	(working copy)
@@ -3,10 +3,10 @@ 
 
 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" }
+    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 "variable number of arguments" }
+A operator- (A,...);       // { dg-error "3:.A operator-\\(A, ...\\). must not have variable number of arguments" }
Index: testsuite/g++.dg/other/operator1.C
===================================================================
--- testsuite/g++.dg/other/operator1.C	(revision 261431)
+++ testsuite/g++.dg/other/operator1.C	(working copy)
@@ -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()
 {
Index: testsuite/g++.dg/other/operator2.C
===================================================================
--- testsuite/g++.dg/other/operator2.C	(revision 261431)
+++ testsuite/g++.dg/other/operator2.C	(working copy)
@@ -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;
Index: testsuite/g++.dg/overload/operator2.C
===================================================================
--- testsuite/g++.dg/overload/operator2.C	(revision 261431)
+++ testsuite/g++.dg/overload/operator2.C	(working copy)
@@ -3,12 +3,12 @@ 
 
 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
 {
-  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" }
Index: testsuite/g++.dg/parse/defarg11.C
===================================================================
--- testsuite/g++.dg/parse/defarg11.C	(revision 261431)
+++ testsuite/g++.dg/parse/defarg11.C	(working copy)
@@ -3,7 +3,7 @@ 
 
 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" }
+  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" }
 };
Index: testsuite/g++.dg/parse/operator4.C
===================================================================
--- testsuite/g++.dg/parse/operator4.C	(revision 261431)
+++ testsuite/g++.dg/parse/operator4.C	(working copy)
@@ -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" }
Index: testsuite/g++.dg/template/error30.C
===================================================================
--- testsuite/g++.dg/template/error30.C	(revision 261431)
+++ testsuite/g++.dg/template/error30.C	(working copy)
@@ -2,4 +2,4 @@ 
 
 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" }
Index: testsuite/g++.dg/template/explicit-args3.C
===================================================================
--- testsuite/g++.dg/template/explicit-args3.C	(revision 261431)
+++ testsuite/g++.dg/template/explicit-args3.C	(working copy)
@@ -4,7 +4,7 @@  template <class T>
 struct A { };
 
 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()
 {
Index: testsuite/g++.dg/warn/effc1.C
===================================================================
--- testsuite/g++.dg/warn/effc1.C	(revision 261431)
+++ testsuite/g++.dg/warn/effc1.C	(working copy)
@@ -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 );
 };
Index: testsuite/g++.old-deja/g++.brendan/prepost2.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/prepost2.C	(revision 261431)
+++ testsuite/g++.old-deja/g++.brendan/prepost2.C	(working copy)
@@ -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 }
 };
Index: testsuite/g++.old-deja/g++.brendan/prepost3.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/prepost3.C	(revision 261431)
+++ testsuite/g++.old-deja/g++.brendan/prepost3.C	(working copy)
@@ -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" }
 };
Index: testsuite/g++.old-deja/g++.bugs/900215_01.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900215_01.C	(revision 261431)
+++ testsuite/g++.old-deja/g++.bugs/900215_01.C	(working copy)
@@ -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;
Index: testsuite/g++.old-deja/g++.jason/conversion5.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/conversion5.C	(revision 261431)
+++ testsuite/g++.old-deja/g++.jason/conversion5.C	(working copy)
@@ -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()
Index: testsuite/g++.old-deja/g++.jason/operator.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/operator.C	(revision 261431)
+++ testsuite/g++.old-deja/g++.jason/operator.C	(working copy)
@@ -6,10 +6,10 @@  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);	
 };
@@ -16,7 +16,7 @@  struct A {
 
 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);
@@ -23,10 +23,10 @@  struct B {
   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 }