Patchwork C++ PATCH for c++/50973 (ICE with defaulted virtual destructor)

login
register
mail settings
Submitter Jason Merrill
Date Nov. 10, 2011, 9:12 p.m.
Message ID <4EBC3E4D.2090301@redhat.com>
Download mbox | patch
Permalink /patch/125004/
State New
Headers show

Comments

Jason Merrill - Nov. 10, 2011, 9:12 p.m.
Here the problem was that we were calling use_thunk before we knew what 
the right linkage for the function it's thunking to was.  Fixed by 
deferring synthesis of virtual dtors until EOF.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 566d5469261e63f8359998386b3b7c60ecd5e2ba
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Nov 9 15:53:04 2011 -0500

    	PR c++/50973
    	* decl2.c (mark_used): Defer synthesis of virtual functions.
    	* method.c (use_thunk): Make sure the target function has
    	DECL_INTERFACE_KNOWN.

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 4e24755..05f4b42 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -4347,6 +4347,14 @@  mark_used (tree decl)
       && !DECL_DEFAULTED_OUTSIDE_CLASS_P (decl)
       && ! DECL_INITIAL (decl))
     {
+      /* Defer virtual destructors so that thunks get the right
+	 linkage.  */
+      if (DECL_VIRTUAL_P (decl) && !at_eof)
+	{
+	  note_vague_linkage_fn (decl);
+	  return true;
+	}
+
       /* Remember the current location for a function we will end up
 	 synthesizing.  Then we can inform the user where it was
 	 required in the case of error.  */
@@ -4358,7 +4366,7 @@  mark_used (tree decl)
 	 on the stack (such as overload resolution candidates).
 
          We could just let cp_write_global_declarations handle synthesizing
-         this function, since we just added it to deferred_fns, but doing
+         this function by adding it to deferred_fns, but doing
          it at the use site produces better error messages.  */
       ++function_depth;
       synthesize_method (decl);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index bb58312..8101f8a 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -339,6 +339,7 @@  use_thunk (tree thunk_fndecl, bool emit_p)
   DECL_EXTERNAL (thunk_fndecl) = 0;
   /* The linkage of the function may have changed.  FIXME in linkage
      rewrite.  */
+  gcc_assert (DECL_INTERFACE_KNOWN (function));
   TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
   DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
   DECL_VISIBILITY_SPECIFIED (thunk_fndecl)
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted33.C b/gcc/testsuite/g++.dg/cpp0x/defaulted33.C
new file mode 100644
index 0000000..2f11c13
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted33.C
@@ -0,0 +1,32 @@ 
+// PR c++/50973
+// { dg-do compile { target c++11 } }
+
+class HD
+{
+  public:
+  virtual ~HD() {};
+};
+class InputHD : public virtual HD
+{
+};
+class OutputHD : public virtual HD
+{
+};
+class IOHD : public InputHD, public OutputHD
+{
+};
+template <typename T, unsigned int N>
+class ArrayNHD : public IOHD
+{
+  public:
+  ~ArrayNHD() = default;
+};
+class TLText
+{
+  ~TLText();
+  ArrayNHD<int, 1>* m_argsHD;
+};
+TLText::~TLText()
+{
+  delete m_argsHD;
+}