re PR ipa/61659 (Extra undefined symbol because of devirtualization)

PR c++/61659
	PR c++/61687
gcc/c-family/
	* c.opt (-fuse-all-virtuals): New.
gcc/cp/
	* decl2.c (mark_all_virtuals): New variable.
	(maybe_emit_vtables): Check it instead of flag_devirtualize.
	(cp_write_global_declarations): Set it and give helpful diagnostic
	if it introduces errors.
	* class.c (finish_struct_1): Check it.
	* decl.c (grokdeclarator): Clear virtualp after 'virtual auto' error.

From-SVN: r212436
This commit is contained in:
Jason Merrill 2014-07-10 15:29:59 -04:00 committed by Jason Merrill
parent 7757d79bfc
commit c0221884ec
8 changed files with 70 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2014-07-10 Jason Merrill <jason@redhat.com>
PR c++/61659
PR c++/61687
* c.opt (-fuse-all-virtuals): New.
2014-07-09 Richard Biener <rguenther@suse.de>
PR c-family/61741

View File

@ -1268,6 +1268,10 @@ funsigned-char
C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0)
Make \"char\" unsigned by default
fuse-all-virtuals
C++ ObjC++ Var(flag_use_all_virtuals) Init(1)
Treat all virtual functions as odr-used
fuse-cxa-atexit
C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT)
Use __cxa_atexit to register destructors

View File

@ -1,3 +1,14 @@
2014-07-10 Jason Merrill <jason@redhat.com>
PR c++/61659
PR c++/61687
* decl2.c (mark_all_virtuals): New variable.
(maybe_emit_vtables): Check it instead of flag_devirtualize.
(cp_write_global_declarations): Set it and give helpful diagnostic
if it introduces errors.
* class.c (finish_struct_1): Check it.
* decl.c (grokdeclarator): Clear virtualp after 'virtual auto' error.
2014-07-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60686

View File

@ -6408,7 +6408,7 @@ finish_struct_1 (tree t)
in every translation unit where the class definition appears. If
we're devirtualizing, we can look into the vtable even if we
aren't emitting it. */
if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE || flag_devirtualize)
if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE || flag_use_all_virtuals)
keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
}

View File

@ -9631,8 +9631,11 @@ grokdeclarator (const cp_declarator *declarator,
"-std=gnu++1y");
}
else if (virtualp)
error ("virtual function cannot "
"have deduced return type");
{
error ("virtual function cannot "
"have deduced return type");
virtualp = false;
}
}
else if (!is_auto (type))
{

View File

@ -106,6 +106,11 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls;
/* Nonzero if we're done parsing and into end-of-file activities. */
int at_eof;
/* Nonzero if we've instantiated everything used directly, and now want to
mark all virtual functions as used so that they are available for
devirtualization. */
static int mark_all_virtuals;
/* Return a member function type (a METHOD_TYPE), given FNTYPE (a
@ -2009,7 +2014,7 @@ maybe_emit_vtables (tree ctype)
if (DECL_COMDAT (primary_vtbl)
&& CLASSTYPE_DEBUG_REQUESTED (ctype))
note_debug_info_needed (ctype);
if (flag_devirtualize)
if (mark_all_virtuals)
/* Make sure virtual functions get instantiated/synthesized so that
they can be inlined after devirtualization even if the vtable is
never emitted. */
@ -4340,6 +4345,8 @@ cp_write_global_declarations (void)
instantiated, etc., etc. */
emit_support_tinfos ();
int errs = errorcount + sorrycount;
bool explained_devirt = false;
do
{
@ -4572,6 +4579,27 @@ cp_write_global_declarations (void)
pending_statics->length ()))
reconsider = true;
if (flag_use_all_virtuals)
{
if (!reconsider && !mark_all_virtuals)
{
mark_all_virtuals = true;
reconsider = true;
errs = errorcount + sorrycount;
}
else if (mark_all_virtuals
&& !explained_devirt
&& (errorcount + sorrycount > errs))
{
inform (global_dc->last_location, "this error is seen due to "
"instantiation of all virtual functions, which the C++ "
"standard says are always considered used; this is done "
"to support devirtualization optimizations, but can be "
"disabled with -fno-use-all-virtuals");
explained_devirt = true;
}
}
retries++;
}
while (reconsider);

View File

@ -1,4 +1,5 @@
// PR c++/60347
// { dg-options "-fno-use-all-virtuals" }
struct A;

View File

@ -0,0 +1,13 @@
// PR c++/60347
// { dg-options "-fuse-all-virtuals" }
struct A;
template <class T>
struct B
{
T* p;
virtual ~B() { p->~T(); } // { dg-error "incomplete" }
};
struct C: B<A> { };