This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix 20637


this patch fixes 20637, a place where we issued a less than informative error message.

I also took up Giovanni's suggestion of using 'inform' for my recent synthesize_method patch -- thanks.

built & tested on i686-pc-linux-gnu. Installed mainline, and shortly on 4.0

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-06-06  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/20637
	* cp-tree.h (add_method): Add using_decl parameter.
	* class.c (add_method): Add using_decl parameter.  Adjust error
	messages.
	(handle_using_decl): Pass the using decl to add_method.
	(clone_function_decl): Adjust add_member calls.
	* decl2.c (check_classfn): Likewise.
	* method.c (lazily_declare_fn): Likewise.
	* semantics.c (finish_member_declaration): Likewise.

	* method.c (synthesize_method): Use inform, not warning.

2005-06-06  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/20637
	* g++.dg/inherit/using4.C: New.
	* g++.dg/overload/error1.C: Adjust expected errors.
	* g++.old-deja/g++.benjamin/warn02.C: Likewise.
	* g++.old-deja/g++.brendan/arm2.C: Likewise.
	* g++.old-deja/g++.other/redecl2.C: Likewise.
	* g++.old-deja/g++.other/redecl4.C: Likewise.
	* g++.old-deja/g++.pt/memtemp78.C: Likewise.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.718
diff -c -3 -p -r1.718 class.c
*** cp/class.c	24 May 2005 22:22:14 -0000	1.718
--- cp/class.c	6 Jun 2005 13:56:57 -0000
*************** modify_vtable_entry (tree t,
*** 878,889 ****
  }
  
  
! /* Add method METHOD to class TYPE.  */
  
  void
! add_method (tree type, tree method)
  {
-   int using;
    unsigned slot;
    tree overload;
    bool template_conv_p = false;
--- 878,889 ----
  }
  
  
! /* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
!    the USING_DECL naming METHOD.  */
  
  void
! add_method (tree type, tree method, tree using_decl)
  {
    unsigned slot;
    tree overload;
    bool template_conv_p = false;
*************** add_method (tree type, tree method)
*** 897,903 ****
      return;
  
    complete_p = COMPLETE_TYPE_P (type);
-   using = (DECL_CONTEXT (method) != type);
    conv_p = DECL_CONV_FN_P (method);
    if (conv_p)
      template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
--- 897,902 ----
*************** add_method (tree type, tree method)
*** 1024,1044 ****
  		  || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
  				  TREE_TYPE (TREE_TYPE (method)))))
  	    {
! 	      if (using && DECL_CONTEXT (fn) == type)
! 		/* Defer to the local function.  */
! 		return;
  	      else
  		{
! 		  cp_error_at ("%q#D and %q#D cannot be overloaded",
! 			       method, fn);
! 
! 		  /* We don't call duplicate_decls here to merge
! 		     the declarations because that will confuse
! 		     things if the methods have inline
! 		     definitions.  In particular, we will crash
! 		     while processing the definitions.  */
! 		  return;
  		}
  	    }
  	}
      }
--- 1023,1050 ----
  		  || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
  				  TREE_TYPE (TREE_TYPE (method)))))
  	    {
! 	      if (using_decl)
! 		{
! 		  if (DECL_CONTEXT (fn) == type)
! 		    /* Defer to the local function.  */
! 		    return;
! 		  if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
! 		    cp_error_at ("repeated using declaration %qD", using_decl);
! 		  else
! 		    cp_error_at ("using declaration %qD conflicts with a previous using declaration",
! 				 using_decl);
! 		}
  	      else
  		{
! 		  cp_error_at ("%q#D cannot be overloaded", method);
! 		  cp_error_at ("with %q#D", fn);
  		}
+ 	      
+ 	      /* We don't call duplicate_decls here to merge the
+ 		 declarations because that will confuse things if the
+ 		 methods have inline definitions.  In particular, we
+ 		 will crash while processing the definitions.  */
+ 	      return;
  	    }
  	}
      }
