From 7f0964e6f146e333b2d97b1f1a8518a733f3cc17 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 18 Apr 2019 12:50:10 -0400 Subject: [PATCH] PR c++/87554 - ICE with extern template and reference member. 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 --- gcc/cp/ChangeLog | 5 +++ gcc/cp/decl.c | 3 +- .../g++.dg/cpp0x/extern_template-5.C | 36 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/extern_template-5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bfaf355ebb7..7bb464f8aa7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-04-18 Jason Merrill + + 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 PR c++/90047 - ICE with enable_if alias template. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 67d9244c450..420d6d896ec 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7354,8 +7354,7 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, && ! (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)) diff --git a/gcc/testsuite/g++.dg/cpp0x/extern_template-5.C b/gcc/testsuite/g++.dg/cpp0x/extern_template-5.C new file mode 100644 index 00000000000..5d412489fb2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/extern_template-5.C @@ -0,0 +1,36 @@ +// 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); +} -- 2.30.2