diff options
author | Jason Merrill <jason@redhat.com> | 2014-07-10 15:29:59 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-07-10 15:29:59 -0400 |
commit | c0221884ecbda8d99a43aa0f5e306638c71533d6 (patch) | |
tree | 7cef2e435d85f003b0320c564b270b29bbcc9dca | |
parent | 7757d79bfcce1f13facc96a420eea4bcd542a3e2 (diff) | |
download | gcc-c0221884ecbda8d99a43aa0f5e306638c71533d6.zip gcc-c0221884ecbda8d99a43aa0f5e306638c71533d6.tar.gz gcc-c0221884ecbda8d99a43aa0f5e306638c71533d6.tar.bz2 |
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
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c.opt | 4 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 7 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/dtor9.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/dtor9a.C | 13 |
8 files changed, 70 insertions, 4 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2445597..23c5c82 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -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 diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index faef774..3a2084f 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5827bbd..a184a40 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 3a44dba..d0eb103 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); } diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1ade586..01d74e3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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)) { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 98897f4..0926dbc 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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); diff --git a/gcc/testsuite/g++.dg/template/dtor9.C b/gcc/testsuite/g++.dg/template/dtor9.C index fd71389..006a754 100644 --- a/gcc/testsuite/g++.dg/template/dtor9.C +++ b/gcc/testsuite/g++.dg/template/dtor9.C @@ -1,4 +1,5 @@ // PR c++/60347 +// { dg-options "-fno-use-all-virtuals" } struct A; diff --git a/gcc/testsuite/g++.dg/template/dtor9a.C b/gcc/testsuite/g++.dg/template/dtor9a.C new file mode 100644 index 0000000..aaae8b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dtor9a.C @@ -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> { }; |