diff options
author | Nathan Sidwell <nathan@acm.org> | 2021-02-10 05:29:39 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2021-02-10 05:34:42 -0800 |
commit | f8fac476b5ce4b9a37ea2b257d9da810f8c507be (patch) | |
tree | c61987740ec5c1df419f50268d687c2c500b0abc | |
parent | 57d1b68d6582efec5a7ca63ea56a1cedbfe6e874 (diff) | |
download | gcc-f8fac476b5ce4b9a37ea2b257d9da810f8c507be.zip gcc-f8fac476b5ce4b9a37ea2b257d9da810f8c507be.tar.gz gcc-f8fac476b5ce4b9a37ea2b257d9da810f8c507be.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/pr99030.C | 16 |
2 files changed, 24 insertions, 3 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index f73deb3..d8574f6 100644 --- a/gcc/cp/pt.c +++ b/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))) diff --git a/gcc/testsuite/g++.dg/lookup/pr99030.C b/gcc/testsuite/g++.dg/lookup/pr99030.C new file mode 100644 index 0000000..080847c --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/pr99030.C @@ -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> (); |