aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-02-10 05:29:39 -0800
committerNathan Sidwell <nathan@acm.org>2021-02-10 05:34:42 -0800
commitf8fac476b5ce4b9a37ea2b257d9da810f8c507be (patch)
treec61987740ec5c1df419f50268d687c2c500b0abc
parent57d1b68d6582efec5a7ca63ea56a1cedbfe6e874 (diff)
downloadgcc-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.c11
-rw-r--r--gcc/testsuite/g++.dg/lookup/pr99030.C16
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> ();