PR c++/81164 - ICE with invalid inherited constructor.
authorJason Merrill <jason@redhat.com>
Thu, 29 Jun 2017 15:30:11 +0000 (11:30 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 29 Jun 2017 15:30:11 +0000 (11:30 -0400)
* search.c (binfo_direct_p): New.
* name-lookup.c (do_class_using_decl): Use it.

From-SVN: r249797

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/name-lookup.c
gcc/cp/search.c
gcc/testsuite/g++.dg/cpp0x/inh-ctor28.C [new file with mode: 0644]

index 9281c6100f8343ffd99e673a430fe3270028e68d..2c29f1e6d16463355c25497ec696c6cc17af43fa 100644 (file)
@@ -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,
index 435a23a3c4e3fe04d78878ea9a3c82b2eb80ed71..b3cff08805da03445b452cd8ccfb272a0485daaf 100644 (file)
@@ -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);
index 1f492a4898f8896df544cbc7e66825c36aa17486..f15c811695922ed4de9dc4f1695e245ca6db2b10 100644 (file)
@@ -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;
index af7a0f169a158ffe01c20d8c1d5d4acad9a777d7..7bcbcbfe535e0f363e90509a177f443c97ba8fae 100644 (file)
@@ -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 (file)
index 0000000..90a06c6
--- /dev/null
@@ -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" }