public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370)
@ 2017-04-10 20:35 Jakub Jelinek
  2017-04-10 20:49 ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2017-04-10 20:35 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

The following testcase ICEs, because when cp_finish_decomp is called
during parsing with processing_template_decl, but decl is not type
dependent, we finalize it at that point and when we try to do it again
during tsubst time, it doesn't find the expected trees (e.g. DECL_VALUE_EXPR
of the expected form on the corresponding user decls).

The following patch changes cp_finish_decomp processing_template_decl
handling when decl is not type dependent, such that it performs diagnostics
and sets types on the individual decls, but doesn't otherwise finalize them
(modify their DECL_VALUE_EXPR or clear them and cp_finish_decl them).

I think this way we can treat the decls as no longer type dependent, but
will let the final decomp finalization still to tsubst time.

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

2017-04-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/80370
	* decl.c (cp_finish_decomp): If processing_template_decl on
	non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't
	change their DECL_VALUE_EXPR nor cp_finish_decl them.  Instead make
	sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst
	processing.
	* constexpr.c (cxx_eval_constant_expression) <case VAR_DECL>: Don't
	recurse on DECL_VALUE_EXPR if the value expr has NULL type on a
	decomposition decl.

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

--- gcc/cp/decl.c.jj	2017-03-30 15:24:22.000000000 +0200
+++ gcc/cp/decl.c	2017-04-10 12:15:44.156022403 +0200
@@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
 			  eltype, t, size_int (i), NULL_TREE,
@@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build1_loc (DECL_SOURCE_LOCATION (v[i]),
 			  i ? IMAGPART_EXPR : REALPART_EXPR, eltype,
@@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
 						 &t, size_int (i));
@@ -7549,7 +7555,8 @@ cp_finish_decomp (tree decl, tree first,
 	      goto error_out;
 	    }
 	  /* Save the decltype away before reference collapse.  */
-	  store_decomp_type (v[i], eltype);
+	  if (!processing_template_decl)
+	    store_decomp_type (v[i], eltype);
 	  eltype = cp_build_reference_type (eltype, !lvalue_p (init));
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
@@ -7559,8 +7566,9 @@ cp_finish_decomp (tree decl, tree first,
 	      SET_DECL_VALUE_EXPR (v[i], NULL_TREE);
 	      DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
 	    }
-	  cp_finish_decl (v[i], init, /*constexpr*/false,
-			  /*asm*/NULL_TREE, LOOKUP_NORMAL);
+	  if (!processing_template_decl)
+	    cp_finish_decl (v[i], init, /*constexpr*/false,
+			    /*asm*/NULL_TREE, LOOKUP_NORMAL);
 	}
     }
   else if (TREE_CODE (type) == UNION_TYPE)
@@ -7615,12 +7623,26 @@ cp_finish_decomp (tree decl, tree first,
 	      tt = TREE_OPERAND (tt, 0);
 	    TREE_TYPE (v[i]) = TREE_TYPE (tt);
 	    layout_decl (v[i], 0);
-	    SET_DECL_VALUE_EXPR (v[i], tt);
-	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	    if (!processing_template_decl)
+	      {
+		SET_DECL_VALUE_EXPR (v[i], tt);
+		DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	      }
 	    i++;
 	  }
     }
-  if (DECL_NAMESPACE_SCOPE_P (decl))
+  if (processing_template_decl)
+    {
+      for (unsigned int i = 0; i < count; i++)
+	if (!DECL_HAS_VALUE_EXPR_P (v[i]))
+	  {
+	    tree a = build_nt (ARRAY_REF, decl, size_int (i),
+			       NULL_TREE, NULL_TREE);
+	    SET_DECL_VALUE_EXPR (v[i], a);
+	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	  }
+    }
+  else if (DECL_NAMESPACE_SCOPE_P (decl))
     SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v));
 }
 
--- gcc/cp/constexpr.c.jj	2017-03-21 07:57:00.000000000 +0100
+++ gcc/cp/constexpr.c	2017-04-10 12:24:11.849717112 +0200
@@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons
       return (*ctx->values->get (t));
 
     case VAR_DECL:
-      if (DECL_HAS_VALUE_EXPR_P (t))
+      if (DECL_HAS_VALUE_EXPR_P (t)
+	  /* Don't recurse on DECL_VALUE_EXPR of decomposition decls
+	     that have not been finalized yet.  */
+	  && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t))))
 	return cxx_eval_constant_expression (ctx, DECL_VALUE_EXPR (t),
 					     lval, non_constant_p, overflow_p);
       /* fall through */
--- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj	2017-04-10 11:40:39.209346743 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp28.C	2017-04-10 11:42:15.939128016 +0200
@@ -0,0 +1,39 @@
+// PR c++/80370
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+namespace std {
+  template <typename> struct tuple_size;
+  template <long, typename> struct tuple_element;
+  template <typename...> struct tuple {};
+  template <typename... T> struct tuple_size<tuple<T...>> { static constexpr int value = 1; };
+  template <typename T, typename... U> struct tuple_element<0, tuple<T, U...>> { typedef T type; };
+  template <int, typename... T> int& get (tuple<T...>);
+}
+
+template <int N>
+void
+foo (std::tuple<int> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+template <typename T>
+void
+bar (std::tuple<T> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+void
+baz (std::tuple<int> b)
+{
+  foo <5> (b);
+  bar (b);
+}
+
+int
+main ()
+{
+  [](auto) { [](std::tuple<int> b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}

	Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370)
  2017-04-10 20:35 [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370) Jakub Jelinek
@ 2017-04-10 20:49 ` Jason Merrill
  2017-04-10 20:52   ` Jakub Jelinek
  2017-04-11 13:41   ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 2) Jakub Jelinek
  0 siblings, 2 replies; 6+ messages in thread
From: Jason Merrill @ 2017-04-10 20:49 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

On Mon, Apr 10, 2017 at 4:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> -         store_decomp_type (v[i], eltype);
> +         if (!processing_template_decl)
> +           store_decomp_type (v[i], eltype);

This spot shouldn't change; we do want to remember the decltype even
in a template.

> @@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons
>        return (*ctx->values->get (t));
>
>      case VAR_DECL:
> -      if (DECL_HAS_VALUE_EXPR_P (t))
> +      if (DECL_HAS_VALUE_EXPR_P (t)
> +         /* Don't recurse on DECL_VALUE_EXPR of decomposition decls
> +            that have not been finalized yet.  */
> +         && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t))))

Hmm, we shouldn't get here in this case.  I think
value_dependent_expression_p should return true for a VAR_DECL with
type-dependent DECL_VALUE_EXPR.

Jason

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370)
  2017-04-10 20:49 ` Jason Merrill
@ 2017-04-10 20:52   ` Jakub Jelinek
  2017-04-11 13:41   ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 2) Jakub Jelinek
  1 sibling, 0 replies; 6+ messages in thread
From: Jakub Jelinek @ 2017-04-10 20:52 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Mon, Apr 10, 2017 at 04:48:43PM -0400, Jason Merrill wrote:
> On Mon, Apr 10, 2017 at 4:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > -         store_decomp_type (v[i], eltype);
> > +         if (!processing_template_decl)
> > +           store_decomp_type (v[i], eltype);
> 
> This spot shouldn't change; we do want to remember the decltype even
> in a template.

Ok.

> > @@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons
> >        return (*ctx->values->get (t));
> >
> >      case VAR_DECL:
> > -      if (DECL_HAS_VALUE_EXPR_P (t))
> > +      if (DECL_HAS_VALUE_EXPR_P (t)
> > +         /* Don't recurse on DECL_VALUE_EXPR of decomposition decls
> > +            that have not been finalized yet.  */
> > +         && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t))))
> 
> Hmm, we shouldn't get here in this case.  I think
> value_dependent_expression_p should return true for a VAR_DECL with
> type-dependent DECL_VALUE_EXPR.

Will try that tomorrow.

	Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 2)
  2017-04-10 20:49 ` Jason Merrill
  2017-04-10 20:52   ` Jakub Jelinek
