This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] FIx 20350
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 01 Jun 2005 15:45:05 +0100
- Subject: [C++ PATCH] FIx 20350
This patch fixes 20350, an ICE with specializations. The separate
specialization declaration and then definition
template <> int Mutex<0>::mutex;
template <> int Mutex<0>::mutex = 0;
cause us to run through duplicate_decls twice. The first time through we'll have
an implicit instantiation as the old decl, which we faithfully preserve and this
allows start_decl to determine it really is a specialization. The second time
round, duplicate_decls did not propagate the 'is-a-specialization' information
thus leaving start_decl thinking this isn't an instantiation and therefore isn't
a specialization. Thus later on we regenerate_decl_from_template and copy over
the initializer from the general template.
built & tested on i686-pc-linux-gnu, installed on 4.0
I'll patch HEAD shortly, but with an associated clean up of start_decl
nathan
--
Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk
2005-06-01 Nathan Sidwell <nathan@codesourcery.com>
PR c++/20350
* decl.c (duplicate_decls): Copy all of DECL_USE_TEMPLATE.
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1371.2.11
diff -c -3 -p -r1.1371.2.11 decl.c
*** cp/decl.c 20 May 2005 17:28:39 -0000 1.1371.2.11
--- cp/decl.c 1 Jun 2005 14:33:47 -0000
*************** duplicate_decls (tree newdecl, tree oldd
*** 1675,1687 ****
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
DECL_TEMPLATE_INSTANTIATED (newdecl)
|= DECL_TEMPLATE_INSTANTIATED (olddecl);
! /* If the OLDDECL is an implicit instantiation, then the NEWDECL
! must be too. But, it may not yet be marked as such if the
! caller has created NEWDECL, but has not yet figured out that
! it is a redeclaration. */
! if (DECL_IMPLICIT_INSTANTIATION (olddecl)
! && !DECL_USE_TEMPLATE (newdecl))
! SET_DECL_IMPLICIT_INSTANTIATION (newdecl);
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
--- 1675,1688 ----
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
DECL_TEMPLATE_INSTANTIATED (newdecl)
|= DECL_TEMPLATE_INSTANTIATED (olddecl);
!
! /* If the OLDDECL is an instantiation and/or specialization,
! then the NEWDECL must be too. But, it may not yet be marked
! as such if the caller has created NEWDECL, but has not yet
! figured out that it is a redeclaration. */
! if (!DECL_USE_TEMPLATE (newdecl))
! DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
!
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 1 June 2005 <nathan@codesourcery.com>
// PR 20350: ICE on member specialization with later initialization
// Origin: Carlo Wood carlo@gcc.gnu.org
template <int i> struct Mutex
{
static int mutex;
};
template <int i>
int Mutex<i>::mutex = {1};
template <> int Mutex<0>::mutex;
template <> int Mutex<0>::mutex = 0;
void g()
{
Mutex<0>::mutex = 0;
}