Hi!

The following patch fixes ICE when cp_finish_decomp already when parsing
template manages to diagnose the decomposition as errorneous, then
the types of all the decls for the decomp identifiers are all
error_mark_node, but they don't have DECL_VALUE_EXPR tsubst_decl_names
has been asserting.  Fixed thusly, bootstrapped/regtested on x86_64-linux
and i686-linux, ok for trunk?

2017-02-06  Jakub Jelinek  <ja...@redhat.com>

        PR c++/79372
        * decl.c (cp_finish_decomp): On error set decl type to error_mark_node.
        * pt.c (tsubst_expr): Don't call tsubst_decomp_names on decompositions
        with error_mark_node type.

        * g++.dg/cpp1z/decomp25.C: New test.

--- gcc/cp/decl.c.jj    2017-01-31 09:26:02.000000000 +0100
+++ gcc/cp/decl.c       2017-02-06 18:02:02.115840352 +0100
@@ -7378,6 +7378,7 @@ cp_finish_decomp (tree decl, tree first,
            }
          first = DECL_CHAIN (first);
        }
+      TREE_TYPE (decl) = error_mark_node;
       if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl))
        SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("<decomp>"));
       return;
--- gcc/cp/pt.c.jj      2017-02-03 23:35:37.000000000 +0100
+++ gcc/cp/pt.c 2017-02-06 18:12:17.533828738 +0100
@@ -15765,7 +15765,9 @@ tsubst_expr (tree t, tree args, tsubst_f
                      const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P
                                    (pattern_decl));
                    cp_finish_decl (decl, init, const_init, NULL_TREE, 0);
-                   if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
+                   if (VAR_P (decl)
+                       && DECL_DECOMPOSITION_P (decl)
+                       && TREE_TYPE (pattern_decl) != error_mark_node)
                      {
                        unsigned int cnt;
                        tree first;
--- gcc/testsuite/g++.dg/cpp1z/decomp25.C.jj    2017-02-06 18:03:40.318562362 
+0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp25.C       2017-02-06 18:15:37.000000000 
+0100
@@ -0,0 +1,20 @@
+// PR c++/79372
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <typename T>
+struct S
+{
+  enum E { A };
+  void f () { auto [x] = 0; x++; }     // { dg-error "cannot decompose 
non-array non-class type" }
+                                       // { dg-warning "decomposition 
declaration only available with" "" { target c++14_down } .-1 }
+  void g (T t) { auto [y] = t; y++; }  // { dg-error "cannot decompose 
non-array non-class type" }
+};                                     // { dg-warning "decomposition 
declaration only available with" "" { target c++14_down } .-1 }
+
+int
+main ()
+{
+  S <int> s;
+  s.f ();
+  s.g (5);
+}

        Jakub

Reply via email to