@ 2017-04-11 13:41   ` Jakub Jelinek
  2017-04-11 17:13     ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 3) Jakub Jelinek
  1 sibling, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2017-04-11 13:41 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

Hi!

On Mon, Apr 10, 2017 at 04:48:43PM -0400, Jason Merrill wrote:
> On Mon, Apr 10, 2017 at 4:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> > -         store_decomp_type (v[i], eltype);
> > +         if (!processing_template_decl)
> > +           store_decomp_type (v[i], eltype);
> 
> This spot shouldn't change; we do want to remember the decltype even
> in a template.
> 
> > @@ -3935,7 +3935,10 @@ cxx_eval_constant_expression (const cons
> >        return (*ctx->values->get (t));
> >
> >      case VAR_DECL:
> > -      if (DECL_HAS_VALUE_EXPR_P (t))
> > +      if (DECL_HAS_VALUE_EXPR_P (t)
> > +         /* Don't recurse on DECL_VALUE_EXPR of decomposition decls
> > +            that have not been finalized yet.  */
> > +         && (!DECL_DECOMPOSITION_P (t) || TREE_TYPE (DECL_VALUE_EXPR (t))))
> 
> Hmm, we shouldn't get here in this case.  I think
> value_dependent_expression_p should return true for a VAR_DECL with
> type-dependent DECL_VALUE_EXPR.

So like this?  Or just type_dependent_expression_p check rather than
both?

2017-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/80370
	* decl.c (cp_finish_decomp): If processing_template_decl on
	non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't
	change their DECL_VALUE_EXPR nor cp_finish_decl them.  Instead make
	sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst
	processing.
	* pt.c (value_dependent_expression_p) <case VAR_DECL>: For variables
	with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type or
	value dependent.

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

--- gcc/cp/decl.c.jj	2017-04-10 22:26:56.441388051 +0200
+++ gcc/cp/decl.c	2017-04-11 15:21:24.473163169 +0200
@@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
 			  eltype, t, size_int (i), NULL_TREE,
@@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build1_loc (DECL_SOURCE_LOCATION (v[i]),
 			  i ? IMAGPART_EXPR : REALPART_EXPR, eltype,
@@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
 						 &t, size_int (i));
@@ -7559,8 +7565,9 @@ cp_finish_decomp (tree decl, tree first,
 	      SET_DECL_VALUE_EXPR (v[i], NULL_TREE);
 	      DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
 	    }
-	  cp_finish_decl (v[i], init, /*constexpr*/false,
-			  /*asm*/NULL_TREE, LOOKUP_NORMAL);
+	  if (!processing_template_decl)
+	    cp_finish_decl (v[i], init, /*constexpr*/false,
+			    /*asm*/NULL_TREE, LOOKUP_NORMAL);
 	}
     }
   else if (TREE_CODE (type) == UNION_TYPE)
@@ -7615,12 +7622,26 @@ cp_finish_decomp (tree decl, tree first,
 	      tt = TREE_OPERAND (tt, 0);
 	    TREE_TYPE (v[i]) = TREE_TYPE (tt);
 	    layout_decl (v[i], 0);
-	    SET_DECL_VALUE_EXPR (v[i], tt);
-	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	    if (!processing_template_decl)
+	      {
+		SET_DECL_VALUE_EXPR (v[i], tt);
+		DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	      }
 	    i++;
 	  }
     }
-  if (DECL_NAMESPACE_SCOPE_P (decl))
+  if (processing_template_decl)
+    {
+      for (unsigned int i = 0; i < count; i++)
+	if (!DECL_HAS_VALUE_EXPR_P (v[i]))
+	  {
+	    tree a = build_nt (ARRAY_REF, decl, size_int (i),
+			       NULL_TREE, NULL_TREE);
+	    SET_DECL_VALUE_EXPR (v[i], a);
+	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	  }
+    }
+  else if (DECL_NAMESPACE_SCOPE_P (decl))
     SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v));
 }
 
--- gcc/cp/pt.c.jj	2017-04-10 08:18:51.000000000 +0200
+++ gcc/cp/pt.c	2017-04-11 15:37:59.727673709 +0200
@@ -23576,6 +23576,13 @@ value_dependent_expression_p (tree expre
 	      || type_dependent_expression_p (DECL_INITIAL (expression))
 	      || value_dependent_expression_p (DECL_INITIAL (expression))))
 	return true;
+      if (DECL_HAS_VALUE_EXPR_P (expression))
+	{
+	  tree value_expr = DECL_VALUE_EXPR (expression);
+	  if (type_dependent_expression_p (value_expr)
+	      || value_dependent_expression_p (value_expr))
+	    return true;
+	}
       return false;
 
     case DYNAMIC_CAST_EXPR:
--- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj	2017-04-11 15:21:24.473163169 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp28.C	2017-04-11 15:21:24.473163169 +0200
@@ -0,0 +1,39 @@
+// PR c++/80370
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+namespace std {
+  template <typename> struct tuple_size;
+  template <long, typename> struct tuple_element;
+  template <typename...> struct tuple {};
+  template <typename... T> struct tuple_size<tuple<T...>> { static constexpr int value = 1; };
+  template <typename T, typename... U> struct tuple_element<0, tuple<T, U...>> { typedef T type; };
+  template <int, typename... T> int& get (tuple<T...>);
+}
+
+template <int N>
+void
+foo (std::tuple<int> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+template <typename T>
+void
+bar (std::tuple<T> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+void
+baz (std::tuple<int> b)
+{
+  foo <5> (b);
+  bar (b);
+}
+
+int
+main ()
+{
+  [](auto) { [](std::tuple<int> b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}


	Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 3)
  2017-04-11 13:41   ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 2) Jakub Jelinek
@ 2017-04-11 17:13     ` Jakub Jelinek
  2017-04-11 18:40       ` Jason Merrill
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Jelinek @ 2017-04-11 17:13 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches List

On Tue, Apr 11, 2017 at 03:41:39PM +0200, Jakub Jelinek wrote:
> So like this?  Or just type_dependent_expression_p check rather than
> both?

To answer myself, testing there both type_dependent_expression_p
and value_dependent_expression_p for value_expr breaks
the lambda-generic-const2.C testcase.  So I'll test this instead:

2017-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/80370
	* decl.c (cp_finish_decomp): If processing_template_decl on
	non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't
	change their DECL_VALUE_EXPR nor cp_finish_decl them.  Instead make
	sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst
	processing.
	* pt.c (value_dependent_expression_p) <case VAR_DECL>: For variables
	with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type
	dependent.

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

--- gcc/cp/decl.c.jj	2017-04-10 22:26:56.441388051 +0200
+++ gcc/cp/decl.c	2017-04-11 15:21:24.473163169 +0200
@@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
 			  eltype, t, size_int (i), NULL_TREE,
@@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  t = build1_loc (DECL_SOURCE_LOCATION (v[i]),
 			  i ? IMAGPART_EXPR : REALPART_EXPR, eltype,
@@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first,
 	{
 	  TREE_TYPE (v[i]) = eltype;
 	  layout_decl (v[i], 0);
+	  if (processing_template_decl)
+	    continue;
 	  tree t = unshare_expr (dexp);
 	  convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
 						 &t, size_int (i));
@@ -7559,8 +7565,9 @@ cp_finish_decomp (tree decl, tree first,
 	      SET_DECL_VALUE_EXPR (v[i], NULL_TREE);
 	      DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
 	    }
-	  cp_finish_decl (v[i], init, /*constexpr*/false,
-			  /*asm*/NULL_TREE, LOOKUP_NORMAL);
+	  if (!processing_template_decl)
+	    cp_finish_decl (v[i], init, /*constexpr*/false,
+			    /*asm*/NULL_TREE, LOOKUP_NORMAL);
 	}
     }
   else if (TREE_CODE (type) == UNION_TYPE)
@@ -7615,12 +7622,26 @@ cp_finish_decomp (tree decl, tree first,
 	      tt = TREE_OPERAND (tt, 0);
 	    TREE_TYPE (v[i]) = TREE_TYPE (tt);
 	    layout_decl (v[i], 0);
-	    SET_DECL_VALUE_EXPR (v[i], tt);
-	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	    if (!processing_template_decl)
+	      {
+		SET_DECL_VALUE_EXPR (v[i], tt);
+		DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	      }
 	    i++;
 	  }
     }
-  if (DECL_NAMESPACE_SCOPE_P (decl))
+  if (processing_template_decl)
+    {
+      for (unsigned int i = 0; i < count; i++)
+	if (!DECL_HAS_VALUE_EXPR_P (v[i]))
+	  {
+	    tree a = build_nt (ARRAY_REF, decl, size_int (i),
+			       NULL_TREE, NULL_TREE);
+	    SET_DECL_VALUE_EXPR (v[i], a);
+	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
+	  }
+    }
+  else if (DECL_NAMESPACE_SCOPE_P (decl))
     SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v));
 }
 
--- gcc/cp/pt.c.jj	2017-04-11 19:06:52.871624849 +0200
+++ gcc/cp/pt.c	2017-04-11 19:10:39.795803274 +0200
@@ -23576,6 +23576,12 @@ value_dependent_expression_p (tree expre
 	      || type_dependent_expression_p (DECL_INITIAL (expression))
 	      || value_dependent_expression_p (DECL_INITIAL (expression))))
 	return true;
+      if (DECL_HAS_VALUE_EXPR_P (expression))
+	{
+	  tree value_expr = DECL_VALUE_EXPR (expression);
+	  if (type_dependent_expression_p (value_expr))
+	    return true;
+	}
       return false;
 
     case DYNAMIC_CAST_EXPR:
--- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj	2017-04-11 15:21:24.473163169 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp28.C	2017-04-11 15:21:24.473163169 +0200
@@ -0,0 +1,39 @@
+// PR c++/80370
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+namespace std {
+  template <typename> struct tuple_size;
+  template <long, typename> struct tuple_element;
+  template <typename...> struct tuple {};
+  template <typename... T> struct tuple_size<tuple<T...>> { static constexpr int value = 1; };
+  template <typename T, typename... U> struct tuple_element<0, tuple<T, U...>> { typedef T type; };
+  template <int, typename... T> int& get (tuple<T...>);
+}
+
+template <int N>
+void
+foo (std::tuple<int> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+template <typename T>
+void
+bar (std::tuple<T> b)
+{
+  auto [c] = b;		// { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}
+
+void
+baz (std::tuple<int> b)
+{
+  foo <5> (b);
+  bar (b);
+}
+
+int
+main ()
+{
+  [](auto) { [](std::tuple<int> b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
+}


	Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 3)
  2017-04-11 17:13     ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 3) Jakub Jelinek
@ 2017-04-11 18:40       ` Jason Merrill
  0 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2017-04-11 18:40 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches List

