aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-06-29 11:30:11 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-06-29 11:30:11 -0400
commit84eb0f1a3bfc8007e8d6ecf4bf208682fbf5b4dd (patch)
tree25c42b5cc3d4ffc3545b2a55bb83c2ceba7a956e /gcc
parent8ff22ea5a8ee58457a7c16f3501e2731a92b9df8 (diff)
downloadgcc-84eb0f1a3bfc8007e8d6ecf4bf208682fbf5b4dd.zip
gcc-84eb0f1a3bfc8007e8d6ecf4bf208682fbf5b4dd.tar.gz
gcc-84eb0f1a3bfc8007e8d6ecf4bf208682fbf5b4dd.tar.bz2
PR c++/81164 - ICE with invalid inherited constructor.
* search.c (binfo_direct_p): New. * name-lookup.c (do_class_using_decl): Use it. From-SVN: r249797
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/name-lookup.c3
-rw-r--r--gcc/cp/search.c22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C7
5 files changed, 37 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9281c61..2c29f1e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/81164 - ICE with invalid inherited constructor.
+ * search.c (binfo_direct_p): New.
+ * name-lookup.c (do_class_using_decl): Use it.
+
2017-06-29 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (THIS_NAME, IN_CHARGE_NAME, VTBL_PTR_TYPE,
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 435a23a..b3cff08 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6598,6 +6598,7 @@ extern tree dfs_walk_all (tree, tree (*) (tree, void *),
extern tree dfs_walk_once (tree, tree (*) (tree, void *),
tree (*) (tree, void *), void *);
extern tree binfo_via_virtual (tree, tree);
+extern bool binfo_direct_p (tree);
extern tree build_baselink (tree, tree, tree, tree);
extern tree adjust_result_of_qualified_name_lookup
(tree, tree, tree);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1f492a4..f15c811 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4167,8 +4167,7 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
}
- else if (name == ctor_identifier
- && BINFO_INHERITANCE_CHAIN (BINFO_INHERITANCE_CHAIN (binfo)))
+ else if (name == ctor_identifier && !binfo_direct_p (binfo))
{
error ("cannot inherit constructors from indirect base %qT", scope);
return NULL_TREE;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index af7a0f1..7bcbcbf 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2976,6 +2976,28 @@ binfo_via_virtual (tree binfo, tree limit)
return NULL_TREE;
}
+/* BINFO is for a base class in some hierarchy. Return true iff it is a
+ direct base. */
+
+bool
+binfo_direct_p (tree binfo)
+{
+ tree d_binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ if (BINFO_INHERITANCE_CHAIN (d_binfo))
+ /* A second inheritance chain means indirect. */
+ return false;
+ if (!BINFO_VIRTUAL_P (binfo))
+ /* Non-virtual, so only one inheritance chain means direct. */
+ return true;
+ /* A virtual base looks like a direct base, so we need to look through the
+ direct bases to see if it's there. */
+ tree b_binfo;
+ for (int i = 0; BINFO_BASE_ITERATE (d_binfo, i, b_binfo); ++i)
+ if (b_binfo == binfo)
+ return true;
+ return false;
+}
+
/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
Find the equivalent binfo within whatever graph HERE is located.
This is the inverse of original_binfo. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C
new file mode 100644
index 0000000..90a06c6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C
@@ -0,0 +1,7 @@
+// PR c++/81164
+// { dg-do compile { target c++11 } }
+
+struct A {};
+struct B : virtual A {};
+struct C : virtual A {};
+struct D : B,C { using A::A; }; // { dg-error "indirect" }