c++: generic lambdas and local-externs from outer scopes [PR 99030]
Lambdas can refer to local externs from their enclosing scope. When the lambda's generic but the containing function is not a temploid, we'll never have tsubsted the declaring decl so won't have a local specialization. But in that case we can just use the decl we tsubsting directly -- it's not dependent. PR c++/99030 gcc/cp * pt.c (tsubst_copy) [VAR_DECL]: For a DECL_LOCAL_DECL_P T is the answer if there's no local specialization. gcc/testsuite/ * g++.dg/lookup/pr99030.C: New.
This commit is contained in:
parent
57d1b68d65
commit
f8fac476b5
11
gcc/cp/pt.c
11
gcc/cp/pt.c
@ -16650,11 +16650,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
r = tsubst (t, args, complain, in_decl);
|
||||
else if (DECL_LOCAL_DECL_P (t))
|
||||
{
|
||||
/* Local specialization will have been created when we
|
||||
instantiated the DECL_EXPR_DECL. */
|
||||
/* Local specialization will usually have been created when
|
||||
we instantiated the DECL_EXPR_DECL. */
|
||||
r = retrieve_local_specialization (t);
|
||||
if (!r)
|
||||
r = error_mark_node;
|
||||
{
|
||||
/* We're in a generic lambda referencing a local extern
|
||||
from an outer block-scope of a non-template. */
|
||||
gcc_checking_assert (LAMBDA_FUNCTION_P (current_function_decl));
|
||||
r = t;
|
||||
}
|
||||
}
|
||||
else if (local_variable_p (t)
|
||||
&& uses_template_parms (DECL_CONTEXT (t)))
|
||||
|
16
gcc/testsuite/g++.dg/lookup/pr99030.C
Normal file
16
gcc/testsuite/g++.dg/lookup/pr99030.C
Normal file
@ -0,0 +1,16 @@
|
||||
// PR 99030 ICE with generic lambda accessing local extern
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
void foo ()
|
||||
{
|
||||
extern int a;
|
||||
[] (auto b) { a; } (1);
|
||||
}
|
||||
|
||||
template<typename T> void bar ()
|
||||
{
|
||||
extern T a;
|
||||
[] (auto b) { a; } (1);
|
||||
}
|
||||
|
||||
template void bar<int> ();
|
Loading…
Reference in New Issue
Block a user