diff options
author | Mark Mitchell <mark@markmitchell.com> | 1999-02-26 12:11:43 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-02-26 12:11:43 +0000 |
commit | 2b0a63a35b58c529363c6ed6db01f26d9cfa737f (patch) | |
tree | 88245a986d08f50e02468d5be72d94987f8133ca | |
parent | ed70c42623729d86d2dc610a5279a5f394be68ee (diff) | |
download | gcc-2b0a63a35b58c529363c6ed6db01f26d9cfa737f.zip gcc-2b0a63a35b58c529363c6ed6db01f26d9cfa737f.tar.gz gcc-2b0a63a35b58c529363c6ed6db01f26d9cfa737f.tar.bz2 |
decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when merging decls.
* decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when
merging decls.
* pt.c (regenerate_decl_from_template): Tweak for clarity.
(instantiate_decl): Mark a decl instantiated before regenerating
it to avoid recursion.
* tree.c (mapcar): Don't call decl_constant_value unless we know
something is TREE_READONLY_DECL_P.
From-SVN: r25458
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 2 | ||||
-rw-r--r-- | gcc/cp/pt.c | 11 | ||||
-rw-r--r-- | gcc/cp/tree.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/crash29.C | 69 |
5 files changed, 94 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e9f87d7..4424a32 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 1999-02-26 Mark Mitchell <mark@markmitchell.com> + * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when + merging decls. + * pt.c (regenerate_decl_from_template): Tweak for clarity. + (instantiate_decl): Mark a decl instantiated before regenerating + it to avoid recursion. + * tree.c (mapcar): Don't call decl_constant_value unless we know + something is TREE_READONLY_DECL_P. + * class.c (check_for_override): Don't stop checking when we find the first overridden function. Delete #if 0'd code. * search.c (get_matching_virtual): Likewise. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4cd37a7..c18eab7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3319,6 +3319,8 @@ duplicate_decls (newdecl, olddecl) DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); + DECL_TEMPLATE_INSTANTIATED (newdecl) + |= DECL_TEMPLATE_INSTANTIATED (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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b13a8c8..0f6d228 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9053,8 +9053,7 @@ regenerate_decl_from_template (decl, tmpl) /* Pop the class context we pushed above. */ popclass (1); } - - if (TREE_CODE (decl) == FUNCTION_DECL) + else if (TREE_CODE (decl) == FUNCTION_DECL) { /* Convince duplicate_decls to use the DECL_ARGUMENTS from the new decl. */ @@ -9249,9 +9248,15 @@ instantiate_decl (d) goto out; } - regenerate_decl_from_template (d, td); + /* We're now committed to instantiating this template. Mark it as + instantiated so that recursive calls to instantiate_decl do not + try to instantiate it again. */ DECL_TEMPLATE_INSTANTIATED (d) = 1; + /* Regenerate the declaration in case the template has been modified + by a subsequent redeclaration. */ + regenerate_decl_from_template (d, td); + /* We already set the file and line above. Reset them now in case they changed as a result of calling regenerate_decl_from_template. */ lineno = DECL_SOURCE_LINE (d); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 323532a..6d6fc43 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1846,11 +1846,13 @@ mapcar (t, func) void g() { const int i = 7; f<i>(7); } however, we must actually return the constant initializer. */ - tmp = decl_constant_value (t); - if (tmp != t) - return mapcar (tmp, func); - else - return error_mark_node; + if (TREE_READONLY_DECL_P (t)) + { + tmp = decl_constant_value (t); + if (tmp != t) + return mapcar (tmp, func); + } + return error_mark_node; case PARM_DECL: { diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash29.C b/gcc/testsuite/g++.old-deja/g++.pt/crash29.C new file mode 100644 index 0000000..5910064 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash29.C @@ -0,0 +1,69 @@ +// Build don't link: +// Origin: Steven Parkes <parkes@sierravista.com> + +typedef unsigned int size_t; + +class UUId {}; + +template <class T> class MetaClass; + +class TypeInfo; + +struct MetaClassGeneric +{ + MetaClassGeneric( TypeInfo& ); +}; + +struct TypeInfo +{ + void (*constructor)( void* ); + void initialize( void* ); +}; + +template <class T> +class TypeIDInit { +public: + TypeIDInit(); + static void initialize(); + static TypeInfo info; + static int storage[]; + static void metaclassConstructor( void* ); +}; + +template <class T> +TypeInfo TypeIDInit<T>::info = +{ + TypeIDInit<T>::metaclassConstructor +}; + +template <class T> +inline +TypeIDInit<T>::TypeIDInit() +{ + info.initialize(storage); +} + +template <class T> +class NameInfo : public MetaClassGeneric { +public: + NameInfo() + : MetaClassGeneric( TypeIDInit<T>::info ) {} +}; + +class MetaClass<UUId> +: public NameInfo<UUId> +{ +}; + +extern "C++" +inline void *operator new(size_t, void *place) throw() { return place; } + +template <class T> +void +TypeIDInit<T>::metaclassConstructor( void* place ) +{ + new ( place ) MetaClass<T>; +} + +template class TypeIDInit<UUId> ; + |