aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-09-23 07:01:10 -0700
committerNathan Sidwell <nathan@acm.org>2020-09-23 07:18:54 -0700
commit13f7c5d504b5fe6c233f2e68acd10bd4fc9007ac (patch)
tree66e0e66297f31fe72e8ecf90fb8a81ae5c6c85d2 /gcc
parentc48ffe21f8f3478cf08f9442e3f973df358caf2a (diff)
downloadgcc-13f7c5d504b5fe6c233f2e68acd10bd4fc9007ac.zip
gcc-13f7c5d504b5fe6c233f2e68acd10bd4fc9007ac.tar.gz
gcc-13f7c5d504b5fe6c233f2e68acd10bd4fc9007ac.tar.bz2
c++: dependent local extern decl ICE [PR97171]
I'd missed the piece of substutution for the uses of a local extern decl. Just grab the local specialization. We need to do this regardless of dependentness because we always cloned the local extern. PR c++/97171 gcc/cp/ * pt.c (tsubst_copy) [FUNCTION_DECL,VAR_DECL]: Retrieve local specialization for DECL_LOCAL_P decls. gcc/testsuite/ * g++.dg/template/local10.C: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/testsuite/g++.dg/template/local10.C15
2 files changed, 23 insertions, 0 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 314bd03..1ec039d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16531,6 +16531,14 @@ 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 (DECL_LOCAL_DECL_P (t))
+ {
+ /* Local specialization will have been created when we
+ instantiated the DECL_EXPR_DECL. */
+ r = retrieve_local_specialization (t);
+ if (!r)
+ r = error_mark_node;
+ }
else if (local_variable_p (t)
&& uses_template_parms (DECL_CONTEXT (t)))
{
diff --git a/gcc/testsuite/g++.dg/template/local10.C b/gcc/testsuite/g++.dg/template/local10.C
new file mode 100644
index 0000000..a2ffc1e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/local10.C
@@ -0,0 +1,15 @@
+// PR c++/97171
+// { dg-additional-options -flto }
+
+template <typename _UnaryOperation>
+void transform(_UnaryOperation);
+
+template <typename T>
+void Apply ()
+{
+ extern T Maker (void); // block-scope extern with dependent type
+
+ transform (Maker);
+}
+
+template void Apply<int> ();