]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR ipa/61659 (Extra undefined symbol because of devirtualization)
authorJason Merrill <jason@redhat.com>
Mon, 30 Jun 2014 20:20:55 +0000 (16:20 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 30 Jun 2014 20:20:55 +0000 (16:20 -0400)
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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl2.c
gcc/cp/init.c
gcc/testsuite/g++.dg/opt/devirt5.C [new file with mode: 0644]
libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/cxxabi.h

index dba9c551bacfc8f2b64a5fc816de89355c233c56..cc9883331083feaad0d9184b46afd8c5d0878999 100644 (file)
@@ -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.
 
index d3bc71e01ce5a2aa7c800e68064e8cc8afdb5206..1c28dd6fe98660a95cbe472b57da4d67cc1301ab 100644 (file)
@@ -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);
     }
 
index 99ea582f9588e9862aeb9072c5a4511d2f0bec42..98897f4fb9258e4c1dd61d15e5d33c3641dd89e8 100644 (file)
@@ -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;
     }
 
index 8edf5193750440a758ed81f315378e5c1b471622..f8cae283383dc49e75265afd2bb46f37d8d483ea 100644 (file)
@@ -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 (file)
index 0000000..f839cbe
--- /dev/null
@@ -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;
index 170f608c47b702ff0919cb350b035387f9bd4180..1d6cf7a5bd8c29ca889f0b97f595e41bf6092b5e 100644 (file)
@@ -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:
index ab87321985e6101ba239ff9abc8dc874a2b83b26..5b77aee9e6c5eab0c824fd5554928e411a09b393 100644 (file)
@@ -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.