The removed code ended up setting DECL_INITIAL to the INIT_EXPR returned by
split_nonconstant_init, which makes no sense. This code was added back in
1996, so any rationale is long lost.
* decl.c (cp_finish_decl): Don't set DECL_INITIAL of external vars.
From-SVN: r270445
+2019-04-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/87554 - ICE with extern template and reference member.
+ * decl.c (cp_finish_decl): Don't set DECL_INITIAL of external vars.
+
2019-04-17 Jason Merrill <jason@redhat.com>
PR c++/90047 - ICE with enable_if alias template.
&& ! (DECL_LANG_SPECIFIC (decl)
&& DECL_NOT_REALLY_EXTERN (decl)))
{
- if (init)
- DECL_INITIAL (decl) = init;
+ /* check_initializer will have done any constant initialization. */
}
/* A variable definition. */
else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
--- /dev/null
+// PR c++/87554
+// { dg-options "-O" }
+
+template < class a > class b {
+ static void c(a);
+ static a &create() { c(instance); return mya; }
+
+ static a mya;
+
+public:
+ static a d() { create(); return a(); }
+ static a &instance;
+};
+template < class a > a &b< a >::instance = create();
+class e;
+class f {
+public:
+ void operator()(int g) { h(g); }
+ template < class a > void h(a i) { p(j, i); }
+ e *j;
+};
+class e : public f {
+public:
+ e(int);
+};
+struct k {
+ int l;
+};
+template < class m, class a > void p(m, a) { b< k >::d(); }
+extern template class b< k >;
+int n;
+int o;
+void test() {
+ e out(o);
+ out(n);
+}