aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-06-03 07:56:58 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-06-03 07:56:58 -0400
commit616abc647c1fa14fabdbe708c4adcf88135916ef (patch)
tree7f6499e383aaa725cb6f8db30917be0aed42e538 /gcc
parentb31e65bb600deccb25cdac88b8db1144066c307e (diff)
downloadgcc-616abc647c1fa14fabdbe708c4adcf88135916ef.zip
gcc-616abc647c1fa14fabdbe708c4adcf88135916ef.tar.gz
gcc-616abc647c1fa14fabdbe708c4adcf88135916ef.tar.bz2
re PR c++/61020 (typeid(typeid(X)) produces 'ud2')
PR c++/61020 * varpool.c (ctor_for_folding): Handle uninitialized vtables. From-SVN: r211178
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/typeinfo1.C27
-rw-r--r--gcc/varpool.c11
3 files changed, 42 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b35b444..5bc582b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/61020
+ * varpool.c (ctor_for_folding): Handle uninitialized vtables.
+
2014-06-03 Alan Lawrence <alan.lawrence@arm.com>
* config/aarch64/aarch64.c (aarch64_evpc_ext): allow and handle
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. */