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. pushing to trunk nathan -- Nathan Sidwell
diff --git c/gcc/cp/pt.c w/gcc/cp/pt.c index 314bd038c6d..1ec039d0793 100644 --- c/gcc/cp/pt.c +++ w/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 c/gcc/testsuite/g++.dg/template/local10.C w/gcc/testsuite/g++.dg/template/local10.C new file mode 100644 index 00000000000..a2ffc1e7306 --- /dev/null +++ w/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> ();