OK.

On Tue, Apr 11, 2017 at 1:13 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Apr 11, 2017 at 03:41:39PM +0200, Jakub Jelinek wrote:
>> So like this?  Or just type_dependent_expression_p check rather than
>> both?
>
> To answer myself, testing there both type_dependent_expression_p
> and value_dependent_expression_p for value_expr breaks
> the lambda-generic-const2.C testcase.  So I'll test this instead:
>
> 2017-04-11  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/80370
>         * decl.c (cp_finish_decomp): If processing_template_decl on
>         non-dependent decl, only set TREE_TYPE on the v[i] decls, but don't
>         change their DECL_VALUE_EXPR nor cp_finish_decl them.  Instead make
>         sure DECL_VALUE_EXPR is the canonical NULL type ARRAY_REF for tsubst
>         processing.
>         * pt.c (value_dependent_expression_p) <case VAR_DECL>: For variables
>         with DECL_VALUE_EXPR, return true if DECL_VALUE_EXPR is type
>         dependent.
>
>         * g++.dg/cpp1z/decomp28.C: New test.
>
> --- gcc/cp/decl.c.jj    2017-04-10 22:26:56.441388051 +0200
> +++ gcc/cp/decl.c       2017-04-11 15:21:24.473163169 +0200
> @@ -7473,6 +7473,8 @@ cp_finish_decomp (tree decl, tree first,
>         {
>           TREE_TYPE (v[i]) = eltype;
>           layout_decl (v[i], 0);
> +         if (processing_template_decl)
> +           continue;
>           tree t = unshare_expr (dexp);
>           t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
>                           eltype, t, size_int (i), NULL_TREE,
> @@ -7492,6 +7494,8 @@ cp_finish_decomp (tree decl, tree first,
>         {
>           TREE_TYPE (v[i]) = eltype;
>           layout_decl (v[i], 0);
> +         if (processing_template_decl)
> +           continue;
>           tree t = unshare_expr (dexp);
>           t = build1_loc (DECL_SOURCE_LOCATION (v[i]),
>                           i ? IMAGPART_EXPR : REALPART_EXPR, eltype,
> @@ -7510,6 +7514,8 @@ cp_finish_decomp (tree decl, tree first,
>         {
>           TREE_TYPE (v[i]) = eltype;
>           layout_decl (v[i], 0);
> +         if (processing_template_decl)
> +           continue;
>           tree t = unshare_expr (dexp);
>           convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
>                                                  &t, size_int (i));
> @@ -7559,8 +7565,9 @@ cp_finish_decomp (tree decl, tree first,
>               SET_DECL_VALUE_EXPR (v[i], NULL_TREE);
>               DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
>             }
> -         cp_finish_decl (v[i], init, /*constexpr*/false,
> -                         /*asm*/NULL_TREE, LOOKUP_NORMAL);
> +         if (!processing_template_decl)
> +           cp_finish_decl (v[i], init, /*constexpr*/false,
> +                           /*asm*/NULL_TREE, LOOKUP_NORMAL);
>         }
>      }
>    else if (TREE_CODE (type) == UNION_TYPE)
> @@ -7615,12 +7622,26 @@ cp_finish_decomp (tree decl, tree first,
>               tt = TREE_OPERAND (tt, 0);
>             TREE_TYPE (v[i]) = TREE_TYPE (tt);
>             layout_decl (v[i], 0);
> -           SET_DECL_VALUE_EXPR (v[i], tt);
> -           DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
> +           if (!processing_template_decl)
> +             {
> +               SET_DECL_VALUE_EXPR (v[i], tt);
> +               DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
> +             }
>             i++;
>           }
>      }
> -  if (DECL_NAMESPACE_SCOPE_P (decl))
> +  if (processing_template_decl)
> +    {
> +      for (unsigned int i = 0; i < count; i++)
> +       if (!DECL_HAS_VALUE_EXPR_P (v[i]))
> +         {
> +           tree a = build_nt (ARRAY_REF, decl, size_int (i),
> +                              NULL_TREE, NULL_TREE);
> +           SET_DECL_VALUE_EXPR (v[i], a);
> +           DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
> +         }
> +    }
> +  else if (DECL_NAMESPACE_SCOPE_P (decl))
>      SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v));
>  }
>
> --- gcc/cp/pt.c.jj      2017-04-11 19:06:52.871624849 +0200
> +++ gcc/cp/pt.c 2017-04-11 19:10:39.795803274 +0200
> @@ -23576,6 +23576,12 @@ value_dependent_expression_p (tree expre
>               || type_dependent_expression_p (DECL_INITIAL (expression))
>               || value_dependent_expression_p (DECL_INITIAL (expression))))
>         return true;
> +      if (DECL_HAS_VALUE_EXPR_P (expression))
> +       {
> +         tree value_expr = DECL_VALUE_EXPR (expression);
> +         if (type_dependent_expression_p (value_expr))
> +           return true;
> +       }
>        return false;
>
>      case DYNAMIC_CAST_EXPR:
> --- gcc/testsuite/g++.dg/cpp1z/decomp28.C.jj    2017-04-11 15:21:24.473163169 +0200
> +++ gcc/testsuite/g++.dg/cpp1z/decomp28.C       2017-04-11 15:21:24.473163169 +0200
> @@ -0,0 +1,39 @@
> +// PR c++/80370
> +// { dg-do compile { target c++14 } }
> +// { dg-options "" }
> +
> +namespace std {
> +  template <typename> struct tuple_size;
> +  template <long, typename> struct tuple_element;
> +  template <typename...> struct tuple {};
> +  template <typename... T> struct tuple_size<tuple<T...>> { static constexpr int value = 1; };
> +  template <typename T, typename... U> struct tuple_element<0, tuple<T, U...>> { typedef T type; };
> +  template <int, typename... T> int& get (tuple<T...>);
> +}
> +
> +template <int N>
> +void
> +foo (std::tuple<int> b)
> +{
> +  auto [c] = b;                // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
> +}
> +
> +template <typename T>
> +void
> +bar (std::tuple<T> b)
> +{
> +  auto [c] = b;                // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
> +}
> +
> +void
> +baz (std::tuple<int> b)
> +{
> +  foo <5> (b);
> +  bar (b);
> +}
> +
> +int
> +main ()
> +{
> +  [](auto) { [](std::tuple<int> b) { auto[c] = b; }; } (0); // { dg-warning "decomposition declaration only available with" "" { target c++14_down } }
> +}
>
>
>         Jakub

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-04-11 18:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-10 20:35 [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370) Jakub Jelinek
2017-04-10 20:49 ` Jason Merrill
2017-04-10 20:52   ` Jakub Jelinek
2017-04-11 13:41   ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 2) Jakub Jelinek
2017-04-11 17:13     ` [C++ PATCH] Fix decomp ICEs in templates (PR c++/80370, take 3) Jakub Jelinek
2017-04-11 18:40       ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).