This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix 20637
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 06 Jun 2005 15:16:35 +0100
- Subject: [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
};