Patchwork PR c++/51477 - ICE with invalid NSDMI

login
register
mail settings
Submitter Dodji Seketeli
Date Dec. 13, 2011, 9:24 p.m.
Message ID <m3mxaw4133.fsf@redhat.com>
Download mbox | patch
Permalink /patch/131193/
State New
Headers show

Comments

Dodji Seketeli - Dec. 13, 2011, 9:24 p.m.
Hello,

In the example of this patch, during the implicit declaration of the
destructor, walk_field_subobs calls locate_fn_flags on the field
invalid field 'x', to locate its destructor.  That function pokes the
BINFO of that field, which is NULL, and passes it along to
lookup_fnfields.  And we ICE because of that NULL base type.

Just preventing lookup_member from crashing because of a NULL (or
otherwise invalid) base type fixes the issue.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

	PR c++/51477
	* search.c (lookup_member): Get out early on invalid base type.

gcc/testsuite/

	PR c++/51477
	* g++.dg/cpp0x/nsdmi6.C: New test.
---
 gcc/cp/search.c                     |    4 +++-
 gcc/testsuite/g++.dg/cpp0x/nsdmi6.C |    8 ++++++++
 2 files changed, 11 insertions(+), 1 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
Jason Merrill - Dec. 16, 2011, 7:34 p.m.
OK.

Jason

Patch

diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 3894c68..0ceb5bc 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1171,7 +1171,9 @@  lookup_member (tree xbasetype, tree name, int protect, bool want_type,
 
   const char *errstr = 0;
 
-  if (name == error_mark_node)
+  if (name == error_mark_node
+      || xbasetype == NULL_TREE
+      || xbasetype == error_mark_node)
     return NULL_TREE;
 
   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
new file mode 100644
index 0000000..bb455e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
@@ -0,0 +1,8 @@ 
+// Origin PR c++/51477
+// { dg-options "-std=c++11" }
+
+struct A
+{
+    typedef int int T; // { dg-error "two or more data types in declaration" }
+    struct T x[1] = { 0 }; // { dg-error "invalid|forward" }
+};