mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-12-25 03:55:32 +08:00
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
This commit is contained in:
parent
fc56f9d284
commit
5796bf3422
@ -1,5 +1,13 @@
|
||||
2014-06-30 Jason Merrill <jason@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
19
gcc/testsuite/g++.dg/opt/devirt5.C
Normal file
19
gcc/testsuite/g++.dg/opt/devirt5.C
Normal file
@ -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 <class DataType> struct parser : public generic_parser_base {
|
||||
virtual void getOption() {}
|
||||
};
|
||||
struct PassNameParser : public parser<int> {
|
||||
PassNameParser();
|
||||
};
|
||||
struct list {
|
||||
PassNameParser Parser;
|
||||
virtual void getExtraOptionNames() { return Parser.getExtraOptionNames(); }
|
||||
};
|
||||
list PassList;
|
@ -1,3 +1,8 @@
|
||||
2014-06-30 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* libsupc++/cxxabi.h (class __pbase_type_info): __pointer_catch
|
||||
is pure, not inline.
|
||||
|
||||
2014-06-28 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
Revert:
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user