PR c++/70735 - generic lambda and local static variable
* pt.c (tsubst_copy): Just return a local variable from non-template context. Don't call rest_of_decl_compilation for duplicated static locals. (tsubst_decl): Set DECL_CONTEXT of local static from another function. From-SVN: r236615
This commit is contained in:
parent
26d6ae55d8
commit
9c62c1f364
|
@ -1,3 +1,12 @@
|
|||
2016-05-23 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/70735
|
||||
* pt.c (tsubst_copy): Just return a local variable from
|
||||
non-template context. Don't call rest_of_decl_compilation for
|
||||
duplicated static locals.
|
||||
(tsubst_decl): Set DECL_CONTEXT of local static from another
|
||||
function.
|
||||
|
||||
2016-05-23 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/70972
|
||||
|
|
22
gcc/cp/pt.c
22
gcc/cp/pt.c
|
@ -12281,6 +12281,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
|
|||
local_p = true;
|
||||
/* Subsequent calls to pushdecl will fill this in. */
|
||||
ctx = NULL_TREE;
|
||||
/* Unless this is a reference to a static variable from an
|
||||
enclosing function, in which case we need to fill it in now. */
|
||||
if (TREE_STATIC (t))
|
||||
{
|
||||
tree fn = tsubst (DECL_CONTEXT (t), args, complain, in_decl);
|
||||
if (fn != current_function_decl)
|
||||
ctx = fn;
|
||||
}
|
||||
spec = retrieve_local_specialization (t);
|
||||
}
|
||||
/* If we already have the specialization we need, there is
|
||||
|
@ -13992,7 +14000,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
|||
case FUNCTION_DECL:
|
||||
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
|
||||
r = tsubst (t, args, complain, in_decl);
|
||||
else if (local_variable_p (t))
|
||||
else if (local_variable_p (t)
|
||||
&& uses_template_parms (DECL_CONTEXT (t)))
|
||||
{
|
||||
r = retrieve_local_specialization (t);
|
||||
if (r == NULL_TREE)
|
||||
|
@ -14036,14 +14045,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
|||
gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
|
||||
|| decl_constant_var_p (r)
|
||||
|| errorcount || sorrycount);
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
if (TREE_STATIC (r))
|
||||
rest_of_decl_compilation (r, toplevel_bindings_p (),
|
||||
at_eof);
|
||||
else
|
||||
r = process_outer_var_ref (r, complain);
|
||||
}
|
||||
if (!processing_template_decl
|
||||
&& !TREE_STATIC (r))
|
||||
r = process_outer_var_ref (r, complain);
|
||||
}
|
||||
/* Remember this for subsequent uses. */
|
||||
if (local_specializations)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// PR c++/70735
|
||||
// { dg-do run { target c++1y } }
|
||||
|
||||
int main()
|
||||
{
|
||||
static int a;
|
||||
auto f = [](auto) { return a; };
|
||||
if (f(0) != 0)
|
||||
__builtin_abort();
|
||||
a = 1;
|
||||
if (f(0) != 1)
|
||||
__builtin_abort();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// PR c++/70735
|
||||
// { dg-do run { target c++1y } }
|
||||
|
||||
template <class T>
|
||||
static void g()
|
||||
{
|
||||
static int a;
|
||||
auto f = [](auto) { return a; };
|
||||
if (f(0) != 0)
|
||||
__builtin_abort();
|
||||
a = 1;
|
||||
if (f(0) != 1)
|
||||
__builtin_abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
g<int>();
|
||||
}
|
Loading…
Reference in New Issue