re PR c++/64521 (ICE with -frepo)
authorJason Merrill <jason@redhat.com>
Thu, 29 Jan 2015 16:09:56 +0000 (11:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 29 Jan 2015 16:09:56 +0000 (11:09 -0500)
PR c++/64521
* repo.c (repo_emit_p): It's OK for a clone to be extern at this
point.

From-SVN: r220251

gcc/cp/ChangeLog
gcc/cp/repo.c
gcc/testsuite/g++.dg/template/repo11.C [new file with mode: 0644]

index 743fda3704d7c74bbd04c0764fb46e0a3ba65fc7..fb3e2dc79e4d8044b64687237af81dab4965530c 100644 (file)
@@ -1,3 +1,9 @@
+2015-01-29  Jason Merrill  <jason@redhat.com>
+
+       PR c++/64521
+       * repo.c (repo_emit_p): It's OK for a clone to be extern at this
+       point.
+
 2015-01-27  Caroline Tice  <cmtice@google.com>
 
        Committing VTV Cywin/Ming patch for Patrick Wollgast
index 604d66728de2de83e1a3007e74432270dfb346e0..f417e4b56f12e5fe6a11b0ea4affe05776c4dd59 100644 (file)
@@ -302,7 +302,11 @@ repo_emit_p (tree decl)
   int ret = 0;
   gcc_assert (TREE_PUBLIC (decl));
   gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
-  gcc_assert (!DECL_REALLY_EXTERN (decl));
+  gcc_assert (!DECL_REALLY_EXTERN (decl)
+             /* A clone might not have its linkage flags updated yet
+                because we call import_export_decl before
+                maybe_clone_body.  */
+             || DECL_ABSTRACT_ORIGIN (decl));
 
   /* When not using the repository, emit everything.  */
   if (!flag_use_repository)
diff --git a/gcc/testsuite/g++.dg/template/repo11.C b/gcc/testsuite/g++.dg/template/repo11.C
new file mode 100644 (file)
index 0000000..5cabfd4
--- /dev/null
@@ -0,0 +1,31 @@
+// PR c++/64521
+// { dg-options "-frepo -std=c++11" }
+// { dg-require-host-local "" }
+// { dg-skip-if "dkms are not final links" { vxworks_kernel } }
+// { dg-final cleanup-repo-files }
+
+template <typename H> struct J { J(H) {} };
+template <unsigned long, typename...> struct K;
+template <unsigned long I> struct K<I> {};
+template <unsigned long I, typename H, typename... T>
+struct K<I, H, T...> : K<I + 1, T...>, J<H> {
+  K(const H &p1, const T &... p2) : K<I + 1, T...>(p2...), J<H>(p1) {}
+};
+template <typename... E> struct C : K<0, E...> {
+  C(const E &... p1) : K<0, E...>(p1...) {}
+};
+template <typename> struct A {
+  A() = default;
+};
+struct M;
+template <typename> struct L {
+  struct B {
+    template <typename> static M *__test(...);
+    typedef A<int> _Del;
+    typedef decltype(__test<_Del>()) type;
+  };
+  C<typename B::type, A<M>> _M_t;
+  L(typename B::type) : _M_t(0, A<M>()) {}
+};
+struct M {};
+int main() { L<int>(new M); }