Commit c0221884 by Jason Merrill Committed by Jason Merrill

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
parent 7757d79b
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> 2014-07-09 Richard Biener <rguenther@suse.de>
PR c-family/61741 PR c-family/61741
......
...@@ -1268,6 +1268,10 @@ funsigned-char ...@@ -1268,6 +1268,10 @@ funsigned-char
C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0) C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0)
Make \"char\" unsigned by default 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 fuse-cxa-atexit
C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT) C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT)
Use __cxa_atexit to register destructors Use __cxa_atexit to register destructors
......
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> 2014-07-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/60686 PR c++/60686
......
...@@ -6408,7 +6408,7 @@ finish_struct_1 (tree t) ...@@ -6408,7 +6408,7 @@ finish_struct_1 (tree t)
in every translation unit where the class definition appears. If in every translation unit where the class definition appears. If
we're devirtualizing, we can look into the vtable even if we we're devirtualizing, we can look into the vtable even if we
aren't emitting it. */ 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); keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
} }
......
...@@ -9631,8 +9631,11 @@ grokdeclarator (const cp_declarator *declarator, ...@@ -9631,8 +9631,11 @@ grokdeclarator (const cp_declarator *declarator,
"-std=gnu++1y"); "-std=gnu++1y");
} }
else if (virtualp) 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)) else if (!is_auto (type))
{ {
......
...@@ -106,6 +106,11 @@ static GTY(()) vec<tree, va_gc> *no_linkage_decls; ...@@ -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. */ /* Nonzero if we're done parsing and into end-of-file activities. */
int at_eof; 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 /* Return a member function type (a METHOD_TYPE), given FNTYPE (a
...@@ -2009,7 +2014,7 @@ maybe_emit_vtables (tree ctype) ...@@ -2009,7 +2014,7 @@ maybe_emit_vtables (tree ctype)
if (DECL_COMDAT (primary_vtbl) if (DECL_COMDAT (primary_vtbl)
&& CLASSTYPE_DEBUG_REQUESTED (ctype)) && CLASSTYPE_DEBUG_REQUESTED (ctype))
note_debug_info_needed (ctype); note_debug_info_needed (ctype);
if (flag_devirtualize) if (mark_all_virtuals)
/* Make sure virtual functions get instantiated/synthesized so that /* Make sure virtual functions get instantiated/synthesized so that
they can be inlined after devirtualization even if the vtable is they can be inlined after devirtualization even if the vtable is
never emitted. */ never emitted. */
...@@ -4340,6 +4345,8 @@ cp_write_global_declarations (void) ...@@ -4340,6 +4345,8 @@ cp_write_global_declarations (void)
instantiated, etc., etc. */ instantiated, etc., etc. */
emit_support_tinfos (); emit_support_tinfos ();
int errs = errorcount + sorrycount;
bool explained_devirt = false;
do do
{ {
...@@ -4572,6 +4579,27 @@ cp_write_global_declarations (void) ...@@ -4572,6 +4579,27 @@ cp_write_global_declarations (void)
pending_statics->length ())) pending_statics->length ()))
reconsider = true; 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++; retries++;
} }
while (reconsider); while (reconsider);
......
// PR c++/60347 // PR c++/60347
// { dg-options "-fno-use-all-virtuals" }
struct A; struct A;
......
// 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> { };
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