summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-30 20:20:55 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-06-30 20:20:55 +0000
commitee19f44b465d98d329e2bc321ccc8a4ba5e6d4fa (patch)
treef9fcc7a5e7a3e1bb84179bde977d34c49ec5c243 /gcc
parent9f4ec746affbde185eedfc5de139e8617061bbe3 (diff)
downloadgcc-ee19f44b465d98d329e2bc321ccc8a4ba5e6d4fa.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212174 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/testsuite/g++.dg/opt/devirt5.C19
5 files changed, 36 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index dba9c551bac..cc988333108 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d3bc71e01ce..1c28dd6fe98 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 99ea582f958..98897f4fb92 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 8edf5193750..f8cae283383 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 00000000000..f839cbeae20
--- /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 <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;