re PR ipa/61659 (Extra undefined symbol because of devirtualization)
authorJason Merrill <jason@redhat.com>
Thu, 10 Jul 2014 19:29:59 +0000 (15:29 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 10 Jul 2014 19:29:59 +0000 (15:29 -0400)
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

gcc/c-family/ChangeLog
gcc/c-family/c.opt
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/testsuite/g++.dg/template/dtor9.C
gcc/testsuite/g++.dg/template/dtor9a.C [new file with mode: 0644]

index 24455978734fc88a8f656ec0daeb7d53f050ae15..23c5c8274a6d35cbf4cdfbeb3c834344a43e75d0 100644 (file)
@@ -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
index faef774e8c4c8dd4547ffecb7981158607fec97f..3a2084f60567b008aa5bfcdd09a2283b2ff2bfed 100644 (file)
@@ -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
index 5827bbdf3de5c32f774976eae764026c78caa345..a184a401d9f289c8084d7e8cfbb5e9d4527cc4cd 100644 (file)
@@ -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
index 3a44dba9db175ec7383f8e2594edc276a8c4e0e1..d0eb1033ef280074c525214153df9a0d436f4439 100644 (file)
@@ -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);
     }
 
index 1ade5861d581e0b67821b690c3f64be15566d88a..01d74e34f923be48b9ab550836fab3ac3bb172ca 100644 (file)
@@ -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))
                      {
index 98897f4fb9258e4c1dd61d15e5d33c3641dd89e8..0926dbc60fcdb4854edafeabf83ad4d556117a77 100644 (file)
@@ -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;
 \f
 
 /* 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);
index fd71389b865bc9f440bd4494b46fbc7fa7cc95e9..006a75489d6b2f74e9e4b77a2e04bbf577982997 100644 (file)
@@ -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 (file)
index 0000000..aaae8b6
--- /dev/null
@@ -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> { };