Commit 880a467b by Nathan Sidwell Committed by Nathan Sidwell

invoke.texi (Wnon-virtual-dtor): Adjust documentation.

	* doc/invoke.texi (Wnon-virtual-dtor): Adjust documentation.
	(Weffc++): Remove Scott's numbering, merge lists and reference
	Wnon-virtual-dtor.

	c-family/
	* c.opt (Wnon-virtual-dtor): Auto set when Weffc++.

	cp/
	* class.c (accessible_nvdtor_p): New.
	(check_bases): Don't check base destructor here ...
	(check_bases_and_members): ... check them here.  Trigger on
	Wnon-virtual-dtor flag.
	(finish_struct_1): Use accessible_nvdtor_p.

	testsuite/
	* g++.dg/warn/Wnvdtor.C: Add non-polymorphic case.
	* g++.dg/warn/Wnvdtor-2.C: New.
	* g++.dg/warn/Wnvdtor-3.C: New.
	* g++.dg/warn/Wnvdtor-4.C: New.
	* g++.dg/warn/Weff1.C: Delete.
	* g++.old-deja/g++.benjamin/15309-1.C: Delete.
	* g++.old-deja/g++.benjamin/15309-2.C: Delete.

From-SVN: r209056
parent 08866760
2014-04-03 Nathan Sidwell <nathan@codesourcery.com>
* doc/invoke.texi (Wnon-virtual-dtor): Adjust documentation.
(Weffc++): Remove Scott's numbering, merge lists and reference
Wnon-virtual-dtor.
c-family/
cp/
* class.c (accessible_nvdtor_p): New.
(check_bases): Don't check base destructor here ...
(check_bases_and_members): ... check them here. Trigger on
Wnon-virtual-dtor flag.
(finish_struct_1): Use accessible_nvdtor_p.
testsuite/
* g++.dg/warn/Wnvdtor.C: Add non-polymorphic case.
* g++.dg/warn/Wnvdtor-2.C: New.
* g++.dg/warn/Wnvdtor-3.C: New.
* g++.dg/warn/Wnvdtor-4.C: New.
* g++.dg/warn/Weff1.C: Delete.
* g++.old-deja/g++.benjamin/15309-1.C: Delete.
* g++.old-deja/g++.benjamin/15309-2.C: Delete.
2014-04-03 Nick Clifton <nickc@redhat.com>
* config/rl78/rl78-expand.md (movqi): Handle (SUBREG (SYMBOL_REF))
......
2014-04-03 Nathan Sidwell <nathan@codesourcery.com>
* c.opt (Wnon-virtual-dtor): Auto set when Weffc++.
2014-04-02 Marek Polacek <polacek@redhat.com>
* c-common.h (c_expand_expr): Remove declaration.
......
......@@ -569,7 +569,7 @@ C++ ObjC++ Var(warn_nontemplate_friend) Init(1) Warning
Warn when non-templatized friend functions are declared within a template
Wnon-virtual-dtor
C++ ObjC++ Var(warn_nonvdtor) Warning
C++ ObjC++ Var(warn_nonvdtor) Warning LangEnabledBy(C++ ObjC++,Weffc++)
Warn about non-virtual destructors
Wnonnull
......
2014-04-03 Nathan Sidwell <nathan@codesourcery.com>
* class.c (accessible_nvdtor_p): New.
(check_bases): Don't check base destructor here ...
(check_bases_and_members): ... check them here. Trigger on
Wnon-virtual-dtor flag.
(finish_struct_1): Use accessible_nvdtor_p.
2014-04-01 Jason Merrill <jason@redhat.com>
* pt.c (process_partial_specialization): Say "not deducible"
......
......@@ -149,6 +149,7 @@ static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
static void build_base_fields (record_layout_info, splay_tree, tree *);
static void check_methods (tree);
static void remove_zero_width_bit_fields (tree);
static bool accessible_nvdtor_p (tree);
static void check_bases (tree, int *, int *);
static void check_bases_and_members (tree);
static tree create_vtable_ptr (tree, tree *);
......@@ -1476,6 +1477,33 @@ inherit_targ_abi_tags (tree t)
mark_type_abi_tags (t, false);
}
/* Return true, iff class T has a non-virtual destructor that is
accessible from outside the class heirarchy (i.e. is public, or
there's a suitable friend. */
static bool
accessible_nvdtor_p (tree t)
{
tree dtor = CLASSTYPE_DESTRUCTORS (t);
/* An implicitly declared destructor is always public. And,
if it were virtual, we would have created it by now. */
if (!dtor)
return true;
if (DECL_VINDEX (dtor))
return false; /* Virtual */
if (!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
return true; /* Public */
if (CLASSTYPE_FRIEND_CLASSES (t)
|| DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))
return true; /* Has friends */
return false;
}
/* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
and NO_CONST_ASN_REF_P. Also set flag bits in T based on
properties of the bases. */
......@@ -1512,13 +1540,6 @@ check_bases (tree t,
if (!CLASSTYPE_LITERAL_P (basetype))
CLASSTYPE_LITERAL_P (t) = false;
/* Effective C++ rule 14. We only need to check TYPE_POLYMORPHIC_P
here because the case of virtual functions but non-virtual
dtor is handled in finish_struct_1. */
if (!TYPE_POLYMORPHIC_P (basetype))
warning (OPT_Weffc__,
"base class %q#T has a non-virtual destructor", basetype);
/* If the base class doesn't have copy constructors or
assignment operators that take const references, then the
derived class cannot have such a member automatically
......@@ -5547,6 +5568,27 @@ check_bases_and_members (tree t)
TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
/* Warn if a base of a polymorphic type has an accessible
non-virtual destructor. It is only now that we know the class is
polymorphic. Although a polymorphic base will have a already
been diagnosed during its definition, we warn on use too. */
if (TYPE_POLYMORPHIC_P (t) && warn_nonvdtor)
{
tree binfo, base_binfo;
unsigned i;
for (binfo = TYPE_BINFO (t), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
{
tree basetype = TREE_TYPE (base_binfo);
if (accessible_nvdtor_p (basetype))
warning (OPT_Wnon_virtual_dtor,
"base class %q#T has accessible non-virtual destructor",
basetype);
}
}
/* If the class has no user-declared constructor, but does have
non-static const or reference data members that can never be
initialized, issue a warning. */
......@@ -6597,25 +6639,11 @@ finish_struct_1 (tree t)
/* This warning does not make sense for Java classes, since they
cannot have destructors. */
if (!TYPE_FOR_JAVA (t) && warn_nonvdtor && TYPE_POLYMORPHIC_P (t))
{
tree dtor;
dtor = CLASSTYPE_DESTRUCTORS (t);
if (/* An implicitly declared destructor is always public. And,
if it were virtual, we would have created it by now. */
!dtor
|| (!DECL_VINDEX (dtor)
&& (/* public non-virtual */
(!TREE_PRIVATE (dtor) && !TREE_PROTECTED (dtor))
|| (/* non-public non-virtual with friends */
(TREE_PRIVATE (dtor) || TREE_PROTECTED (dtor))
&& (CLASSTYPE_FRIEND_CLASSES (t)
|| DECL_FRIENDLIST (TYPE_MAIN_DECL (t)))))))
if (!TYPE_FOR_JAVA (t) && warn_nonvdtor
&& TYPE_POLYMORPHIC_P (t) && accessible_nvdtor_p (t))
warning (OPT_Wnon_virtual_dtor,
"%q#T has virtual functions and accessible"
" non-virtual destructor", t);
}
complete_vars (t);
......
......@@ -2670,9 +2670,10 @@ the compiler to never throw an exception.
@opindex Wnon-virtual-dtor
@opindex Wno-non-virtual-dtor
Warn when a class has virtual functions and an accessible non-virtual
destructor, in which case it is possible but unsafe to delete
an instance of a derived class through a pointer to the base class.
This warning is also enabled if @option{-Weffc++} is specified.
destructor itself or in a base class, or has in which case it is
possible but unsafe to delete an instance of a derived class through a
pointer to the base class. This warning is automatically enabled if
@option{-Weffc++} is specified.
@item -Wreorder @r{(C++ and Objective-C++ only)}
@opindex Wreorder
......@@ -2716,40 +2717,34 @@ The following @option{-W@dots{}} options are not affected by @option{-Wall}.
@opindex Weffc++
@opindex Wno-effc++
Warn about violations of the following style guidelines from Scott Meyers'
@cite{Effective C++, Second Edition} book:
@cite{Effective C++} series of books:
@itemize @bullet
@item
Item 11: Define a copy constructor and an assignment operator for classes
Define a copy constructor and an assignment operator for classes
with dynamically-allocated memory.
@item
Item 12: Prefer initialization to assignment in constructors.
Prefer initialization to assignment in constructors.
@item
Item 14: Make destructors virtual in base classes.
Have @code{operator=} return a reference to @code{*this}.
@item
Item 15: Have @code{operator=} return a reference to @code{*this}.
Don't try to return a reference when you must return an object.
@item
Item 23: Don't try to return a reference when you must return an object.
@end itemize
Also warn about violations of the following style guidelines from
Scott Meyers' @cite{More Effective C++} book:
@itemize @bullet
@item
Item 6: Distinguish between prefix and postfix forms of increment and
Distinguish between prefix and postfix forms of increment and
decrement operators.
@item
Item 7: Never overload @code{&&}, @code{||}, or @code{,}.
Never overload @code{&&}, @code{||}, or @code{,}.
@end itemize
This option also enables @option{-Wnon-virtual-dtor}, which is also
one of the effective C++ recommendations.
When selecting this option, be aware that the standard library
headers do not obey all of these guidelines; use @samp{grep -v}
to filter out those warnings.
......
2014-04-03 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/warn/Wnvdtor.C: Add non-polymorphic case.
* g++.dg/warn/Wnvdtor-2.C: New.
* g++.dg/warn/Wnvdtor-3.C: New.
* g++.dg/warn/Wnvdtor-4.C: New.
* g++.dg/warn/Weff1.C: Delete.
* g++.old-deja/g++.benjamin/15309-1.C: Delete.
* g++.old-deja/g++.benjamin/15309-2.C: Delete.
2014-04-02 Jan Hubicka <hubicka@ucw.cz>
PR ipa/60659
......
// { dg-options "-Weffc++" }
struct S {};
/* Base classes should have virtual destructors. */
struct T : public S {}; // { dg-warning "" }
......@@ -6,18 +6,18 @@
// destructor, in which case it would be possible but unsafe to delete
// an instance of a derived class through a pointer to the base class.
struct A // { dg-bogus "non-virtual destructor" }
struct A
{
protected:
~A();
~A(); // inaccessible - no warning
public:
virtual void f() = 0;
};
struct B // { dg-bogus "non-virtual destructor" }
struct B
{
private:
~B();
~B(); // inaccessible - no warning
public:
virtual void f() = 0;
};
......@@ -52,3 +52,6 @@ private:
public:
virtual void f() = 0;
};
struct H {};
struct I : H {};
// { dg-do compile }
// { dg-options "-Weffc++" }
// Warn when a class has virtual functions and accessible non-virtual
// destructor, in which case it would be possible but unsafe to delete
// an instance of a derived class through a pointer to the base class.
struct A
{
protected:
~A(); // inaccessible - no warning
public:
virtual void f() = 0;
};
struct B
{
private:
~B(); // inaccessible - no warning
public:
virtual void f() = 0;
};
struct C // { dg-warning "non-virtual destructor" }
{
virtual void f() = 0;
};
struct D // { dg-warning "non-virtual destructor" }
{
~D();
virtual void f() = 0;
};
struct E;
struct F // { dg-warning "non-virtual destructor" }
{
protected:
friend class E;
~F();
public:
virtual void f() = 0;
};
struct G // { dg-warning "non-virtual destructor" }
{
private:
friend class E;
~G();
public:
virtual void f() = 0;
};
struct H {};
struct I : H {};
// { dg-do compile }
// { dg-options "-Weffc++ -Wno-non-virtual-dtor" }
// Warn when a class has virtual functions and accessible non-virtual
// destructor, in which case it would be possible but unsafe to delete
// an instance of a derived class through a pointer to the base class.
struct A
{
protected:
~A();
public:
virtual void f() = 0;
};
struct B
{
private:
~B();
public:
virtual void f() = 0;
};
struct C
{
virtual void f() = 0;
};
struct D
{
~D();
virtual void f() = 0;
};
struct E;
struct F
{
protected:
friend class E;
~F();
public:
virtual void f() = 0;
};
struct G
{
private:
friend class E;
~G();
public:
virtual void f() = 0;
};
struct H {};
struct I : H {};
......@@ -8,3 +8,4 @@ extern "Java"
virtual void bar( void);
};
}
// { dg-do assemble }
// { dg-options "-Wnon-virtual-dtor -Weffc++" }
// 981203 bkoz
// g++/15309
class bahamian {
public:
bahamian ();
~bahamian ();
};
class miami : public bahamian // { dg-warning "" } // WARNING -
{
public:
miami ();
~miami ();
};
// { dg-do assemble }
// { dg-options "-Wnon-virtual-dtor -Weffc++" }
// 981203 bkoz
// g++/15309
class bermuda { // { dg-warning "" } // WARNING -
public:
virtual int func1(int);
~bermuda();
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment