From: jason Date: Thu, 18 Apr 2019 16:50:10 +0000 (+0000) Subject: PR c++/87554 - ICE with extern template and reference member. X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fgcc.git;a=commitdiff_plain;h=849a7926848082c390a6d4bdc1b02f672fea5ed9 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270445 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bfaf355ebb70..7bb464f8aa78 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 67d9244c450e..420d6d896ec0 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 000000000000..5d412489fb28 --- /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); +}