c++: local-decls are never member fns [PR97186]
authorNathan Sidwell <nathan@acm.org>
Thu, 24 Sep 2020 13:17:00 +0000 (06:17 -0700)
committerNathan Sidwell <nathan@acm.org>
Thu, 24 Sep 2020 13:21:54 +0000 (06:21 -0700)
This fixes an ICE in noexcept instantiation.  It was presuming
functions always have template_info, but that changed with my
DECL_LOCAL_DECL_P changes.  Fortunately DECL_LOCAL_DECL_P fns are
never member fns, so we don't need to go fishing out a this pointer.

Also I realized I'd misnamed local10.C, so renaming it local-fn3.C,
and while there adding the effective-target lto that David E pointed
out was missing.

PR c++/97186
gcc/cp/
* pt.c (maybe_instantiate_noexcept): Local externs are never
member fns.
gcc/testsuite/
* g++.dg/template/local10.C: Rename ...
* g++.dg/template/local-fn3.C: .. here.  Require lto.
* g++.dg/template/local-fn4.C: New.

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

index 1ec039d079318d8e5fc76417e6ab3bd16c7f11d7..62e85095bc4adfe906d56276a8c4c1d671e967cf 100644 (file)
@@ -25397,15 +25397,20 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
          push_deferring_access_checks (dk_no_deferred);
          input_location = DECL_SOURCE_LOCATION (fn);
 
-         /* If needed, set current_class_ptr for the benefit of
-            tsubst_copy/PARM_DECL.  */
-         tree tdecl = DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (fn));
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tdecl))
+         if (!DECL_LOCAL_DECL_P (fn))
            {
-             tree this_parm = DECL_ARGUMENTS (tdecl);
-             current_class_ptr = NULL_TREE;
-             current_class_ref = cp_build_fold_indirect_ref (this_parm);
-             current_class_ptr = this_parm;
+             /* If needed, set current_class_ptr for the benefit of
+                tsubst_copy/PARM_DECL.  The exception pattern will
+                refer to the parm of the template, not the
+                instantiation.  */
+             tree tdecl = DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (fn));
+             if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tdecl))
+               {
+                 tree this_parm = DECL_ARGUMENTS (tdecl);
+                 current_class_ptr = NULL_TREE;
+                 current_class_ref = cp_build_fold_indirect_ref (this_parm);
+                 current_class_ptr = this_parm;
+               }
            }
 
          /* If this function is represented by a TEMPLATE_DECL, then
diff --git a/gcc/testsuite/g++.dg/template/local-fn3.C b/gcc/testsuite/g++.dg/template/local-fn3.C
new file mode 100644 (file)
index 0000000..2affe23
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/97171
+
+// { dg-require-effective-target lto }
+// { 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> ();
diff --git a/gcc/testsuite/g++.dg/template/local-fn4.C b/gcc/testsuite/g++.dg/template/local-fn4.C
new file mode 100644 (file)
index 0000000..4699012
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/97186
+// ICE in exception spec substitution
+
+
+template <class GG>
+struct no {
+  static void
+  tg ()
+  {
+    void
+      hk () noexcept (tg); // { dg-error "convert" }
+
+    hk ();
+  }
+};
+
+void
+os ()
+{
+  no<int> ().tg ();
+}
diff --git a/gcc/testsuite/g++.dg/template/local10.C b/gcc/testsuite/g++.dg/template/local10.C
deleted file mode 100644 (file)
index a2ffc1e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// 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> ();