]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: dependent local extern decl ICE [PR97171]
authorNathan Sidwell <nathan@acm.org>
Wed, 23 Sep 2020 14:01:10 +0000 (07:01 -0700)
committerNathan Sidwell <nathan@acm.org>
Wed, 23 Sep 2020 14:18:54 +0000 (07:18 -0700)
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.

gcc/cp/pt.c
gcc/testsuite/g++.dg/template/local10.C [new file with mode: 0644]

index 314bd038c6d50b05572eae139da7a12247052805..1ec039d079318d8e5fc76417e6ab3bd16c7f11d7 100644 (file)
@@ -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 (file)
index 0000000..a2ffc1e
--- /dev/null
@@ -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> ();