re PR c++/8211 (-Weffc++ warns about copyable classes with func ptr members)
PR c++/8211 PR c++/16165 * class.c (check_field_decls): Improve -Weffc++ warning: do not warn for pointers to functions/members, or for classes without destructors. PR c++/8211 PR c++/16165 * g++.dg/warn/effc3.C: New test. From-SVN: r84338
This commit is contained in:
parent
45dc67b726
commit
dd29d26b24
|
@ -1,3 +1,11 @@
|
||||||
|
2004-07-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR c++/8211
|
||||||
|
PR c++/16165
|
||||||
|
* class.c (check_field_decls): Improve -Weffc++ warning: do not
|
||||||
|
warn for pointers to functions/members, or for classes without
|
||||||
|
destructors.
|
||||||
|
|
||||||
2004-07-08 Mark Mitchell <mark@codesourcery.com>
|
2004-07-08 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
* name-lookup.h (struct cp_binding_level): Update documentation
|
* name-lookup.h (struct cp_binding_level): Update documentation
|
||||||
|
|
|
@ -2925,13 +2925,13 @@ check_field_decls (tree t, tree *access_decls,
|
||||||
{
|
{
|
||||||
tree *field;
|
tree *field;
|
||||||
tree *next;
|
tree *next;
|
||||||
int has_pointers;
|
bool has_pointers;
|
||||||
int any_default_members;
|
int any_default_members;
|
||||||
|
|
||||||
/* Assume there are no access declarations. */
|
/* Assume there are no access declarations. */
|
||||||
*access_decls = NULL_TREE;
|
*access_decls = NULL_TREE;
|
||||||
/* Assume this class has no pointer members. */
|
/* Assume this class has no pointer members. */
|
||||||
has_pointers = 0;
|
has_pointers = false;
|
||||||
/* Assume none of the members of this class have default
|
/* Assume none of the members of this class have default
|
||||||
initializations. */
|
initializations. */
|
||||||
any_default_members = 0;
|
any_default_members = 0;
|
||||||
|
@ -3073,8 +3073,13 @@ check_field_decls (tree t, tree *access_decls,
|
||||||
|
|
||||||
type = strip_array_types (type);
|
type = strip_array_types (type);
|
||||||
|
|
||||||
if (TYPE_PTR_P (type))
|
/* This is used by -Weffc++ (see below). Warn only for pointers
|
||||||
has_pointers = 1;
|
to members which might hold dynamic memory. So do not warn
|
||||||
|
for pointers to functions or pointers to members. */
|
||||||
|
if (TYPE_PTR_P (type)
|
||||||
|
&& !TYPE_PTRFN_P (type)
|
||||||
|
&& !TYPE_PTR_TO_MEMBER_P (type))
|
||||||
|
has_pointers = true;
|
||||||
|
|
||||||
if (CLASS_TYPE_P (type))
|
if (CLASS_TYPE_P (type))
|
||||||
{
|
{
|
||||||
|
@ -3140,9 +3145,25 @@ check_field_decls (tree t, tree *access_decls,
|
||||||
&any_default_members);
|
&any_default_members);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Effective C++ rule 11. */
|
/* Effective C++ rule 11: if a class has dynamic memory held by pointers,
|
||||||
if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
|
it should also define a copy constructor and an assignment operator to
|
||||||
&& ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
|
implement the correct copy semantic (deep vs shallow, etc.). As it is
|
||||||
|
not feasible to check whether the constructors do allocate dynamic memory
|
||||||
|
and store it within members, we approximate the warning like this:
|
||||||
|
|
||||||
|
-- Warn only if there are members which are pointers
|
||||||
|
-- Warn only if there is a non-trivial constructor (otherwise,
|
||||||
|
there cannot be memory allocated).
|
||||||
|
-- Warn only if there is a non-trivial destructor. We assume that the
|
||||||
|
user at least implemented the cleanup correctly, and a destructor
|
||||||
|
is needed to free dynamic memory.
|
||||||
|
|
||||||
|
This seems enough for pratical purposes. */
|
||||||
|
if (warn_ecpp
|
||||||
|
&& has_pointers
|
||||||
|
&& TYPE_HAS_CONSTRUCTOR (t)
|
||||||
|
&& TYPE_HAS_DESTRUCTOR (t)
|
||||||
|
&& !(TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
|
||||||
{
|
{
|
||||||
warning ("`%#T' has pointer data members", t);
|
warning ("`%#T' has pointer data members", t);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2004-07-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR c++/8211
|
||||||
|
PR c++/16165
|
||||||
|
* g++.dg/warn/effc3.C: New test.
|
||||||
|
|
||||||
2004-07-09 David Billinghurst (David.Billinghurst@riotinto.com)
|
2004-07-09 David Billinghurst (David.Billinghurst@riotinto.com)
|
||||||
|
|
||||||
* gfortran.dg/g77/f77-edit-i-in.f: Copy from g77.dg and
|
* gfortran.dg/g77/f77-edit-i-in.f: Copy from g77.dg and
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
// { dg-options "-Weffc++" }
|
||||||
|
// Contributed by Benjamin Kosnik <bkoz at redhat dot com>
|
||||||
|
// PR c++/16165 and PR c++/8211: Improve item 11 of -Weffc++
|
||||||
|
|
||||||
|
|
||||||
|
// We should not warn for this class since this kind of pointers can
|
||||||
|
// never hold dynamic memory.
|
||||||
|
struct A {
|
||||||
|
void (*func1)(void);
|
||||||
|
void (A::*func2)(void);
|
||||||
|
int A::*func3;
|
||||||
|
|
||||||
|
int a;
|
||||||
|
void b(void);
|
||||||
|
|
||||||
|
A();
|
||||||
|
~A();
|
||||||
|
};
|
||||||
|
|
||||||
|
// We do not warn for this class because there is no destructor, so we
|
||||||
|
// assume there is no dynamic memory allocated (it could point to a
|
||||||
|
// global variable).
|
||||||
|
struct B {
|
||||||
|
int *ptr;
|
||||||
|
B();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// We should emit a warning for these
|
||||||
|
struct C1 { // { dg-warning "" "" }
|
||||||
|
int *ptr;
|
||||||
|
C1();
|
||||||
|
~C1();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C2 { // { dg-warning "" "" }
|
||||||
|
int *ptr;
|
||||||
|
C2();
|
||||||
|
C2(const C2&);
|
||||||
|
~C2();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct C3 { // { dg-warning "" "" }
|
||||||
|
int *ptr;
|
||||||
|
C3();
|
||||||
|
~C3();
|
||||||
|
C3& operator=(const C3&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// But not for this
|
||||||
|
struct C4 {
|
||||||
|
int *ptr;
|
||||||
|
C4();
|
||||||
|
C4(const C4&);
|
||||||
|
~C4();
|
||||||
|
C4& operator=(const C4&);
|
||||||
|
};
|
Loading…
Reference in New Issue