re PR c++/5645 (gcc warns that pure virtual class not explicitly initialized)

PR c++/5645
        PR c++/11159
        * class.c (type_has_user_nondefault_constructor): New fn.
        * cp-tree.h: Declare it.
        * init.c (emit_mem_initializers): Use it for -W warning about
        missing base initializer.

Co-Authored-By: Jason Merrill <jason@redhat.com>

From-SVN: r132324
This commit is contained in:
Manuel López-Ibáñez 2008-02-14 18:11:04 -05:00 committed by Jason Merrill
parent 101e174d2c
commit 8c95264b5c
7 changed files with 108 additions and 5 deletions

View File

@ -1,3 +1,13 @@
2008-02-14 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
Jason Merrill <jason@redhat.com>
PR c++/5645
PR c++/11159
* class.c (type_has_user_nondefault_constructor): New fn.
* cp-tree.h: Declare it.
* init.c (emit_mem_initializers): Use it for -W warning about
missing base initializer.
2008-02-14 Paolo Carlini <pcarlini@suse.de>
PR c++/28743

View File

@ -4039,6 +4039,28 @@ clone_constructors_and_destructors (tree t)
clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1);
}
/* Returns true iff class T has a user-defined constructor other than
the default constructor. */
bool
type_has_user_nondefault_constructor (tree t)
{
tree fns;
if (!TYPE_HAS_USER_CONSTRUCTOR (t))
return false;
for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
{
tree fn = OVL_CURRENT (fns);
if (!DECL_ARTIFICIAL (fn)
&& skip_artificial_parms_for (fn, DECL_ARGUMENTS (fn)) != NULL_TREE)
return true;
}
return false;
}
/* Remove all zero-width bit-fields from T. */
static void

View File

@ -4157,6 +4157,7 @@ extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
extern bool type_has_user_nondefault_constructor (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);

View File

@ -829,12 +829,13 @@ emit_mem_initializers (tree mem_inits)
tree subobject = TREE_PURPOSE (mem_inits);
tree arguments = TREE_VALUE (mem_inits);
/* If these initializations are taking place in a copy
constructor, the base class should probably be explicitly
initialized. */
/* If these initializations are taking place in a copy constructor,
the base class should probably be explicitly initialized if there
is a user-defined constructor in the base class (other than the
default constructor, which will be called anyway). */
if (extra_warnings && !arguments
&& DECL_COPY_CONSTRUCTOR_P (current_function_decl)
&& TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (subobject)))
&& type_has_user_nondefault_constructor (BINFO_TYPE (subobject)))
warning (OPT_Wextra, "%Jbase class %q#T should be explicitly initialized in the "
"copy constructor",
current_function_decl, BINFO_TYPE (subobject));

View File

@ -10,5 +10,5 @@ struct T {
struct U : virtual public S, virtual public T {
U () : T (), S () {} // { dg-warning "" }
U (const U&) : S () {} // { dg-warning "copy" }
U (const U&) : S () {}
};

View File

@ -0,0 +1,37 @@
// PR c++/11159 : erroneous warning in copy ctor with virtual inheritance
// { dg-do compile }
// { dg-options "-Wall -Wextra" }
struct A
{
A ();
};
struct B : virtual A
{
B ();
};
struct C : virtual A
{
C ();
};
struct D : B, C
{
D (D const&){}
};
template <typename Base>
struct E : Base
{
E ();
E (E const &)
: Base ()
{
};
};
E<C> foo;
E<C> bar (foo);

View File

@ -0,0 +1,32 @@
// PR5645: gcc warns that pure virtual class not explicitly initialized.
// { dg-do compile }
// { dg-options "-Wall -Wextra" }
class a {
public:
virtual int f() = 0;
virtual int g() = 0;
};
class b : public a {
public:
b();
b(const b& c);
protected:
int i;
};
b::b() {}
b::b(const b& c) { // { dg-bogus "base class .class a. should be explicitly initialized in the copy constructor" }
i = c.i;
}
struct X {};
struct Y : X
{
Y (Y const&) {}
};