From: Jason Merrill Date: Mon, 30 Jun 2014 20:20:55 +0000 (-0400) Subject: re PR ipa/61659 (Extra undefined symbol because of devirtualization) X-Git-Tag: releases/gcc-5.1.0~6561 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5796bf3422e2e7aa652020100c742fa6b26f40c9;p=thirdparty%2Fgcc.git re PR ipa/61659 (Extra undefined symbol because of devirtualization) PR c++/61659 PR lto/53808 gcc/cp * decl2.c (maybe_emit_vtables): Mark all vtable entries if devirtualizing. * init.c (build_vtbl_address): Don't mark destructor. * class.c (finish_struct_1): Add all classes to keyed_classes if devirtualizing. libstdc++-v3/ * libsupc++/cxxabi.h (class __pbase_type_info): __pointer_catch is pure, not inline. From-SVN: r212174 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dba9c551bacf..cc9883331083 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2014-06-30 Jason Merrill + PR c++/61659 + PR lto/53808 + * decl2.c (maybe_emit_vtables): Mark all vtable entries if + devirtualizing. + * init.c (build_vtbl_address): Don't mark destructor. + * class.c (finish_struct_1): Add all classes to keyed_classes + if devirtualizing. + PR c++/61647 * pt.c (type_dependent_expression_p): Check BASELINK_OPTYPE. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d3bc71e01ce5..1c28dd6fe986 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6405,8 +6405,10 @@ finish_struct_1 (tree t) determine_key_method (t); /* If a polymorphic class has no key method, we may emit the vtable - in every translation unit where the class definition appears. */ - if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE) + 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) keyed_classes = tree_cons (NULL_TREE, t, keyed_classes); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 99ea582f9588..98897f4fb925 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2009,6 +2009,11 @@ maybe_emit_vtables (tree ctype) if (DECL_COMDAT (primary_vtbl) && CLASSTYPE_DEBUG_REQUESTED (ctype)) note_debug_info_needed (ctype); + if (flag_devirtualize) + /* Make sure virtual functions get instantiated/synthesized so that + they can be inlined after devirtualization even if the vtable is + never emitted. */ + mark_vtable_entries (primary_vtbl); return false; } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 8edf51937504..f8cae283383d 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1155,12 +1155,6 @@ build_vtbl_address (tree binfo) /* Figure out what vtable BINFO's vtable is based on, and mark it as used. */ vtbl = get_vtbl_decl_for_binfo (binfo_for); - if (tree dtor = CLASSTYPE_DESTRUCTORS (DECL_CONTEXT (vtbl))) - if (!TREE_USED (vtbl) && DECL_VIRTUAL_P (dtor) && DECL_DEFAULTED_FN (dtor)) - /* Make sure the destructor gets synthesized so that it can be - inlined after devirtualization even if the vtable is never - emitted. */ - note_vague_linkage_fn (dtor); TREE_USED (vtbl) = true; /* Now compute the address to use when initializing the vptr. */ diff --git a/gcc/testsuite/g++.dg/opt/devirt5.C b/gcc/testsuite/g++.dg/opt/devirt5.C new file mode 100644 index 000000000000..f839cbeae206 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/devirt5.C @@ -0,0 +1,19 @@ +// PR c++/61659 +// { dg-options "-O3" } +// { dg-final { scan-assembler-not "_ZN6parserIiE9getOptionEv" } } + +struct generic_parser_base { + virtual void getOption(); + void getExtraOptionNames() { getOption(); } +}; +template struct parser : public generic_parser_base { + virtual void getOption() {} +}; +struct PassNameParser : public parser { + PassNameParser(); +}; +struct list { + PassNameParser Parser; + virtual void getExtraOptionNames() { return Parser.getExtraOptionNames(); } +}; +list PassList; diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 170f608c47b7..1d6cf7a5bd8c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2014-06-30 Jason Merrill + + * libsupc++/cxxabi.h (class __pbase_type_info): __pointer_catch + is pure, not inline. + 2014-06-28 Paolo Carlini Revert: diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h index ab87321985e6..5b77aee9e6c5 100644 --- a/libstdc++-v3/libsupc++/cxxabi.h +++ b/libstdc++-v3/libsupc++/cxxabi.h @@ -298,9 +298,9 @@ namespace __cxxabiv1 __do_catch(const std::type_info* __thr_type, void** __thr_obj, unsigned int __outer) const; - inline virtual bool + virtual bool __pointer_catch(const __pbase_type_info* __thr_type, void** __thr_obj, - unsigned __outer) const; + unsigned __outer) const = 0; }; // Type information for simple pointers.