re PR c++/88986 (ICE: tree check: expected tree that contains 'decl minimal' structur...
authorPaolo Carlini <paolo.carlini@oracle.com>
Wed, 13 Feb 2019 10:34:49 +0000 (10:34 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Wed, 13 Feb 2019 10:34:49 +0000 (10:34 +0000)
/cp
2019-02-13  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/88986
* decl.c (make_typename_type): Allow for TYPE_PACK_EXPANSION as
context (the first argument).
* pt.c (tsubst, case TYPENAME_TYPE): Handle TYPE_PACK_EXPANSION
as context.

/testsuite
2019-02-13  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/88986
* g++.dg/cpp1z/using4.C: New.
* g++.dg/cpp1z/using5.C: Likewise.
* g++.dg/cpp1z/using6.C: Likewise.

From-SVN: r268839

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp1z/using4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/using5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1z/using6.C [new file with mode: 0644]

index cb74761571682fb0c21da27e652e072307b2cfbb..b423f7c9b1e5467ef7429953c8ab77595d8a220a 100644 (file)
@@ -1,3 +1,11 @@
+2019-02-13  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/88986
+       * decl.c (make_typename_type): Allow for TYPE_PACK_EXPANSION as
+       context (the first argument).
+       * pt.c (tsubst, case TYPENAME_TYPE): Handle TYPE_PACK_EXPANSION
+       as context.
+
 2019-02-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/89144 - link error with constexpr initializer_list.
index 40381978312bb93be40dafd6c9aa32f2c8b7c77d..31d7dc5be1e7fe5943d79a510fba32a3c5fe2c6c 100644 (file)
@@ -3816,7 +3816,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
   gcc_assert (identifier_p (name));
   gcc_assert (TYPE_P (context));
 
-  if (!MAYBE_CLASS_TYPE_P (context))
+  if (TREE_CODE (context) == TYPE_PACK_EXPANSION)
+    /* This can happen for C++17 variadic using (c++/88986).  */;
+  else if (!MAYBE_CLASS_TYPE_P (context))
     {
       if (complain & tf_error)
        error ("%q#T is not a class", context);
index b96e3aa9cd564ca6348d119a120af4cc0cf6a350..e6782fe785bfa9cf70e0501e0b8b159b37f331c2 100644 (file)
@@ -14928,8 +14928,25 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case TYPENAME_TYPE:
       {
-       tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, complain,
-                                    in_decl, /*entering_scope=*/1);
+       tree ctx = TYPE_CONTEXT (t);
+       if (TREE_CODE (ctx) == TYPE_PACK_EXPANSION)
+         {
+           ctx = tsubst_pack_expansion (ctx, args, complain, in_decl);
+           if (ctx == error_mark_node
+               || TREE_VEC_LENGTH (ctx) > 1)
+             return error_mark_node;
+           if (TREE_VEC_LENGTH (ctx) == 0)
+             {
+               if (complain & tf_error)
+                 error ("%qD is instantiated for an empty pack",
+                        TYPENAME_TYPE_FULLNAME (t));
+               return error_mark_node;
+             }
+           ctx = TREE_VEC_ELT (ctx, 0);
+         }
+       else
+         ctx = tsubst_aggr_type (ctx, args, complain, in_decl,
+                                 /*entering_scope=*/1);
        if (ctx == error_mark_node)
          return error_mark_node;
 
index bf9d01cc97887ca8c3147cbe68602e2270f8c891..d22149515aabf9527d0b2ba41068c9d7a36bf4f7 100644 (file)
@@ -1,3 +1,10 @@
+2019-02-13  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/88986
+       * g++.dg/cpp1z/using4.C: New.
+       * g++.dg/cpp1z/using5.C: Likewise.
+       * g++.dg/cpp1z/using6.C: Likewise.
+
 2019-02-13  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/89290
diff --git a/gcc/testsuite/g++.dg/cpp1z/using4.C b/gcc/testsuite/g++.dg/cpp1z/using4.C
new file mode 100644 (file)
index 0000000..2c133d9
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/88986
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct B { typedef int type; };
+
+template<typename ...T> struct C : T... {
+  using typename T::type ...;  // { dg-warning "pack expansion" "" { target c++14_down } }
+  void f() { type value; }
+};
+
+template struct C<B>;
diff --git a/gcc/testsuite/g++.dg/cpp1z/using5.C b/gcc/testsuite/g++.dg/cpp1z/using5.C
new file mode 100644 (file)
index 0000000..90f37cc
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/88986
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template<typename ...T> struct C : T... {
+  using typename T::type ...;  // { dg-warning "pack expansion" "" { target c++14_down } }
+  void f() { type value; }  // { dg-error "empty pack" }
+};
+
+template struct C<>;
diff --git a/gcc/testsuite/g++.dg/cpp1z/using6.C b/gcc/testsuite/g++.dg/cpp1z/using6.C
new file mode 100644 (file)
index 0000000..af78d6d
--- /dev/null
@@ -0,0 +1,14 @@
+// PR c++/88986
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct B1 { typedef int type; };
+struct B2 { typedef double type; };
+
+template<typename ...T> struct C : T... {
+  using typename T::type ...;  // { dg-warning "pack expansion" "" { target c++14_down } }
+  // { dg-error "redeclaration" "" { target *-*-* } .-1 }
+  void f() { type value; }
+};
+
+template struct C<B1, B2>;