diff mbox

[C++] Fix decomp error recovery (PR c++/79654)

Message ID 20170221163530.GQ1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 21, 2017, 4:35 p.m. UTC
Hi!

This patch undoes part of my r245218 change, there is nothing wrong with
the decomposition type, it is better to handle it in tsubst_decomp_names.
Plus Paolo's decl2.c change that also fixes the ICE.

I think we want both, there could be other spots that aren't happy about
error_mark_node type, on the other side type might be error_mark_node
for other reasons.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-02-21  Jakub Jelinek  <jakub@redhat.com>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/79654
	* decl.c (cp_finish_decomp): Don't set decl's type to error_mark_node
	on error.
	* pt.c (tsubst_decomp_names): Return error_mark_node if the first
	decl after the decomposition artificial decl has error_mark_node.
	* decl2.c (prune_vars_needing_no_initialization): Use error_operand_p
	instead of just == error_mark_node comparison.

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


	Jakub

Comments

Jason Merrill Feb. 21, 2017, 5:55 p.m. UTC | #1
OK.

On Tue, Feb 21, 2017 at 8:35 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> This patch undoes part of my r245218 change, there is nothing wrong with
> the decomposition type, it is better to handle it in tsubst_decomp_names.
> Plus Paolo's decl2.c change that also fixes the ICE.
>
> I think we want both, there could be other spots that aren't happy about
> error_mark_node type, on the other side type might be error_mark_node
> for other reasons.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2017-02-21  Jakub Jelinek  <jakub@redhat.com>
>             Paolo Carlini  <paolo.carlini@oracle.com>
>
>         PR c++/79654
>         * decl.c (cp_finish_decomp): Don't set decl's type to error_mark_node
>         on error.
>         * pt.c (tsubst_decomp_names): Return error_mark_node if the first
>         decl after the decomposition artificial decl has error_mark_node.
>         * decl2.c (prune_vars_needing_no_initialization): Use error_operand_p
>         instead of just == error_mark_node comparison.
>
>         * g++.dg/cpp1z/decomp26.C: New test.
>
> --- gcc/cp/decl.c.jj    2017-02-20 13:43:21.000000000 +0100
> +++ gcc/cp/decl.c       2017-02-21 11:42:31.832447757 +0100
> @@ -7385,7 +7385,6 @@ 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-20 13:43:21.000000000 +0100
> +++ gcc/cp/pt.c 2017-02-21 11:45:48.736860963 +0100
> @@ -15610,6 +15610,11 @@ tsubst_decomp_names (tree decl, tree pat
>         && DECL_NAME (decl2);
>         decl2 = DECL_CHAIN (decl2))
>      {
> +      if (TREE_TYPE (decl2) == error_mark_node && *cnt == 0)
> +       {
> +         gcc_assert (errorcount);
> +         return error_mark_node;
> +       }
>        (*cnt)++;
>        gcc_assert (DECL_HAS_VALUE_EXPR_P (decl2));
>        tree v = DECL_VALUE_EXPR (decl2);
> --- gcc/cp/decl2.c.jj   2017-02-13 20:30:18.000000000 +0100
> +++ gcc/cp/decl2.c      2017-02-21 15:32:38.327611223 +0100
> @@ -3879,7 +3879,7 @@ prune_vars_needing_no_initialization (tr
>        tree init = TREE_PURPOSE (t);
>
>        /* Deal gracefully with error.  */
> -      if (decl == error_mark_node)
> +      if (error_operand_p (decl))
>         {
>           var = &TREE_CHAIN (t);
>           continue;
> --- gcc/testsuite/g++.dg/cpp1z/decomp26.C.jj    2017-02-21 11:48:20.356261173 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp26.C       2017-02-21 11:47:56.000000000 +0100
> @@ -0,0 +1,6 @@
> +// PR c++/79654
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +template<typename T> T &make();        // { dg-warning "decomposition declaration only available with" "" { target c++14_down } .+1 }
> +auto [d1, d2] = make<int>();   // { dg-error "cannot decompose non-array non-class type" }
>
>         Jakub
diff mbox

Patch

--- gcc/cp/decl.c.jj	2017-02-20 13:43:21.000000000 +0100
+++ gcc/cp/decl.c	2017-02-21 11:42:31.832447757 +0100
@@ -7385,7 +7385,6 @@  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-20 13:43:21.000000000 +0100
+++ gcc/cp/pt.c	2017-02-21 11:45:48.736860963 +0100
@@ -15610,6 +15610,11 @@  tsubst_decomp_names (tree decl, tree pat
        && DECL_NAME (decl2);
        decl2 = DECL_CHAIN (decl2))
     {
+      if (TREE_TYPE (decl2) == error_mark_node && *cnt == 0)
+	{
+	  gcc_assert (errorcount);
+	  return error_mark_node;
+	}
       (*cnt)++;
       gcc_assert (DECL_HAS_VALUE_EXPR_P (decl2));
       tree v = DECL_VALUE_EXPR (decl2);
--- gcc/cp/decl2.c.jj	2017-02-13 20:30:18.000000000 +0100
+++ gcc/cp/decl2.c	2017-02-21 15:32:38.327611223 +0100
@@ -3879,7 +3879,7 @@  prune_vars_needing_no_initialization (tr
       tree init = TREE_PURPOSE (t);
 
       /* Deal gracefully with error.  */
-      if (decl == error_mark_node)
+      if (error_operand_p (decl))
 	{
 	  var = &TREE_CHAIN (t);
 	  continue;
--- gcc/testsuite/g++.dg/cpp1z/decomp26.C.jj	2017-02-21 11:48:20.356261173 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp26.C	2017-02-21 11:47:56.000000000 +0100
@@ -0,0 +1,6 @@ 
+// PR c++/79654
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template<typename T> T &make();	// { dg-warning "decomposition declaration only available with" "" { target c++14_down } .+1 }
+auto [d1, d2] = make<int>();	// { dg-error "cannot decompose non-array non-class type" }