*************** handle_using_decl (tree using_decl, tree
*** 1201,1207 ****
    if (flist)
      for (; flist; flist = OVL_NEXT (flist))
        {
! 	add_method (t, OVL_CURRENT (flist));
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
--- 1207,1213 ----
    if (flist)
      for (; flist; flist = OVL_NEXT (flist))
        {
! 	add_method (t, OVL_CURRENT (flist), using_decl);
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
*************** clone_function_decl (tree fn, int update
*** 3829,3838 ****
  	 and a not-in-charge version.  */
        clone = build_clone (fn, complete_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
        clone = build_clone (fn, base_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
      }
    else
      {
--- 3835,3844 ----
  	 and a not-in-charge version.  */
        clone = build_clone (fn, complete_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
        clone = build_clone (fn, base_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
      }
    else
      {
*************** clone_function_decl (tree fn, int update
*** 3851,3864 ****
  	{
  	  clone = build_clone (fn, deleting_dtor_identifier);
  	  if (update_method_vec_p)
! 	    add_method (DECL_CONTEXT (clone), clone);
  	}
        clone = build_clone (fn, complete_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
        clone = build_clone (fn, base_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
      }
  
    /* Note that this is an abstract function that is never emitted.  */
--- 3857,3870 ----
  	{
  	  clone = build_clone (fn, deleting_dtor_identifier);
  	  if (update_method_vec_p)
! 	    add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
  	}
        clone = build_clone (fn, complete_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
        clone = build_clone (fn, base_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
      }
  
    /* Note that this is an abstract function that is never emitted.  */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1141
diff -c -3 -p -r1.1141 cp-tree.h
*** cp/cp-tree.h	5 Jun 2005 16:33:35 -0000	1.1141
--- cp/cp-tree.h	6 Jun 2005 13:57:10 -0000
*************** extern tree build_vfn_ref			(tree, tree)
*** 3667,3673 ****
  extern tree get_vtable_decl                     (tree, int);
  extern void resort_type_method_vec
    (void *, void *, gt_pointer_operator, void *);
! extern void add_method				(tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
--- 3667,3673 ----
  extern tree get_vtable_decl                     (tree, int);
  extern void resort_type_method_vec
    (void *, void *, gt_pointer_operator, void *);
! extern void add_method				(tree, tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.784
diff -c -3 -p -r1.784 decl2.c
*** cp/decl2.c	2 Jun 2005 17:52:12 -0000	1.784
--- cp/decl2.c	6 Jun 2005 13:57:17 -0000
*************** check_classfn (tree ctype, tree function
*** 709,715 ****
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
    if (COMPLETE_TYPE_P (ctype))
!     add_method (ctype, function);
    return NULL_TREE;
  }
  
--- 709,715 ----
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
    if (COMPLETE_TYPE_P (ctype))
!     add_method (ctype, function, NULL_TREE);
    return NULL_TREE;
  }
  
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.332
diff -c -3 -p -r1.332 method.c
*** cp/method.c	2 Jun 2005 20:02:26 -0000	1.332
--- cp/method.c	6 Jun 2005 13:57:19 -0000
*************** synthesize_method (tree fndecl)
*** 806,813 ****
    pop_deferring_access_checks ();
  
    if (error_count != errorcount || warning_count != warningcount)
!     warning (0, "%Hsynthesized method %qD first required here ",
! 	     &input_location, fndecl);
  }
  
  /* Use EXTRACTOR to locate the relevant function called for each base &
--- 806,813 ----
    pop_deferring_access_checks ();
  
    if (error_count != errorcount || warning_count != warningcount)
!     inform ("%Hsynthesized method %qD first required here ",
! 	    &input_location, fndecl);
  }
  
  /* Use EXTRACTOR to locate the relevant function called for each base &
*************** lazily_declare_fn (special_function_kind
*** 1119,1125 ****
    if (sfk == sfk_destructor)
      check_for_override (fn, type);
    /* Add it to CLASSTYPE_METHOD_VEC.  */
!   add_method (type, fn);
    /* Add it to TYPE_METHODS.  */
    if (sfk == sfk_destructor 
        && DECL_VIRTUAL_P (fn)
--- 1119,1125 ----
    if (sfk == sfk_destructor)
      check_for_override (fn, type);
    /* Add it to CLASSTYPE_METHOD_VEC.  */
!   add_method (type, fn, NULL_TREE);
    /* Add it to TYPE_METHODS.  */
    if (sfk == sfk_destructor 
        && DECL_VIRTUAL_P (fn)
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.473
diff -c -3 -p -r1.473 semantics.c
*** cp/semantics.c	28 May 2005 01:38:11 -0000	1.473
--- cp/semantics.c	6 Jun 2005 13:57:27 -0000
*************** finish_member_declaration (tree decl)
*** 2250,2256 ****
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       add_method (current_class_type, decl);
  
        TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
        TYPE_METHODS (current_class_type) = decl;
--- 2250,2256 ----
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       add_method (current_class_type, decl, NULL_TREE);
  
        TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
        TYPE_METHODS (current_class_type) = decl;
Index: testsuite/g++.dg/inherit/using4.C
===================================================================
RCS file: testsuite/g++.dg/inherit/using4.C
diff -N testsuite/g++.dg/inherit/using4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/using4.C	6 Jun 2005 13:57:43 -0000
***************
*** 0 ****
--- 1,14 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 6 Jun 2005 <nathan@codesourcery.com>
+ 
+ // PR 20613:uninformative diagnostic
+ // Origin:  Wolfgang Bangerth <bangerth@dealii.org>
+ 
+ struct B { 
+   void f();
+ }; 
+  
+ struct D : B { 
+   using B::f; 
+   using B::f;  // { dg-error "repeated" }
+ }; 
Index: testsuite/g++.dg/overload/error1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/overload/error1.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 error1.C
*** testsuite/g++.dg/overload/error1.C	11 Jul 2002 22:34:57 -0000	1.2
--- testsuite/g++.dg/overload/error1.C	6 Jun 2005 13:57:44 -0000
***************
*** 2,7 ****
  
  struct S
  {
!   void f () {}
!   int f () { return 0; } // { dg-error "" "" }
  };
--- 2,7 ----
  
  struct S
  {
!   void f () {} // { dg-error "with" "" }
!   int f () { return 0; } // { dg-error "overloaded" "" }
  };
Index: testsuite/g++.old-deja/g++.benjamin/warn02.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C,v
retrieving revision 1.4
diff -c -3 -p -r1.4 warn02.C
*** testsuite/g++.old-deja/g++.benjamin/warn02.C	1 May 2003 02:02:33 -0000	1.4
--- testsuite/g++.old-deja/g++.benjamin/warn02.C	6 Jun 2005 13:57:50 -0000
*************** class C
*** 31,46 ****
  class D
  {
  public:
!   int foo2() {return b;}  
!   int foo2() {return b;}  // { dg-error "" } 
    int b;
  };
  
  class E
  {
  public:
!   int foo2(); 
!   int foo2(); // { dg-error "" } 
    int b;
  };
  
--- 31,46 ----
  class D
  {
  public:
!   int foo2() {return b;}  // { dg-error "with" } 
!   int foo2() {return b;}  // { dg-error "overloaded" } 
    int b;
  };
  
  class E
  {
  public:
!   int foo2(); // { dg-error "with" } 
!   int foo2(); // { dg-error "overloaded" } 
    int b;
  };
  
Index: testsuite/g++.old-deja/g++.brendan/arm2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.brendan/arm2.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 arm2.C
*** testsuite/g++.old-deja/g++.brendan/arm2.C	1 May 2003 02:02:34 -0000	1.3
--- testsuite/g++.old-deja/g++.brendan/arm2.C	6 Jun 2005 13:57:50 -0000
***************
*** 8,19 ****
  
  class X {
  public:
!    int foo();
!   static int foo();	// error: redeclaration// { dg-error "" } .*
  };
  
  class Y {
  public:
!    static int foo();
!   int foo();		// error: redeclaration// { dg-error "" } .*
  };
--- 8,19 ----
  
  class X {
  public:
!   int foo();            // { dg-error "with" }
!   static int foo();	// error: redeclaration// { dg-error "overloaded" } .*
  };
  
  class Y {
  public:
!    static int foo();    // { dg-error "with" }
!   int foo();		// error: redeclaration// { dg-error "overloaded" } .*
  };
Index: testsuite/g++.old-deja/g++.other/redecl2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/redecl2.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 redecl2.C
*** testsuite/g++.old-deja/g++.other/redecl2.C	1 May 2003 02:02:50 -0000	1.3
--- testsuite/g++.old-deja/g++.other/redecl2.C	6 Jun 2005 13:57:54 -0000
***************
*** 1,9 ****
  // { dg-do assemble  }
  
  struct S {
!   S(int);
!   S(int); // { dg-error "" } already declared
  
!   ~S();
!   ~S(); // { dg-error "" } already declared
  };
--- 1,9 ----
  // { dg-do assemble  }
  
  struct S {
!   S(int); // { dg-error "with" }
!   S(int); // { dg-error "overloaded" } already declared
  
!   ~S();// { dg-error "with" }
!   ~S(); // { dg-error "overloaded" } already declared
  };
Index: testsuite/g++.old-deja/g++.other/redecl4.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/redecl4.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 redecl4.C
*** testsuite/g++.old-deja/g++.other/redecl4.C	1 May 2003 02:02:50 -0000	1.2
--- testsuite/g++.old-deja/g++.other/redecl4.C	6 Jun 2005 13:57:54 -0000
***************
*** 1,7 ****
  // { dg-do assemble  }
  int main() {
    struct A {
!     void f();
!     void f();			// { dg-error "" } already declared
    };
  }
--- 1,7 ----
  // { dg-do assemble  }
  int main() {
    struct A {
!     void f();			// { dg-error "with" } already declared
!     void f();			// { dg-error "overloaded" } already declared
    };
  }
Index: testsuite/g++.old-deja/g++.pt/memtemp78.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.pt/memtemp78.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 memtemp78.C
*** testsuite/g++.old-deja/g++.pt/memtemp78.C	1 May 2003 02:02:55 -0000	1.3
--- testsuite/g++.old-deja/g++.pt/memtemp78.C	6 Jun 2005 13:57:56 -0000
*************** template struct B<int>;
*** 23,32 ****
  struct C 
  {
    template <class U>
!   void f() {}
  
    template <class U>
!   void f() {}  // { dg-error "" } redeclaration
  };
  
  
--- 23,32 ----
  struct C 
  {
    template <class U>
!   void f() {}  // { dg-error "with" } redeclaration
  
    template <class U>
!   void f() {}  // { dg-error "overloaded" } redeclaration
  };
  
  
*************** template struct D<int, double>;
*** 42,56 ****
  template <class T, class U>
  struct D2
  {
!   void f(T);
!   void f(U); // { dg-error "" } redeclaration 
  };
  
  template struct D2<int, int>; 
  
  struct E
  {
!   void f(); 
!   void f(); // { dg-error "" } redeclaration
  };
  
--- 42,56 ----
  template <class T, class U>
  struct D2
  {
!   void f(T); // { dg-error "with" } redeclaration 
!   void f(U); // { dg-error "overloaded" } redeclaration 
  };
  
  template struct D2<int, int>; 
  
  struct E
  {
!   void f();  // { dg-error "with" } redeclaration
!   void f(); // { dg-error "overloaded" } redeclaration
  };
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]