Patchwork C++ PATCH to tsubst of var_decl

login
register
mail settings
Submitter Jason Merrill
Date April 11, 2013, 3:50 p.m.
Message ID <5166DBE1.4000804@redhat.com>
Download mbox | patch
Permalink /patch/235816/
State New
Headers show

Comments

Jason Merrill - April 11, 2013, 3:50 p.m.
56901 turns out to be related to an issue that has been bugging me for a 
while; we would hand off instantiation of a use of a variable to 
tsubst_decl, which might end up producing a whole new instantiation of 
the variable rather than look up the one that we (presumably) already 
have.  56901 is an instance of failing to find an existing declaration, 
trying to produce a new one, and running into trouble.  Rather than 
this, we should be more assertive about requiring that variables be 
declared before they are used.

Indeed, when I make this change the only place in the compiler that 
needed to be fixed was the OpenMP for-loop, where a DECL_EXPR for the 
iterator ends up in OMP_FOR_PRE_BODY, so we need to be sure to 
instantiate that before we instantiate anything that mentions the iterator.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 86959b6f73148a9a09d31945d465d42f936aff39
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Apr 11 09:16:51 2013 -0400

    	* pt.c (tsubst_copy) [VAR_DECL]: Don't call tsubst for
    	local variables, look them up instead.
    	(tsubst_decl) [VAR_DECL]: Remove handling for anonymous union
    	proxies and substitution in unevaluated context.
    	(tsubst_expr) [OMP_FOR]: Instantiate OMP_FOR_PRE_BODY
    	before the iterators.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1c0b3ec..487a985 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10666,16 +10666,6 @@  tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	    break;
 	  }
 
-	if (VAR_P (t) && DECL_ANON_UNION_VAR_P (t))
-	  {
-	    /* Just use name lookup to find a member alias for an anonymous
-	       union, but then add it to the hash table.  */
-	    r = lookup_name (DECL_NAME (t));
-	    gcc_assert (DECL_ANON_UNION_VAR_P (r));
-	    register_local_specialization (r, t);
-	    break;
-	  }
-
 	/* Create a new node for the specialization we need.  */
 	r = copy_decl (t);
 	if (type == NULL_TREE)
@@ -10780,21 +10770,7 @@  tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 	    SET_DECL_IMPLICIT_INSTANTIATION (r);
 	  }
 	else if (cp_unevaluated_operand)
-	  {
-	    /* We're substituting this var in a decltype outside of its
-	       scope, such as for a lambda return type.  Don't add it to
-	       local_specializations, do perform auto deduction.  */
-	    tree auto_node = type_uses_auto (type);
-	    if (auto_node)
-	      {
-		tree init
-		  = tsubst_expr (DECL_INITIAL (t), args, complain, in_decl,
-				 /*constant_expression_p=*/false);
-		init = resolve_nondeduced_context (init);
-		TREE_TYPE (r) = type
-		  = do_auto_deduction (type, init, auto_node);
-	      }
-	  }
+	  gcc_unreachable ();
 	else
 	  register_local_specialization (r, t);
 
@@ -12208,11 +12184,32 @@  tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 
     case VAR_DECL:
     case FUNCTION_DECL:
-      if ((DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
-	  || local_variable_p (t))
-	t = tsubst (t, args, complain, in_decl);
-      mark_used (t);
-      return t;
+      if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
+	r = tsubst (t, args, complain, in_decl);
+      else if (local_variable_p (t))
+	{
+	  r = retrieve_local_specialization (t);
+	  if (r == NULL_TREE)
+	    {
+	      if (DECL_ANON_UNION_VAR_P (t))
+		{
+		  /* Just use name lookup to find a member alias for an
+		     anonymous union, but then add it to the hash table.  */
+		  r = lookup_name (DECL_NAME (t));
+		  gcc_assert (DECL_ANON_UNION_VAR_P (r));
+		  register_local_specialization (r, t);
+		}
+	      else
+		{
+		  gcc_assert (errorcount || sorrycount);
+		  return error_mark_node;
+		}
+	    }
+	}
+      else
+	r = t;
+      mark_used (r);
+      return r;
 
     case NAMESPACE_DECL:
       return t;
@@ -13251,15 +13248,15 @@  tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
 
 	stmt = begin_omp_structured_block ();
 
+	pre_body = push_stmt_list ();
+	RECUR (OMP_FOR_PRE_BODY (t));
+	pre_body = pop_stmt_list (pre_body);
+
 	for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (t)); i++)
 	  tsubst_omp_for_iterator (t, i, declv, initv, condv, incrv,
 				   &clauses, args, complain, in_decl,
 				   integral_constant_expression_p);
 
-	pre_body = push_stmt_list ();
-	RECUR (OMP_FOR_PRE_BODY (t));
-	pre_body = pop_stmt_list (pre_body);
-
 	body = push_stmt_list ();
 	RECUR (OMP_FOR_BODY (t));
 	body = pop_stmt_list (body);