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.
commit 86959b6f73148a9a09d31945d465d42f936aff39
Author: Jason Merrill <ja...@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);