... the below passes testing on x86_64-linux.

Note, we have to handle separately the empty pack case, otherwise we don't emit any diagnostics and we crash pretty soon.

Thanks, Paolo.

/////////////////////////


Index: cp/decl.c
===================================================================
--- cp/decl.c   (revision 268513)
+++ cp/decl.c   (working copy)
@@ -3816,7 +3816,9 @@ make_typename_type (tree context, tree name, enum
   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: cp/pt.c
===================================================================
--- cp/pt.c     (revision 268513)
+++ cp/pt.c     (working copy)
@@ -14895,8 +14895,24 @@ tsubst (tree t, tree args, tsubst_flags_t complain
 
     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)
+             {
+               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: testsuite/g++.dg/cpp1z/using4.C
===================================================================
--- testsuite/g++.dg/cpp1z/using4.C     (nonexistent)
+++ testsuite/g++.dg/cpp1z/using4.C     (working copy)
@@ -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>;
Index: testsuite/g++.dg/cpp1z/using5.C
===================================================================
--- testsuite/g++.dg/cpp1z/using5.C     (nonexistent)
+++ testsuite/g++.dg/cpp1z/using5.C     (working copy)
@@ -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; }  // { dg-error "empty pack" }
+};
+
+template struct C<>;

Reply via email to