diff mbox

RFA: PATCH to ctor_for_folding for c++/61020 (ICE with typeid)

Message ID 538D274B.1090802@redhat.com
State New
Headers show

Commit Message

Jason Merrill June 3, 2014, 1:39 a.m. UTC
The C++ front end wants to be able to build up objects of the various 
typeinfo derived classes (such as __si_class_type_info) without needing 
to see the full definition of the class.  As part of this we build a 
VAR_DECL for the vtable, but never define it because we don't actually 
have declarations of the virtual functions, we're only using it for 
external references.  ctor_for_folding was assuming that all vtables are 
defined, which broke on this case.

Tested x86_64-pc-linux-gnu.  OK for trunk?

Comments

Richard Biener June 3, 2014, 9:26 a.m. UTC | #1
On Tue, Jun 3, 2014 at 3:39 AM, Jason Merrill <jason@redhat.com> wrote:
> The C++ front end wants to be able to build up objects of the various
> typeinfo derived classes (such as __si_class_type_info) without needing to
> see the full definition of the class.  As part of this we build a VAR_DECL
> for the vtable, but never define it because we don't actually have
> declarations of the virtual functions, we're only using it for external
> references.  ctor_for_folding was assuming that all vtables are defined,
> which broke on this case.
>
> Tested x86_64-pc-linux-gnu.  OK for trunk?

Ok.

Thanks,
Richard.
diff mbox

Patch

commit e13e596c640374df15c0a25d5049d5e30d08dc6b
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jun 2 20:27:24 2014 -0400

    	PR c++/61020
    	* varpool.c (ctor_for_folding): Handle uninitialized vtables.

diff --git a/gcc/testsuite/g++.dg/opt/typeinfo1.C b/gcc/testsuite/g++.dg/opt/typeinfo1.C
new file mode 100644
index 0000000..efac4cb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/typeinfo1.C
@@ -0,0 +1,27 @@ 
+// PR c++/61020
+// { dg-options "-O2" }
+// { dg-do run }
+
+#include <typeinfo>
+
+struct Base {
+  virtual ~Base() { }
+};
+
+struct Derived : public Base {
+};
+
+int compare(const Base& base)
+{
+  return typeid(base) == typeid(typeid(Derived));
+}
+
+int main()
+{
+  Base base;
+  Derived derived;
+
+  if (compare(base)) return 1;
+  if (compare(derived)) return 2;
+  return 0;
+}
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 1697bb4..143cd3b 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -306,7 +306,16 @@  ctor_for_folding (tree decl)
   if (DECL_VIRTUAL_P (real_decl))
     {
       gcc_checking_assert (TREE_READONLY (real_decl));
-      return DECL_INITIAL (real_decl);
+      if (DECL_INITIAL (real_decl))
+	return DECL_INITIAL (real_decl);
+      else
+	{
+	  /* The C++ front end creates VAR_DECLs for vtables of typeinfo
+	     classes not defined in the current TU so that it can refer
+	     to them from typeinfo objects.  Avoid returning NULL_TREE.  */
+	  gcc_checking_assert (!COMPLETE_TYPE_P (DECL_CONTEXT (real_decl)));
+	  return error_mark_node;
+	}
     }
 
   /* If there is no constructor, we have nothing to do.  */